2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2  След.
 
 Нахождение координат элемента по адресу.
Сообщение04.10.2016, 19:38 
Здравствуйте. Нужна помощь. Задача найти максимальный элемент в двумерном массиве, вывести его значение и координаты, потом удалить строку, которая содержит его.
Адрес максимального элемента я нашёл. Строка удаляется нормально. Максимальный элемент ищется тоже корректно . Как из адреса максимального элемента вытащить его координаты? Пытался пользоваться конструкциями вида : ((P-E[0])%Nmax) или ((P-E[0])/Nmax), где P - адрес максимального элемента, E[0]- адрес нулевого элемента моего массива. Nmax- максимальная размерность массива. Но ничего путного из этого не вышло.
P.S пишу на Си.

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение04.10.2016, 19:52 
А Вы учли, что размер одного элемента, вообще говоря, не обязан равняться одному байту?

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение04.10.2016, 19:54 
Непонятно, зачем и как вы сначала адрес максимального элемента, не зная его индекс. Лучше сразу работать с индексами, а адрес вообще не нужен.
Подозреваю, что ваш код, хотя и работает, некорректен по стандарту языка. Можете привести код?

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение04.10.2016, 19:57 
Код:

#include <iostream>
#include <stdio.h>
#include <clocale>

void transform (float **M,float *V,int n,int m);
int maxline(float **A,int n,int m);
void delline(float **A,int* n,int m, int index);
int readmat(int*n, int* m, float** A, int Nmax, int Mmax);
void writemat(float** A, int n, int m);
float* maxelem(float **A,int n,int m);

int  main()
{
    const int Nmax=18;
    const int Mmax=20;
    float E[Nmax][Mmax];
    float * Ep[Nmax];

    transform(Ep, *E, Nmax, Mmax);

    int n, m;
    if(!readmat(&n, &m, Ep, Nmax, Mmax ))
    {
        printf("Erorr size!!!\n");

        return 0;
    }

    //int index = maxline(Ep, n, m);
    float* P = maxelem(Ep, n, m);
    printf("Maxelem=%lf\n",*P);
    printf("Stroka=%ld\n" ,((P-E[0])%Nmax));
    printf("stolbec=%ld\n",((P-E[0])/Nmax));
    printf("matrix before\n");
    writemat(Ep, n, m);
    printf("\n");
    delline(Ep, &n, m, (P - E[0])/Nmax);
    printf("matrix after\n");
    writemat(Ep, n, m);


    return 1;
}

void transform (float **M,float *V,int n,int m)
{
    for (int i = 0; i < n; i++)
        M[i] = V + i*m;
}

int maxline(float **A,int n,int m)
{
    float Amax = A[0][0];
    int imax = 0;
    for (int i = 0; i < n; i++)\
        for (int j = 0; i < m; i++)
            if(Amax < A[i][j])
            {
                Amax = A[i][j];
                imax = i;
            }

    return imax;
}
float* maxelem(float **A,int n,int m)
{
    float* Pmax = A[0];
    for (int i = 0; i < n; i++)\
        for (int j = 0; j < m; j++)
            if(*Pmax < A[i][j])
            {
                Pmax = A[i] + j;
            }

    return Pmax;
}

void delline(float **A,int* n,int m, int index)
{
    for (int i = index; i < *n - 1; i++)
        for(int j = 0;j < m; j++)
            A[i][j] = A[i+1][j];
    --*n;
}

int readmat(int*n, int* m, float** A, int Nmax, int Mmax)
{
    printf("(n*m): ");
    scanf("%d%d", n, m);

    if(*n <= 0 || *n > Nmax || *m <= 0 || *m > Mmax) return 0;

    printf("Matrix: \n");
    for(int i = 0; i < *n; i++)
        for(int j = 0; j < *m; j++)
                scanf("%f", A[i] + j);

    return 1;
}

void writemat(float** A, int n, int m)
{
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
            printf(" %7.2f", A[i][j]);
        printf("\n");
    }

}


 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение04.10.2016, 20:08 
