2014 dxdy logo

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

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




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Нахождение координат элемента по адресу.
Сообщение04.10.2016, 19:38 


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

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение04.10.2016, 19:52 
Заслуженный участник


09/05/12
25179
А Вы учли, что размер одного элемента, вообще говоря, не обязан равняться одному байту?

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение04.10.2016, 19:54 
Заслуженный участник


04/05/09
4587
Непонятно, зачем и как вы сначала адрес максимального элемента, не зная его индекс. Лучше сразу работать с индексами, а адрес вообще не нужен.
Подозреваю, что ваш код, хотя и работает, некорректен по стандарту языка. Можете привести код?

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


04/07/15
149
Код:

#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 
Заслуженный участник


04/05/09
4587
Ну, как я и подозревал, код некорректный. Вы нагло обращаетесь ко всему двумерному массиву, как к одномерному. Так нельзя. Как к одномерному можно обращаться только в пределах одной строки. Конечно, на многих современных компиляторах такое пройдёт, но не всегда. Более того, гайки закручиваются, и новый компилятор может отказаться делать то, что вам нужно, т.к. оптимизатор заметит выход за пределы массива (одной строки), и выкинет некорректный код.

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение04.10.2016, 20:14 


04/07/15
149
То есть невозможно определить координаты элемента, если знать расстояние от начала массива до данного элемента?

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение05.10.2016, 11:48 
Заслуженный участник
Аватара пользователя


01/08/06
3128
Уфа
Лучше бы в функции maxelem возвращать не A[i]+j, а A[i], то есть адрес строки, которую нужно удалить, плюс дополнительно в параметрах добавить int *i1, int *j1 для возвращения координат максимального элемента. В функции delline параметр n не нужно передавать по указателю, лишнее это, функция ведь его не меняет.

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение05.10.2016, 14:33 


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

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение05.10.2016, 15:15 


04/07/15
149
worm2
Спасибо огромное за совет. Идею понял.

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение05.10.2016, 15:18 
Заслуженный участник


27/04/09
28128
aa_dav в сообщении #1157501 писал(а):
Это еще дискуссионный вопрос.
До того как кто-то найдёт время свериться со стандартом. :-) Насколько я вчитался в черновик стандарта С11 WG14 N1570 (см. описание и ссылки тут), UB таки есть.

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

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение06.10.2016, 06:23 


11/12/14
893
arseniiv в сообщении #1157509 писал(а):
UB таки есть


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

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

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение06.10.2016, 21:30 
Заслуженный участник


27/04/09
28128
Я подожду специалистов со стандартом.

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение10.10.2016, 21:56 


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

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение11.10.2016, 00:06 
Заслуженный участник


27/04/09
28128
Ну, лично я поверил ТС:
Orkimed в сообщении #1157282 писал(а):
P.S пишу на Си.
Может, и зря. Хотя, один раз просмотрев код, признаков плюсости не нашёл.

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

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

 Профиль  
                  
 
 Re: Нахождение координат элемента по адресу.
Сообщение11.10.2016, 00:11 
Заслуженный участник


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

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group