powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Отсортировать по одной из координат матрицу, представленную как одномерный массив
17 сообщений из 17, страница 1 из 1
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558166
Vladimir1R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Такая задача.
Есть класс, в котором определена матрица NxM в виде одномерного массива в контейнере vector.
в каждой строки матрицы хранится n-мерные координаты некоторого объекта типа x1,x2,x3,xn,v1,v2,v3,vn
Требуется отсортировать этот одномерный массив по одной из координат, например по координате x2.
Т.е. нужно переставить строки этой матрицы таким образом, чтобы в каждой строке x2 (второй элемент строки) возрастал. Т.е. сверху матрицы были строки с меньшим вторым элементом, а снизу с большим.
Приходится обрабатывать огромные массивы данных, поэтому скорость и экономия памяти в данной задаче критична. По этому как инструмент сортировки были выбраны стандартные std:sort либо stdlib qsort.
Так же хочу обратить внимание на то что данная матрица представлена в виде ОДНОмерного массива и досуп к n-му элементу m-ой строки в матрице NxM осуществляется как не A[m][n], а вот так A[m*N+n]. Это сделано в целях упрощения задачи и экономии памяти.

Итак, требуется реализовать сортировку матрицы с помощью либо std::sort, либо stdlib qsort, с заданным параметром сортировки (по какому значению сортировать). и реализовать её надо полностью как метод класса.

Вот что сейчас получилось:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
template <typename Tfloat>
class particle_beem
{
    public:
        vector <Tfloat> arr;
 
        particle_beem(int dim, int count_el);
        ~particle_beem();
 
        int resize(int count_el);
        int set_dim(int dim);
        int data_create_rand(Tfloat dXmin, Tfloat dXmax, Tfloat dVmin, Tfloat dVmax);
        int data_write_to_file(const char *cFile_name);
        int data_read_from_file(const char *cFile_name);
        int data_sort_by_coordinate(/*тут необходимо передавать как параметр, по какому элементу сортировать*/);
 
    protected:
 
    private:
        int dimension;
        int count_eliments;
 
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //1 - это по какому элементу идет сортировка, т.е. по второму
        }
 
};
 
//....всякий код....
 
template <typename Tfloat>
int particle_beem<Tfloat>::data_sort_by_coordinate()
{
    qsort(&arr[0], count_eliments, sizeof(Tfloat)*dimension*2, sort_func);
    return 0;
}



На данный момент этот код работает, но мне необходимо передавать как параметр по какому элементу производить сортировку, и сообщать каким то образом этот параметр компаратору sort_func.

через промежуточное прайват свойство класса не получится, т.к. компаратор является статическим членом класса.
Не статическим членом класса его делать не получается, а выносить из класса его не следует по условиям задачи.
Попробовал реализовать компаратор sort_func функтором, чтобы передавать параметр сортировки через свойство функтора, но qsort функторы (оно и понятно:-)) совсем не ест.
Подскажите пожалуйста уважаемые форумчани, как мне быть в этой ситуации? как все таки передавать этот параметр сортировки.

И еще. На самом деле, в контексте C++ я с большей радостью, как это и положено использовал бы для сортировки std::sort, и заодно тем самым решил бы проблему с параметром и увеличил производительность. Но я не могу придумать как применить std::sort применительно к данной задачи не распихивая строки матрицы по отдельным контейнерам.
Ведь у меня матрица представлена одномерным массивом.
В qsort я меняю местами блоки памяти заданной длинны, например sizeof(Tfloat)*dimension*2.
а в std::sort мне не указать какими блоками памяти мне оперировать, он сортирует не блоки памяти а элементы массива.
Может подскажите как мне применить std::sort к данной задачи?

Заранее всех благодарю!
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558445
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir1RЭто сделано в целях упрощения задачи и экономии памяти.
На самом-то деле это только усложняет задачу, не экономит память и чертовски понижает
быстродействие, поскольку вместо обмена двух указателей при сортировке придётся обменивать
большие массивы информации.

Vladimir1Rкак мне применить std::sort к данной задачи?
Не выпендриваться и хранить свою матрицу как массив указателей на вектора-строки.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558455
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir1R,


авторЕсть класс, в котором определена матрица NxM в виде одномерного массива в контейнере vector.
в каждой строки матрицы хранится n-мерные координаты некоторого объекта типа x1,x2,x3,xn,v1,v2,v3,vn
Требуется отсортировать этот одномерный массив по одной из координат, например по координате x2.
Т.е. нужно переставить строки этой матрицы таким образом, чтобы в каждой строке x2 (второй элемент строки) возрастал. Т.е. сверху матрицы были строки с меньшим вторым элементом, а снизу с большим.
Приходится обрабатывать огромные массивы данных, поэтому скорость и экономия памяти в данной задаче критична. По этому как инструмент сортировки были выбраны стандартные std:sort либо stdlib qsort.
Так же хочу обратить внимание на то что данная матрица представлена в виде ОДНОмерного массива и досуп к n-му элементу m-ой строки в матрице NxM осуществляется как не A[m][n], а вот так A[m*N+n]. Это сделано в целях упрощения задачи и экономии памяти.


