сортировка столбца со строками - PullRequest
0 голосов
/ 04 мая 2011

У меня есть набор точек (x, y, z). Я хочу отсортировать эти данные, используя первый столбец, а 2-й и 3-й столбцы должны быть переставлены в соответствии с сортировкой 1-го столбца. Можно ли сделать это в C ++, если это так, вы могли бы помочь мне, пожалуйста.

При этом я прилагаю коды своей реализации, но я получил сообщение об ошибке «недопустимое преобразование из« const »vod *» в «const int [*] [3]» «в строках 31 и 32. Я пробовал это с использованием нескольких методы, но мои усилия пока не увенчались успехом. Я использовал здесь «qsort» для этого, есть ли другие методы или я могу использовать «sort» для этого. Поскольку у меня очень большой набор данных, я хочу использовать быстрый метод. Итак, что мне нужно в конце, набор данных, который отсортирован только по 1-му столбцу, как в следующем примере: до сортировки

34  12  12
12  34 15
24  20  34
13  11  10
40  23  32

после сортировки

12  34 15
13  11  10
24  20  34
34  12  12
40  23  32

если хорошие методы помогут мне написать коды ... спасибо

#include <iostream>
#include <cstdlib>
#include <vector>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

class Point
{
   private:          
    double x;
    double y;
    double z;

   public:
     Point(){};
     ~Point(){};

   Point(double X, double Y, double Z){
     x=X;y=Y;z=Z; }

   double X(){return x;}
   double Y(){return y;}
   double Z(){return z;}
};

int cmp ( const void *pa, const void *pb ) {
const int (*a)[3] = pa;
const int (*b)[3] = pb;
if ( (*a)[1] < (*b)[1] ) return -1;
if ( (*a)[1] > (*b)[1] ) return +1;
return 0;
}

int main ( ) {
vector<Point> points;
int input_x,input_y,input_z;       
   int i=0;
   while(i<6){//data set,it is a example, actual data come from a file 

         cout<<"x: ";cin>>input_x;
         cout<<"y: ";cin>>input_y;
         cout<<"z: ";cin>>input_z;
         Point point(input_x,input_y,input_z);                        
         points.push_back(point);
        i++;                         
         }        
for (int i=0;i<points.size();i++){//before sort
cout<<points[i].X()<<" "<<points[i].Y()<<" "<<points[i].Z()<<endl;
}

qsort( points, 6, sizeof points[0], cmp );

for (int i=0;i<points.size();i++){//after sort
cout<<points[i].X()<<" "<<points[i].Y()<<" "<<points[i].Z()<<endl;
}            
system("PAUSE");
return 0;
}

Ответы [ 2 ]

1 голос
/ 04 мая 2011

Почти наверняка проще всего использовать std::sort вместо qsort:

class Point { 
    int x, y, z;
public:
    Point(int x, int y, int z) : x(x), y(y), z(z) {}

    bool operator<(Point const &other) { 
        return x < other.x;
    }
    // skipping the reading and other stuff for now...
};

int main() { 
    std::vector<Point> points;
    // add some Points to `points` here.

    // sort using order defined in Point::operator<:
    std::sort(points.begin(), points.end());
    return 0;
}

Редактировать: чтобы сохранить сравнение отдельно от сравниваемых элементов, вы используете отдельную функцию или функтор для выполнениясравните и передайте это std::sort.В вашем классе есть несколько вещей, которые вы действительно хотите изменить в любом случае - по крайней мере, так как ваши Point::X(), Point::Y() и Point::Z() не изменяют объект Point, вы хотите сделатьих const функций-членов.Как только вы это сделаете, сортировка будет довольно тривиальной:

#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>

class Point { 
    double x, y, z;
public:
    double X() const { return x; }
    double Y() const { return y; }
    double Z() const { return z; }

    Point(double x=0.0, double y=0.0, double z=0.0) : x(x), y(y), z(z) {}
};

namespace std { 
ostream &operator<<(ostream &os, Point const &p) { 
    return os << "(" << p.X() << ", " << p.Y() << ", " << p.Z() << ")";
}
}
struct byX { 
    bool operator()(Point const &a, Point const &b) { 
        return a.X() < b.X();
    }
};

int main(){ 
    std::vector<Point> points;

    for (int i=0; i<10; i++)
        points.push_back(Point(rand(), i, i));

    std::cout << "Unsorted:\n";
    std::copy(points.begin(), points.end(), 
        std::ostream_iterator<Point>(std::cout, "\n"));

    std::sort(points.begin(), points.end(), byX());

    std::cout << "\nSorted:\n";
    std::copy(points.begin(), points.end(), 
        std::ostream_iterator<Point>(std::cout, "\n"));
    return 0;
}

Технически, я полагаю, я должен добавить еще одну незначительную деталь: если значение x в любой из ваших точек является NaN, этоне будет работать правильноNaN не равен чему-либо (даже самому себе), что нарушает строгий слабый порядок, необходимый для std::sort.

0 голосов
/ 04 мая 2011

Аргументы функции cmp на самом деле const Point *px в вашем случае.Возможно, вы не сможете объявить их в качестве аргументов таким образом, но вы наверняка сможете cast указатели void позже.

Дальнейшая ссылка здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...