Andrew Choi
Andrew Choi

Reputation: 33

How to sort a structure in an ascending order in c++

I was trying to sort the areas of a circle in an ascending order. First, the user chooses the number of circles, then he should type the coordinates and the area of his circles. In the end the program should output the radius of a circle in an ascending order.But the output of areas is not in an ascending order(It's the same as input). What is my problem?

#include<iostream>
#include <algorithm>
using namespace std;
struct circle {
    int 반지름;
    int coordinates;
    int coordinates2;
};
bool compare(circle a, circle b){
    if(a.반지름 < b.반지름)
        return 1;
    else
        return 0;
}

int main()
{
    int n = 1;
    int* ptr1;
    ptr1 = new int;
    circle* circle1;
    circle1 = new (nothrow) circle[5];
    circle1[0].반지름;
    circle1[0].coordinates;
    circle1[0].coordinates2;
    
    circle1[1].반지름;
    circle1[1].coordinates;
    circle1[1].coordinates2;
    
    circle1[2].반지름;
    circle1[2].coordinates;
    circle1[2].coordinates2;
    
    circle1[3].반지름;
    circle1[3].coordinates;
    circle1[3].coordinates2;
    
    circle1[4].반지름;
    circle1[4].coordinates;
    circle1[4].coordinates2;
    
    circle1[5].반지름;
    circle1[5].coordinates;
    circle1[5].coordinates2;
    cout << "Enter the number of circles: ";
    cin >> *ptr1;
    cout << "중심 좌표, 반지름 : " << endl;
    
    for (int i = 0; i < *ptr1; i++) {
        cin >> circle1[i].coordinates >> circle1[i].coordinates2 >> circle1[i].반지름;
}
    
    sort(circle1, circle1 + 1, compare);

    for (int i = 0; i < *ptr1; i++) {
        cout << "The result:  " << circle1[i].coordinates <<  " " << circle1[i].coordinates2 << " " << circle1[i].반지름 << endl;
    }
    
    delete[] circle1;
    delete ptr1;
    return 0;
}

Upvotes: 0

Views: 444

Answers (1)

Wisblade
Wisblade

Reputation: 1644

That's not C++, that's a strange and hybrid thing between C and C++... And this is your main problem. You're mixing up things that should not be mixed, not if you don't know PERFECLY what you do - and obviously, it's not the case, otherwise your code should have worked, and it haven't.

Corrected code, in real C++:

#include <iostream>     // std::cout & co
#include <algorithm>    // std::sort
#include <cstdlib>      // std::rand & co
#include <vector>       // std::vector

struct circle {
    int area ;
    int x ;
    int y ;
} ;

// For printing a circle easily and not repeat code X times.
// Print as: [area@(x,y)]
std::ostream& operator<<(std::ostream& os, const circle& c) {
    os << "[" << c.area << "@(" << c.x << "," << c.y << ")]" ;
    return os;
}

int main() {
    // Set a constant seed: each run will produce the same result, if needed to debug.
    std::srand(1234) ;
    // 5 circles declared within a vector, not a C array.
    auto circles = std::vector<circle>(5) ;

    // Fill the vector.
    std::cout << "Original circles:" << std::endl ;
    // Use a simpler for syntax.
    for ( auto& c: circles ) {
        // Random values used. The fixed seed will always give the same values on each run.
        c.area = 10 + std::rand() % 50 ;
        c.x = std::rand() % 1920 ;
        c.y = std::rand() % 1080 ;
        // Print the circle.
        std::cout << "\t" << c << std::endl ;
    }
    // Sort the vector, use a lambda expression for the compare operator.
    // No need for a "real" function, if it's used only once and only there.
    // Compare function returns directly a bool, not an integer.
    std::sort(circles.begin(), circles.end(), [](const circle& a, const circle& b) -> bool { return (a.area<b.area) ; });

    // Display sorted vector.
    std::cout  << std::endl << "Sorted circles:" << std::endl ;
    for ( const auto& c: circles )
        std::cout << "\t" << c << std::endl ;
    return 0;
}

Still strange that you use area instead of radius or diameter, but anyway... Area is for a disc, not a circle, but that's mathematical precision at this stage.

First, if you print a structure like circle at least twice, do a stream operator to do it only once. Please note that I send directly the structure to std::cout, after...

Then, I use a C++ container, not a C allocated array. You can still allocate memory for big amount of data, but for this example, that's unneeded.

Then, instead of asking for each values, I use std::rand() to fill them. Easier. Can be used in any language. Refined trick: I initialize the pseudo-random generator to a constant, fixed value, so each time the program is run, it will generate the exact same sequence of pseudo-random numbers - this can vary on each machine / OS / compiler / compiler version but it will be constant on YOUR machine during your tests, and it can be debugged easily.

Please also note that I use a compact form of for that will iterate on the whole circles container, giving me each time a circle& (reference) on each element so that I can modify it - needed for initialization.

Now, the sort itself: from begin() to end() of the container, using a lambda expression to define the compare operator. Please note that I return directly the result of the comparison, which is a bool, and that I don't cast an int to a bool implicitely...

Finally, print the result. Note that this time, I ask for a const auto& reference, to be sure to not modify data by mistake.

Nothing to delete, C++ will take care of that.

An example output, on my machine:

Original circles:
    [28@(213,881)]
    [18@(16,157)]
    [34@(1468,816)]
    [14@(745,718)]
    [31@(143,818)]

Sorted circles:
    [14@(745,718)]
    [18@(16,157)]
    [28@(213,881)]
    [31@(143,818)]
    [34@(1468,816)]

Upvotes: 2

Related Questions