В лоб это решать нельзя. Умрёт.
Делаешь массив номеров столбцов (или строк).
Сортируешь номера столбцов (или строк) в соответствии с твоим критерием сортировки.
После сортировки формируешь новую матрицу, взяв из старой соответствующие столбцы (строки) в нужном порядке.
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558460
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir1R
Заранее всех благодарю!

Я что-то совсем не понял, как это должно работать.
Там нет пересчёта координат ячейки в матрице в координаты ячейки в одномерном векторе.
Вызов qsort(&arr[0], count_eliments, sizeof(Tfloat)*dimension*2, sort_func); неверный.
Да и вообще у тебя нет размерностей матрицы.
Также немаловажно, как матрица хранится в векторе -- по столбцам или по строкам.

В общем, бред какой-то ...
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558635
Vladimir1R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry SibiryakovНа самом-то деле это только усложняет задачу, не экономит память и чертовски понижает
быстродействие, поскольку вместо обмена двух указателей при сортировке придётся обменивать
большие массивы информации.


в общем случае, я с Вами согласен, но относительно этой конкретной задачки --
Сортировка, это предварительный этап подготовки к решению более сложной задачки, который исполняется один раз.
Далее, в данной задаче, с одномерным массивом работать все таки проще.
Быстродействием в этом контексте, для сохранения структуры и прозрачности кода все таки можно немного пренебречь(т.к. это предварительный а не основной этап задачи)
Общая задача заключается в моделировании движения пучка заряженных элементарных частиц.

Подскажите, пожалуйста, почему это совсем не экономит память?
Планируется работать с большим количеством частиц, например уже при 1 000 000 000 частиц * 64bit для указателя ~8 ГБ на указатели. Если рассматривать задачу в одномерном случае с типом float, то придется потратить треть памяти только на указатели.

Может я что то упускаю из виду, тогда подскажите, пожалуйста, все таки, почему память мы в таком случае не экономим?
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558703
Vladimir1R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivVladimir1R,
В лоб это решать нельзя. Умрёт.
Делаешь массив номеров столбцов (или строк).
Сортируешь номера столбцов (или строк) в соответствии с твоим критерием сортировки.
После сортировки формируешь новую матрицу, взяв из старой соответствующие столбцы (строки) в нужном порядке.

Спасибо, учту,
но как то это сложно получается.

По скорости и по памяти в таком случае дешевле, мне кажется, сформировать на основе одномерного вектора - вектор векторов, и скормить его std::sort, а в качестве компаратор указать функтор, у которого в свойстве будет параметр для сортировки.

Но все таки это крайне не экономично выходит, и как то не красиво.

В общем то у меня задача минимум - как передать параметр сортировки в компаратор sort_func

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //1 - это по какому элементу идет сортировка, т.е. по второму
        }
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558789
Vladimir1R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivЯ что-то совсем не понял, как это должно работать.
Там нет пересчёта координат ячейки в матрице в координаты ячейки в одномерном векторе.
Вызов qsort(&arr[0], count_eliments, sizeof(Tfloat)*dimension*2, sort_func); неверный.
Да и вообще у тебя нет размерностей матрицы.
Также немаловажно, как матрица хранится в векторе -- по столбцам или по строкам.

В общем, бред какой-то ...

по входным параметрам stdlib qsort:
Код: plaintext
1.
2.
3.
4.
5.
6.
qsort(
&arr[0], //--ссылка на первый элемент массива 
count_eliments, //--всего количество объектов, которые следует сортировать (в моем случае берется из свойства класса, сортировать я хочу строки, следовательно, количество объектов - это количество строк матрицы)
sizeof(Tfloat)*dimension*2,  //--длинна объекта для сортировки, в моем случае, это длинна строки = размер Tfloat * размерность * 2, ну т.е. в размерности 3 c типом float=4 байта, строка будет иметь вид x1,x2,,x3,v1,v2,v3  = 4 байта*3(размерность)*2=строк 24 байта
sort_func  //--ссылка на функцию компаратор, которая производит сравнения двух элементов
);



qsort отдает две ссылки на адрес компаратору, на адрес &arr[0] и на сдрес &arr[0]+24 байта, компаратор сравнивает, и если делает вывод что блоки надо поменять местами, то берет первый блок памяти от &arr[0] до &arr[0]+24-1 и второй блок от &arr[0]+24 до &arr[0]+24*2-1 и меняет их местами (тоесть меняет местами строки).

