qsort 用于对对象表进行排序

qsort using to sort table of objects

本文关键字:排序 对象 用于 qsort      更新时间:2023-10-16

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

  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;
}

如果必须使用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[]来缓解此问题。

在比较函数中,您将参数转换为整数,而它们应该是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

最后,你必须把你的比较函数放在你的类之外。