使用STL算法排序对动态结构数组进行排序

时间:2014-05-02 11:22:47

标签: c++ algorithm sorting

我在排序动态分配的struct数组时遇到问题,请帮我找出问题所在。

这是我的代码

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

struct Box{
    int *dimval;
    int dim;

    ~Box(){
        delete[] dimval;
    }

    friend bool operator < (const Box& a, const Box& b){
        for(int i=0; i<a.dim;i++){
            if(a.dimval[i]>b.dimval[i])
                return false;
        }
        return true;
    }

    void msort(){
        sort(dimval, dimval+dim);
    }

} *boxes;

int main(){
    int num_box, dim;

    scanf("%d%d", &num_box, &dim);

    boxes = new Box[num_box];
    for(int i=0;i<num_box;i++){
        boxes[i].dim = dim;
        boxes[i].dimval = new int[dim];
    }

    for(int i=0;i<num_box; i++){
            for(int j=0;j<dim; j++){
                scanf("%d", &(boxes[i].dimval[j]));
            }
            boxes[i].msort();
    }

    for(int i=0;i<num_box; i++){
            for(int j=0;j<dim; j++){
                cout<<boxes[i].dimval[j]<<" ";
            }
            cout<<endl;
    }
    cout<<"-----"<<endl;

    sort(boxes, boxes+num_box);
    for(int i=0;i<num_box; i++){
        for(int j=0;j<dim; j++){
            cout<<boxes[i].dimval[j]<<" ";
        }
        cout<<endl;
    }
    cout<<"xxxxxxx"<<endl;
}

给出样本输入

8 6
5 2 20 1 30 10
23 15 7 9 11 3
40 50 34 24 14 4
9 10 11 12 13 14
31 4 18 8 27 17
44 32 13 19 41 19
1 2 3 4 5 6
80 37 47 18 21 9

上面代码段的输出是

1 2 5 10 20 30 
3 7 9 11 15 23 
4 14 24 34 40 50 
9 10 11 12 13 14 
4 8 17 18 27 31 
13 19 19 32 41 44 
1 2 3 4 5 6 
9 18 21 37 47 80 
-----
1 2 3 4 5 6 
1 2 5 10 20 30 
201056 200608 9 11 15 23 
4 14 24 34 40 50 
9 10 11 12 13 14 
4 8 17 18 27 31 
201728 200784 19 32 41 44 
9 18 21 37 47 80 
xxxxxxx

正如你所看到的,在Box结构中排序是好的,但在Box之间进行排序很麻烦,任何人都可以帮助解释这里的问题以及如何解决它。感谢

----------------------的更新 ----------------- ----------------------

我知道使用指针框可能是恶魔,但我看不出原因,请赐教理由和实例。 此外,以下是示例解决方案的代码片段。在这里,唯一的区别是它使用的是struct数组而不是指向动态分配数组的指针,并且它获得了正确的输出

这是代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

struct Node{
    int A[12];
    int k;
    void Sort(){
        sort(A,A+k);
    }
    friend bool operator < (const Node&a, const Node&b){
        for(int i=0; i<a.k; ++i){
            if(a.A[i]>b.A[i])return false;
        }
        return true;
    }
}arr[32];

int n,k;

int main(){
scanf("%d%d",&n,&k);
       for(int i=0; i<n; ++i){
            for(int j=0; j<k; ++j)
                scanf("%d",&arr[i].A[j]);
            arr[i].k=k;
            arr[i].Sort();
        }
        for(int i=0;i<n; i++){
            for(int j=0;j<k; j++){
                cout<<arr[i].A[j]<<" ";
            }
            cout<<endl;
        }
        cout<<"-----"<<endl;

        sort(arr,arr+n);
        for(int i=0;i<n; i++){
            for(int j=0;j<k; j++){
                cout<<arr[i].A[j]<<" ";
            }
            cout<<endl;
        }
        cout<<"xxxxxx"<<endl;
}

1 2 5 10 20 30 
3 7 9 11 15 23 
4 14 24 34 40 50 
9 10 11 12 13 14 
4 8 17 18 27 31 
13 19 19 32 41 44 
1 2 3 4 5 6 
9 18 21 37 47 80 
-----
1 2 3 4 5 6 
1 2 5 10 20 30 
3 7 9 11 15 23 
4 14 24 34 40 50 
9 10 11 12 13 14 
4 8 17 18 27 31 
13 19 19 32 41 44 
9 18 21 37 47 80 
xxxxxx

--------------------------- -UPDATE 2 ---------- -------------

我尝试将复制构造函数和赋值重载添加到我的Box结构中,但这并没有按预期方式解决。错误代码为ntdll!RtlpNtEnumerateSubKey() at 0x779d0725
 这个实现有什么问题吗?

struct Box{
    int *dimval;
    int no;
    int dim;

    Box(){};

    Box(const Box& another){
        no = another.no;
        dim = another.dim;
        dimval = new int[no];
        memcpy(dimval, another.dimval, dim*sizeof(int));
    }

    Box& operator = (const Box& another){
        if(this != &another){
            no = another.no;
            dim = another.dim;
            int* tmp = new int[no];
            delete [] dimval;
            dimval = tmp;
            memcpy(dimval, another.dimval, dim*sizeof(int));
        }
        return *this;
    }

    ~Box(){
        delete[] dimval;
    }

    friend bool operator < (const Box& a, const Box& b){
        for(int i=0; i<a.dim;i++){
            if(a.dimval[i]>=b.dimval[i])
                return false;
        }
        return true;
    }

    void msort(){
        sort(dimval, dimval+dim);
    }

} *boxes;

1 个答案:

答案 0 :(得分:2)

很明显,为什么订购不正确。您的operator <错误,只要一个元素小于另一个元素,就应该返回true

至于数据损坏,因为你违反了"rule of three" - 你有自定义析构函数,但没有复制构造函数或赋值运算符。 sort生成副本它排序的元素,当析构函数命中时,删除它所持有的指针。这会导致未定义的行为。

编辑:代码使用固定数组但不是指针的原因是默认的复制构造函数和赋值运算符将生成完整副本 - 当原始文件被销毁时,它不会#39 ;弄乱副本或使他们的记忆无效。

你的&#34;修复&#34;可能看似有效,但现在你有内存泄漏。没有人会去delete那些指针。

关于operator <的另一点,永远不会使用A=B; if(A<B)返回true,但是你的确是