Ну в общем то это у меня работает,
но не получается передавать компаратору параметр сортировки, который бы задавал по какому элементу сортировать строки

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //<===ВОТ  ЗДЕСЬ ХОТЕЛОСЬ БЫ УКАЗАТЬ КАКОЙ НИБУДЬ ПАРАМЕТР param вместо "1"
        }
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558801
Vladimir1R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivТакже немаловажно, как матрица хранится в векторе -- по столбцам или по строкам.


Матрица A=
{
{1,2,3,4},
{1,2,3,4},
{1,2,3,4},
{1,2,3,4}
};
равно
{{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
равно
{1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558803
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir1RПланируется работать с большим количеством частиц, например уже при 1 000
000 000 частиц * 64bit для указателя ~8 ГБ на указатели.
Ты всерьёз рассчитываешь работать с квадратным массивом размера миллиард-на-миллиард
целиком в памяти?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558817
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir1R , ану колись что потом с данными будешь делать? После сортировки.
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558849
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir1RПодскажите, пожалуйста, почему это совсем не экономит память?
Планируется работать с большим количеством частиц, например уже при 1 000 000 000 частиц * 64bit для указателя ~8 ГБ на указатели. Если рассматривать задачу в одномерном случае с типом float, то придется потратить треть памяти только на указатели.

Может я что то упускаю из виду, тогда подскажите, пожалуйста, все таки, почему память мы в таком случае не экономим?

Экономим, экономим.
Мы не знали, что у тебя такие размеры данных.
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558855
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, учту,
но как то это сложно получается.


Ничего сложного.
К тому же, это собственно единственный вариант решения этой задачи.


По скорости и по памяти в таком случае дешевле, мне кажется, сформировать на основе одномерного вектора - вектор векторов, и скормить его std::sort, а в качестве компаратор указать функтор, у которого в свойстве будет параметр для сортировки.


Можно и так. но накладуха будет одинаковая, или даже больше в случае векторов векторов.


Но все таки это крайне не экономично выходит, и как то не красиво.

Э...м... ну, думай сам тогда, предлагай варианты свои.




В общем то у меня задача минимум - как передать параметр сортировки в компаратор sort_func

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //1 - это по какому элементу идет сортировка, т.е. по второму
        }




Используй не компаратор--функцию, а компаратор-класс.



Кроме того, на таких больших данных будет существенным также алгоритм сортировки.
Они разные, по стоимостям и по стоимостям перемещений, и статистически.
Например, QSORT очень плохо работает при почти отсортированном наборе.
Надеюсь, ты всё это учитываешь.
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558860
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir1RMasterZivТакже немаловажно, как матрица хранится в векторе -- по столбцам или по строкам.


Матрица A=
{
{1,2,3,4},
{1,2,3,4},
{1,2,3,4},
{1,2,3,4}
};
равно
{{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
равно
{1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};

А кто тебя знает, что ты тут строками считаешь.
Я могу тебе точно сказать, что твоя задача как-то решается твоим способом при сортировке строк и хранении матрици по строкам,
или сортировке столбцов и хранении матрицы по столбцам, но в остальных случаях она твоим способом не решается вообще.
Поэтому я и говорю -- это важно.

По строкам -- это когда в памяти сначала идут все элементы первой строки, потом второй и так далее. ПО столбцам -- соотв. наоборот.
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558861
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovVladimir1RПланируется работать с большим количеством частиц, например уже при 1 000
000 000 частиц * 64bit для указателя ~8 ГБ на указатели.
Ты всерьёз рассчитываешь работать с квадратным массивом размера миллиард-на-миллиард
целиком в памяти?..


ну может быть миллиард на 10 только...
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558869
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНапример, QSORT очень плохо работает при почти отсортированном наборе.
Он, как и любой другой обменный алгоритм скорее в данном случае сдохнет на скорости обмена
элементов. Сортировка вставками хоть и традиционно медленнее, но в данном случае может
выйграть.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558960
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir1R
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[1] - b1[1];  //<===ВОТ  ЗДЕСЬ ХОТЕЛОСЬ БЫ УКАЗАТЬ КАКОЙ НИБУДЬ ПАРАМЕТР param вместо "1"
        }


Если массив будет один (так оно и будет как я понял), то вынеси индекс в глобальную переменную
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
char cSortIndex = 1;
...
        static int sort_func(const void *a, const void *b)
        {
            Tfloat* a1=(Tfloat*) a;
            Tfloat* b1=(Tfloat*) b;
 
            //cout<<"sort:"<<a1[2]<<"   "<<b1[2]<<endl;
            return a1[cSortIndex] - b1[cSortIndex];
        }


Коряво, но для твоей задачи вполне подойдет.
...
Рейтинг: 0 / 0
Отсортировать по одной из координат матрицу, представленную как одномерный массив
    #38558970
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Автор затих.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Отсортировать по одной из координат матрицу, представленную как одномерный массив
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]