2011-05-04 56 views
0

我有一組點(x,y,z)。我想要使​​用第一列對第一列和第二列進行排序,並根據排序第一列重新排列第二列和第三列。是否有可能在C++中做到這一點,如果可以的話,你可以幫我。用行排序列

因此,我附上了我的實現代碼,但在第31行和第32行中,我收到了一條錯誤信息「const const vod *'無效轉換爲'const int [*] [3]'」幾種方法,但我的努力還沒有成功。我在這裏使用'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; 
} 

回答

1

它幾乎肯定最容易使用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

好回覆。請編輯顯示使用'std :: sort'和一個比較'Point'對象的函數。這將允許OP使用不同的排序方案,而無需每次更改「Point」類。 :-) – 2011-05-04 17:54:17

+0

@Thomas:至少IMO,這不是一個好主意。這個問題表明在一個訂單中只有*有興趣*海事組織,增加其他人會混淆而不是澄清。 – 2011-05-04 18:26:50

+0

嗨,傑裏,謝謝你的回覆,但我想這樣做,而不需要改變我的班級點,所以告訴我在輸入我的所有數據之後,在班級以外的地方輸入數據的方法。謝謝 – aki 2011-05-04 18:42:31

0

cmp函數的參數實際上const Point *px在您的CA SE。您可能無法以這種方式將它們聲明爲參數,但稍後您肯定可以使用void指針。

進一步參考here