Ну, как я и подозревал, код некорректный. Вы нагло обращаетесь ко всему двумерному массиву, как к одномерному. Так нельзя. Как к одномерному можно обращаться только в пределах одной строки. Конечно, на многих современных компиляторах такое пройдёт, но не всегда. Более того, гайки закручиваются, и новый компилятор может отказаться делать то, что вам нужно, т.к. оптимизатор заметит выход за пределы массива (одной строки), и выкинет некорректный код.

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение04.10.2016, 20:14 
То есть невозможно определить координаты элемента, если знать расстояние от начала массива до данного элемента?

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение05.10.2016, 11:48 
Аватара пользователя
Лучше бы в функции maxelem возвращать не A[i]+j, а A[i], то есть адрес строки, которую нужно удалить, плюс дополнительно в параметрах добавить int *i1, int *j1 для возвращения координат максимального элемента. В функции delline параметр n не нужно передавать по указателю, лишнее это, функция ведь его не меняет.

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение05.10.2016, 14:33 
Проблема, как я понял, что при делении о взятии остатка надо было использовать $Mmax$, а не $Nmax$.
И в принципе работать может, исходя из принципов как оно разложено в памяти. Возможно даже стандарт разрешает и никаких UB нет. Это еще дискуссионный вопрос. Но не хотелось бы в него обмакиваться.
Однако так делать действительно не особо нужно, проще и лучше поступать как пишут выше.

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение05.10.2016, 15:15 
worm2
Спасибо огромное за совет. Идею понял.

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение05.10.2016, 15:18 
aa_dav в сообщении #1157501 писал(а):
Это еще дискуссионный вопрос.
До того как кто-то найдёт время свериться со стандартом. :-) Насколько я вчитался в черновик стандарта С11 WG14 N1570 (см. описание и ссылки тут), UB таки есть.

aa_dav в сообщении #1157501 писал(а):
Однако так делать действительно не особо нужно
Так делать нужно тогда и только тогда, когда надо представить $n$-мерный массив одномерным (например, размерность массива известна только в рантайме). В таком случае нам должно быть известно, как мы линейно упорядочиваем индексы.

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение06.10.2016, 06:23 
arseniiv в сообщении #1157509 писал(а):
UB таки есть


Вполне может быть можно найти какую то фразу, которую можно так трактовать.
С другой стороны то, что мы знаем что:
Код:
sizeof(array)==sizeof(elem)*count
и в то же время
&arr[i]==(byte*)arr+sizeof(elem)*i

это тоже нерушимый стандарт. Исходя из него НЕВОЗМОЖНО трактовать иначе то как составлен массив массивов с точностью до адреса любого элемента. И эта раскладка в точности совпадает с раскладкой одномерного массива перемноженной ёмкости. Так что может быть вопросом не правомочно ли считать ли массив массивов одним цельным allocation unit-ом? Ну и, кроме того, тут нет стимула кодерам компиляторов искать и выкидывать код с UB, т.к. производительности это лишней не даст. Обычно эти моменты закручены вокруг оптимизаций.

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение06.10.2016, 21:30 
Я подожду специалистов со стандартом.

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение10.10.2016, 21:56 
Для начала, пример у ТС на плюсах, а не на сях. Это разные стандарты.
Но такие приёмы с многомерными массивами работали всегда и, наверняка, будут работать до тех пор, пока жива арифметика указателей. Из чего не следует, что нельзя написать лучше. Академически - нужно завести двумерный индекс и воспользоваться STL :lol: . Быстро и грязно, но не запутывая читателя подобной арифметикой указателей переменной размерности - работать изначально с одномерным массивом вместо двумерного, схлопнув диапазон индексов в нём при помощи memmove :mrgreen: .

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение11.10.2016, 00:06 
Ну, лично я поверил ТС:
Orkimed в сообщении #1157282 писал(а):
P.S пишу на Си.
Может, и зря. Хотя, один раз просмотрев код, признаков плюсости не нашёл.

-- Вт окт 11, 2016 02:07:18 --

Хотя вот имена инклудов в угловых скобках, и два из них ещё и без расширения. Не помню, говорит ли это о чём-то, или в новых стандартах не.

 
 
 
 Re: Нахождение координат элемента по адресу.
Сообщение11.10.2016, 00:11 
arseniiv в сообщении #1158776 писал(а):
и два из них ещё и без расширения. Не помню, говорит ли это о чём-то, или в новых стандартах не.
Вот ровно две эти строчки и требуют C++. Правда, их можно безболезненно удалить :D, и то, что останется, является кодом на C99.

 
 
 [ Сообщений: 16 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group