qsort function

Hi! I have this kind of problem: My program should work like this:
1.Input the number of points that you want to create.
2.For each point write these:
name,x-position, y-position
3.Program should count the length from point to origin(0,0), it is counting in function Leng()
4.All parameters are saving in object abc
5.I create the table of objects TabOb
6. I want to sort my points from min length from point to origin(0,0), to maximum length between point and origin, I want to do this using qsort function from <stdlib.h>
I have an idea to create compare function which helps me to do that but I don’t know how to do this.. can someone help me?

I’ll give you an example of input and output that I want to get at the end:
INPUT
2
B 6 8
A 9 12
D 3 4

OUTPUT:
D 3 4
B 6 8
A 9 12


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  #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;
}
The class with a non-static member of type std::string is not a trivial type.
std::qsort() can't be used for sorting an array of these objects.
(An indirect sort is possible.)
any advice to do this with another method?
std::sort() http://en.cppreference.com/w/cpp/algorithm/sort

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>

struct point
{
    std::string name ;
    int x ;
    int y ;

    int square_of_radius() const { return x*x + y*y ; }
};

int main()
{
    // http://www.mochima.com/tutorials/vectors.html
    std::vector<point> seq = { { "B", 6, 8 }, { "A", 9, 12 }, { "D", 3, 4 } } ;

    // http://en.cppreference.com/w/cpp/algorithm/sort
    // https://solarianprogrammer.com/2011/11/01/cpp-11-lambda-tutorial/
    // http://www.stroustrup.com/C++11FAQ.html#lambda
    std::sort( seq.begin(), seq.end(),
               [] ( const point& a, const point& b ) { return a.square_of_radius() < b.square_of_radius() ; } );

    // http://www.stroustrup.com/C++11FAQ.html#for
    for( const point& pt : seq ) std::cout << pt.name << ' ' << pt.x << ' ' << pt.y << '\n' ;
}

http://coliru.stacked-crooked.com/a/a28c398d1abbdb59
Indirect sort with std::qsort():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>
#include <cstdlib>

struct point
{
    std::string name ;
    int x ;
    int y ;

    int square_of_radius() const { return x*x + y*y ; }
};

point array[] = { { "B", 6, 8 }, { "A", 9, 12 }, { "D", 3, 4 } } ;
const int N = sizeof(array) / sizeof( array[0] ) ;

int compare( const void* pa, const void* pb )
{
    const int i = *static_cast< const int* >(pa) ;
    const int j = *static_cast< const int* >(pb) ;
    const int a = array[i].square_of_radius() ;
    const int b = array[j].square_of_radius() ;
    return (a>b) - (b>a) ;
}

int main()
{
    // indirect sort
    int indices[N] = { 0, 1, 2 } ;
    std::qsort( indices, N, sizeof( indices[0] ), compare ) ;

    for( int i : indices ) std::cout << array[i].name << ' ' << array[i].x << ' ' << array[i].y << '\n' ;
}

http://coliru.stacked-crooked.com/a/042db6ac401d824d
if you put the objects in an array or vector, you can simply use a bubble sort:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <cmath>// sqrt
using namespace std;

class T {
	
	public:
	int x;
	int y;
	string str;
	double length;
	T (int x1, int y1, string str1)
	: x(x1), y(y1), str(str1), length( sqrt(x*x+y*y) ) 	{	}

};

int main()
{
	
	T a(3, 4, "obj1"); // lenth = 5
	T b= {6, 8, "obj2"}; // lenth = 10
	
	std::swap(a,b);

	cout << a.length; //10
	
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// objects sorting by simple bubble sort
#include <iostream>
#include <string>
using namespace std;

struct T 
{
	string str;
	int n;
	double d;
};


int main()
{	
	T arr[5];
	
	for(int i=0; i<5; i++) 
	{
		arr[i].str = "str_" + to_string(i);
		arr[i].n = i;
		arr[i].d = i/3.0;
	}
	
	cout << arr[3].n << endl;
	
	for(int i=0; i<5; i++)
		for(int j=0; j<5; j++)
			if(arr[i].n > arr[j].n) //  descending //sort by any:  str, n or d
				std::swap(arr[i], arr[j]);
	
	cout << arr[3].n << endl;				
	
return 0;
}
I did something like this, but I dont have an idea how to solve the problem with appearing error: 'compare' undeclared identifier, I know what does it means..but.. maybe its sounds funny but i dont have an idea how to solve this..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <string>
#include <stdlib.h> 
#include <algorithm>
using namespace std;


class Klasa{
	string name;
	int    x,y;
	double rr,leng;
	
public:
	Klasa* TabOb;//table of objects
	int t;//number of points

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




	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;
		}
		
		sort(0, t);
	
		qsort(TabOb, t, sizeof(Klasa), compare);

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


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

int main(){

	wy.InputData();
	return 0;
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// sort objects qsort (cstdlib) // anup 30.11.2014
#include <iostream>    
#include <cstdlib> // qsort
#include <cmath> // sqrt
using namespace std;

class klasa {
	string name;
	int x;
	int y;
	double length;		
	public:
		klasa() { }
		klasa (string s, int n1, int n2) : name(s), x(n1), y(n2), length(sqrt(n1*n1+n2*n2)) {} // constructor
		
		friend int compare (const void * a, const void * b);
		void showLength() { cout << length; }
};


int compare (const void * a, const void * b)
{
	klasa *aa; aa= (klasa*)a;
	klasa *bb; bb= (klasa*)b;
	if( (aa->length - bb->length) > 0) return 1;
	else return -1;
}

int main ()
{  		
	klasa ob1("name1", 6, 8);
	klasa ob2("name2", 5, 3);
	klasa ob3("name3", 3, 4);

	klasa ar[3] = {ob1, ob2, ob3};
	qsort (ar, 3, sizeof(klasa), compare);
	
	for(int i=0; i<3; i++)
	{
		ar[i].showLength();
		cout << " ";
	}
	
	return 0;
}


you can also overload < operator to compare objects.
I made few changes in my program and now it works correctly! Thx much for help! I learnt a lot from you ;) I close the topic as solved thx double!!
Topic archived. No new replies allowed.