简体   繁体   中英

Even and odd sorting arrays

I can't get the following program to sort 'orig', 'even', and 'odd' arrays in ascending order.
The code seems fine to me, but it doesn't sort correctly at all, it will separate the array into the original even and odd lists, but the order is random and not in ascending order at all.
The output should look something like this:

Input up to 50 integers. Use a negative number to stop.
The list will be sorted into odd and even values.

Input an integer: 15
Input an integer: 8
Input an integer: 22
Input an integer: 4
Input an integer: 77
Input an integer: 19
Input an integer: 2
Input an integer: -1

 Orig Even Odd 2 2 15 4 4 19 8 8 77 15 22 19 22 77
#include<iostream>
#include<iomanip>
using namespace std;

void DataIn(int Max[], int List[][50]);
void Separate(int Max[], int List[][50]);
int Lowest(int start, int N, int Vector[]);
void Sort(int Max[], int List[][50]);
void DataOut(int Max[], int List[][50]);

int main()
{
    //Index: 0 = input, 1 = even, 2 = odd
    int Max[3] = { 0, 0, 0 };
    int List[3][50];

    cout << "Input up to 50 integers.  Use a negative number to stop.\n";
    cout << "The list will be sorted into odd and even values.\n\n";

    DataIn(Max, List);
    Separate(Max, List);
    Sort(Max, List);
    DataOut(Max, List);
}

void DataIn(int Max[], int List[][50])
{
    cout << "Input an integer: ";
    cin >> List[0][Max[0]];
    while (List[0][Max[0]] > 0)
    {
        cout << "Input an integer: ";
        cin >> List[0][++Max[0]];
    }

    return;
}

void Separate(int Max[], int List[][50])
{
    int n, type;

    for (n = 0; n < Max[0]; ++n)
    {
        if ((List[0][n] % 2) == 0)
            type = 1;
        else
            type = 2;
        List[type][Max[type]++] = List[0][n];
    }

    return;
}

int Lowest(int start, int N, int Vector[])
{
    int i, low = start;
    for (i = start + 1; i < N; i++)
        if (Vector[i] < Vector[low])
            low = i;
    return (low);
}

void Sort(int Max[], int List[][50])
{
    int i, j, k, l;
    double origSort,evenSort,oddSort;
    for (i = 0; i < Max[0] - 1; ++i)
    {
        j = Lowest(i, Max[0], List[50]);
        origSort = List[0][i];
        List[0][i] = List[0][j];
        List[0][j] = origSort;

        k = Lowest(i, Max[1], List[50]);
        evenSort = List[1][i];
        List[1][i] = List[1][k];
        List[1][k] = evenSort;

        l = Lowest(i, Max[2], List[50]);
        oddSort = List[2][i];
        List[2][i] = List[2][l];
        List[2][l] = oddSort;
    }
}

void DataOut(int Max[], int List[][50])
{
    int i;
    int orig = 0, even = 1, odd = 2;
    cout << "\n\n";
    cout << setw(10) << "Orig" << setw(10) << "Even" << setw(10) << "Odd" << "\n\n";
    for (i = 0;i < Max[0];i++)
    {
        if(List[0][i]>0)
            cout << setw(10) << List[orig][i];
        else
            cout << setw(10) << " ";
        if (List[1][i] > 0)
            cout << setw(10) << List[even][i];
        else
            cout << setw(10) << " ";
        if (List[2][i] > 0)
            cout << setw(10) << List[odd][i] << "\n";
        else
            cout << "\n";
        
    }
}

You have overcomplicated yourself too much with a two dimensional array and whatever int Max[3] is.

Things are simple: sort the original vector, then filter the odds and evens. Since you filter after you sort, the two resulting vectors will already be sorted.

Here's the C++20 solution:

int main()
{
    using namespace std::ranges::views;

    std::vector<int> v{15, 8, 22, 4, 77, 19, 2};

    std::ranges::sort(v);

    auto evens = v | filter([] (int a) { return a % 2 == 0; });
    auto odds = v | filter([] (int a) { return a % 2 != 0; });

    for (auto e : v)
        std::cout << e << " ";
    std::cout << std::endl;

    for (auto e : evens)
        std::cout << e << " ";
    std::cout << std::endl;

    for (auto e : odds)
        std::cout << e << " ";
    std::cout << std::endl;
}

You don't even need the variables to store the ranges. You can do the filter in the output loop if you want:

for (auto e : v | filter([] (int a) { return a % 2 == 0; }))
    std::cout << e << " ";
std::cout << std::endl

And here's the non-ranges solution:

int main()
{
    std::vector<int> v{15, 8, 22, 4, 77, 19, 2};
    std::vector<int> evens;
    std::vector<int> odds;

    std::sort(v.begin(), v.end());

    std::copy_if(v.begin(), v.end(), std::back_inserter(evens),
                 [] (int a) { return a % 2 == 0; });
    std::copy_if(v.begin(), v.end(), std::back_inserter(odds),
                 [] (int a) { return a % 2 != 0; });

    for (auto e : v)
        std::cout << e << " ";
    std::cout << std::endl;

    for (auto e : evens)
        std::cout << e << " ";
    std::cout << std::endl;

    for (auto e : odds)
        std::cout << e << " ";
    std::cout << std::endl;
}

If you for whatever reason don't want to use the standard library algorithms you must at least use the standard containers. Ditch the C arrays. And implement the solution following the same logic: sort then filter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM