0

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;
}
  • what is the meaning of "doesnt work" ? – 463035818_is_not_an_ai Mar 31 '22 at 11:52
  • 3
    `circle1[5]` is an access out of the bounds of the array (undefined behaviour). The array has 5 elements and you are trying to access the 6th. – rturrado Mar 31 '22 at 11:54
  • The output is the same as the input. For example if the input is: 4 5 3 and 2 3 1 then the output is the same. The output should be in an ascending order. – Andrew Choi Mar 31 '22 at 11:55
  • 1
    You only sort a single element, so order won't change. I guess you meant `sort(circle1, circle1 + *ptr1, compare);`. However, there are several other issues with your code. May I suggest getting [a good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to learn from? – Yksisarvinen Mar 31 '22 at 11:57
  • It did work but the coordinates, for some reason, changed their places too. – Andrew Choi Mar 31 '22 at 12:11

1 Answers1

2

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)]
Wisblade
  • 1,483
  • 4
  • 13
  • 1
    Aside: `std::ranges::sort(circles, std::ranges::less, &circle::area)` since C++20 – Caleth Mar 31 '22 at 13:19
  • @Caleth Thanks, didn't had time to seek in details for C++20 for now, still mostly at C++17. A bit deceived, I would have loved a (really) simple `std::sort(circles,&circle::area)` or `std::sort(circles,)` to really have shorter calls... Maybe we will get that in C++30... – Wisblade Mar 31 '22 at 13:28