【问题标题】:qsort using to sort table of objects [closed]qsort 用于对对象表进行排序[关闭]
【发布时间】:2014-11-29 20:30:10
【问题描述】:

我的程序应该是这样工作的:

  1. 输入您要创建的点数。
  2. 为每个点写下:名称、x 位置、y 位置
  3. 程序应该计算从点到原点的长度(0,0),它在函数 Leng() 中计算
  4. 所有参数都保存在对象 abc 中
  5. 然后我创建对象表 TabOb
  6. 我想对我的点进行排序,从点和原点之间的最小长度 (0,0) 到点和原点之间的最大长度。我想使用 stdlib.h 中的 qsort 函数执行此操作 我有一个创建比较函数的想法,它可以帮助我做到这一点,但我不知道具体如何。有人可以帮我吗?

我会给你一个我想在最后得到的输入和输出的例子:

输入:

2

B 6 8

A 9 12

D 3 4

输出:

D 3 4 

B 6 8

A 9 12

这是我的代码:

#include <iostream>
#include <string>
#include <stdlib.h> 
using namespace std;

class Klasa {
    string name;
    int    x,y;
    double rr,leng;

    Klasa* TabOb;//table of objects
    int t;//number of points
public:
    Klasa(){}
    Klasa(string name, int x,int y) {
        this->name = name;
        this->x = x;
        this->y = y;
        this->leng = Leng();
    }
    double Leng(){
        double rr, sq;
        rr = x*x + y*y;
        sq = sqrt(rr);
        return sq;
    }

    int     getX() { return x; }
    int     getY(){ return y; }
    string getName() { return name; }
    double getLength(){ return leng; }

    int compare(const void * a, const void * b)
    {
        int _a = *(int*)a;
        int _b = *(int*)b;
        if (_a < _b) return -1;
        else if (_a == _b) return 0;
        else return 1;
    }

    void InputData(){
        cin >> t;

        TabOb = new Klasa[t];
        for (int i = 0; i < t; i++){
            string name;
            int    x, y;
            cin >> name;
            cin >> x;
            cin >> y;
            Klasa abc(name, x, y);
            TabOb[i] = abc;
        }


        qsort(TabOb, t, sizeof(int), compare);

        for (int i = 0; i < t; i++){
            cout << TabOb[i].getName() << " " << TabOb[i].getX() << " " << TabOb[i].getY() << " " << TabOb[i].getLength() << endl;
        }
    }
}wy;

int main() {

    wy.InputData();
    return 0;
}

【问题讨论】:

  • 为什么不使用std::sort
  • 另外,我会问你——我给你两个 TabOj 对象。在排序时,您告诉我(以及最终排序)哪个项目在另一个项目之前的标准是什么?不管是什么,这就是你的代码。此外,std::sort 使这变得更加简单,因为您没有做 void* 的东西和所有其他非类型安全的编码。
  • 另外,我不明白你在 compare 函数中在做什么。您正在对 Klasa 对象进行排序,但由于某种原因,当它应该转换为 Klasa* 时,您将类型转换为 int*。这看起来不正确。这就是为什么使用 std::sort 会强制您使用正确的类型,而不是像现在这样对 int* 进行虚假强制转换。

标签: c++ qsort


【解决方案1】:

如果您必须使用qsort,则必须进行以下更改:

int compare(const void * a, const void * b)
 {
    Klasa* obj1 = (Klasa*)a;
    Klasa* obj2 = (Klasa*)b;
    if (obj1->x < obj2->x) 
       return -1;
    else 
    if (obj1->x == obj2->x) 
        return 0;
     return 1;
 }

//...
    qsort(TabOb, t, sizeof(Klasa), compare);

qsort 的第三个参数是您要比较的项目的大小。此外,比较函数期待Klasa*,而不是int,所以你的演员都是错误的。最糟糕的部分是编译器没有告诉你演员阵容不正确。这就是为什么在 C++ 中应该使用std::sort

我的比较很简单,因此请更改您需要比较的内容,因为我不完全理解您要在 Klasa 对象中比较的内容。


为了与qsort 进行比较,这里是std::sort 的用法:

#include <algorithm>
//...
bool compare(Klasa& obj1, Klasa& obj2
{
    return obj1.x < obj2.x;
}
//...
TabOb = new Klasa[t];
std::sort(TabOb, TabObj + t, compare);

compare 函数接受两个 Klasa 对象,如果 obj1 在排序中出现在 obj2 之前,则返回 true。否则返回false。我做了一个简单的排序标准,所以更改 compare 以符合您的要求。

请注意,没有类型转换,并且比较返回 truefalse,而不是 1、0 和 -1。没有必要在 C++ 程序中使用 qsort,也不建议使用 IMO。相反,如果您正在编写 C++,请始终更喜欢 std::sort。如果您正在编写 C 代码,那就另当别论了,因为您别无选择,只能使用 qsort

此外,您的代码存在内存泄漏。您可以通过在代码中使用 std::vector 而不是 new[] 来缓解这种情况。

【讨论】:

    【解决方案2】:

    在比较函数中,您将参数转换为整数,而它们应该是klasa 类型。接下来在比较函数中,您必须计算点到原点的距离,这将是排序标准。

     int compare(const void * a, const void * b)
    {
        Klasa j = *(Klasa*)a;
        Klasa k = *(Klasa*)b;
        int temp1=sqrt(pow((double) j.getX(),2)+pow((double) j.getY(),2));
        int temp2=sqrt(pow((double) k.getX(),2)+pow((double) k.getY(),2));
        if (temp1 < temp2) return -1;
        else if (temp1 == temp2) return 0;
        else return 1;
    }
    

    那么你应该调用快速排序为

       qsort(TabOb, t, sizeof(Klasa), compare);
    

    因为类型又是klasa 而不是int

    最后,您必须将比较功能放在课堂之外。

    【讨论】:

      猜你喜欢
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      • 2019-05-23
      • 1970-01-01
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多