Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отсортировать матрицу по одной из координат, матрица представлена как 1-мерный массив 
:(
    Опции темы
Vladimir1R
Дата 12.2.2014, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 12.2.2014

Репутация: нет
Всего: нет



Такая задача. 
Есть класс, в котором определена матрица 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, с заданным параметром сортировки (по какому значению сортировать). и реализовать её надо полностью как метод класса.

Вот что сейчас получилось:
Код

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 к данной задачи?

Заранее всех благодарю!
PM MAIL   Вверх
borisbn
Дата 12.2.2014, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Т.к. тебе нужно переставлять местами строки, а в лучшем случае это придётся делать n * log( n ) раз, то предлагаю след. алгоритм:
1) Создать структуру типа такой
Код
struct {
    Tfloat elem;
    int rowIdx;
} ForSort;
bool operator<( const ForSort & left, const ForSort & right ) const {
    return left.elem < right.elem;
}

2) Выделить ещё один вектор для таких структур.
Код
vector< ForSort > forSort;

3) Перед сортировкой заполнить этот вектор из соотв. столбца (как-то так):
Код
void prepareSort( int columnIdx ) {
    for ( int i = 0; i < RowsCount; i++ ) {
        forSort[ i ].elem = arr[ i * ColumnsCount + columnIdx ];
        forSort[ i ].rowIdx = i;
    }
}

4) Сортировать этот массив std::sort'ом
5) расставить строки в массиве arr в соответствии с их номерами из forSort[ i ].rowIdx. Как это сделать - пока не знаю, но, думаю, ты и сам справишься ))


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.4537 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.