不确定我的排序算法有什么问题

时间:2019-07-14 19:33:52

标签: c++ arrays string sorting struct

我一直在尝试使用C字符串对输入的数据进行排序。到目前为止,一切都很好,除非涉及情况3和4,也就是排序和显示排序后的数据,输出不是预期的。 显示的排序数据的输出仅给我

0 0 0 0 0 0 0 0 0 。 。 。 这是我第一次使用C字符串,但我仍然不太熟悉结构的概念。如果有人有其他方法,或者知道案例3/4的代码出了什么问题,请告诉我。谢谢

这是我的代码:

#include <iostream>
#include <string>
using namespace std;

struct sPlayer {
    char lname[20];
    char fname[20];
    int birthmonth;
    int birthday;
    int birthyear;
};
int main()
{

    int choice;
    sPlayer players[10];
    sPlayer sortedData[10];

    while (true) {
        cout << "Choose an option: " << endl;
        cout << "1 - Input data, 2 - display original data, 3 - 
            sort data by last name,\n4 - display sorted data,
            5 - search by
                    last name,\n6 - display goodbye message and exit the program " << 
            endl;

        cin >> choice;
        switch (choice) {
        case 1:

            cout << "Enter data for 10 soccer players " << endl;
            cout << "Enter in order: Last name, first name,(as integers) birth month, birthday, birth year, ";
            cout << "separated by a space. Press [ENTER] to enter next player data. " << endl;

            for(int i = 0; i < 10; i++)
            {
                cin >> players[i].lname;
                cin >> players[i].fname;
                cin >> players[i].birthmonth;
                cin >> players[i].birthday;
                cin >> players[i].birthyear;
            }
            break;

        case 2:
            cout << "Unsorted data: " << endl;
            for (int i = 0; i < 10; i++) {
                cout << players[i].lname << " "
                     << players[i].fname << " " << players[i].birthmonth;
                cout << " " << players[i].birthday << " " << players[i].birthyear << endl;
            }
            cout << endl;
            break;

        case 3:
            sortedData[10] = players[10];
            for (int i = 0; i < 9; i++) {
                for (int j = i + 1; j < 10; j++) {

                    if (strcmp(sortedData[i].lname, sortedData[j].lname) > 0) {
                        char tempLastName[20];
                        char tempFirstName[20];
                        int tempBirthmonth;
                        int tempBirthday;
                        int tempBirthyear;

                        strcpy(tempLastName, sortedData[i].lname);

                        strcpy(sortedData[i].lname, sortedData[j].lname);

                        strcpy(sortedData[j].lname, tempLastName);

                        strcpy(tempFirstName, sortedData[i].fname);

                        strcpy(sortedData[i].fname, sortedData[j].fname);

                        strcpy(sortedData[j].fname, tempFirstName);

                        tempBirthmonth = sortedData[i].birthmonth;

                        sortedData[i].birthmonth = sortedData[j].birthmonth;

                        sortedData[j].birthmonth = tempBirthmonth;

                        tempBirthday = sortedData[i].birthday;

                        sortedData[i].birthday = sortedData[j].birthday;

                        sortedData[j].birthday = tempBirthday;

                        tempBirthyear = sortedData[i].birthyear;

                        sortedData[i].birthyear = sortedData[j].birthyear;

                        sortedData[j].birthyear = tempBirthyear;
                    }
                }
            }
            break;

        case 4:
            cout << "Sorted data: " << endl;

            for (int i = 0; i < 10; i++) {
                cout << sortedData[i].lname << " 
                                               " << sortedData[i].fname << "
                                               " << sortedData[i].birthmonth << "
                                               " 
                     << sortedData[i].birthday << " " << sortedData[i].birthyear << endl;
            }
            cout << endl;
            break;

        case 5:
            char searchString[20];
            while (true) {
                cout << "Enter one or more 
                        starting letters of the last name(enter '//' to quit this option)
                    : " << endl;
                    cin
                    >> searchString;

                if (strcmp(searchString, "//")
                    == 0)
                    break;
                else {
                    int length = strlen(searchString);

                    strcat(searchString, "xx");
                    bool notFound = true;

                    for (int i = 0; i < 10; i++) {
                        if (strncmp(players[i].lname, searchString, length) == 0) {
                            cout << players[i].lname << " " << players[i].fname << " " << players[i].birthmonth << " " << players[i].birthday << " " << players[i].birthyear << endl;

                            notFound = false;
                        }
                    }
                    if (notFound) {
                        cout << "Not 
                                found." << endl;
                    }
                }
            }
            break;

        case 6:
            cout << "Good Bye " << endl;
            break;

        default:
            cout << "Invalid Option , Try again" << endl;
        }
        if (choice == 6)
            break;
    }

    return 0;
}

1 个答案:

答案 0 :(得分:0)

通常最好将大问题分解为较小的问题。我建议使用子功能。

并且,您应该使用C ++ STL和算法。那很有帮助。你会看见。请勿使用char lname[20]sPlayer players[10];之类的普通数组。请使用STL容器。它们可以成长,可以调整大小。它还可以大大减少您的复印工作。

使用面向对象的方法。数据和方法应归为一类。 sPlayer知道如何打印和阅读。因此,将这些方法添加到您的结构中。

您应该使用算法。像std::copy。这使生活更轻松。

您的帖子下方的评论中已经提到了错误。

请查看修改后的示例(一种可能性):

#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>

struct sPlayer {
    // Data
    std::string lname;
    std::string fname;
    unsigned int birthmonth;
    unsigned int birthday;
    unsigned int birthyear;

    // Extractor operator
    friend std::istream& operator >> (std::istream& is, sPlayer& sp) {
        return is >> sp.lname >> sp.fname >> sp.birthmonth >> sp.birthday >> sp.birthyear;
    }

    // Inserter operator
    friend std::ostream& operator << (std::ostream& os, const sPlayer& sp) {
        return os << sp.fname << ' ' << sp.lname << ' ' << sp.birthmonth << '/' << sp.birthday << '/' << sp.birthyear;
    }
};

constexpr int CmdInputData = 1;
constexpr int CmdDisplayOriginalData = 2;
constexpr int CmdSortByLastName = 3;
constexpr int CmdDisplaySortedData = 4;
constexpr int CmdSearchLastName = 5;
constexpr int CmdExit = 6;

// Read users choice. Check for valid data
int getMenuSelection()
{
    std::cout << "\n\nChoose an option:\n   1 - Input Data\n   2 - Display original data\n" <<
        "   3 - Sort data by last name\n   4 - Display sorted data\n   5 - Search by last name\n" <<
        "   6 - Exit the program\n\n --> ";

    // Here we will store the selection
    int selection{ 0 };
    // As long as there is no good selection, we will read a number
    bool noGoodSelection = true;
    while (noGoodSelection) {
        // Read selection
        std::cin >> selection;
        // Check if valid
        noGoodSelection = ((selection < CmdInputData) || (selection > CmdExit));
        // If not, show message and read again
        if (noGoodSelection) {
            std::cout << "Invalid Option , Try again" << '\n';
            std::cin.clear(); std::cin.ignore();
        }
    }
    return selection;
}


void enterSPlayerData(std::vector<sPlayer>& sp)
{
    // Ask, how many players we would like to register
    std::cout << "\n\nEnter soccer player data\n\nHow many player do you want to register: ";
    size_t numberOfPlayersToRegister{ 0 };
    std::cin >> numberOfPlayersToRegister;

    // Make space in vector for all the players
    sp.clear();
    sp.resize(numberOfPlayersToRegister);

    // Read all players
    for (size_t i = 0; i < numberOfPlayersToRegister; ++i) {
        std::cout << '\n' << (i+1) <<"  Enter --> Last Name --> First Name --> Birt Month --> Birth Day --> Birth Year\n";
        std::cin >> sp[i];
    }
}


int main()
{
    // This is our player vector
    std::vector<sPlayer> players{};

    // Andf here a copy with the sorted data
    std::vector<sPlayer> playersSorted{};

    // If we want zo search a name in the vector
    std::string searchString{};
    bool playerFound{ false };

    // Menu selection
    int selection{ CmdExit };
    do {
        selection = getMenuSelection();
        switch (selection)
        {
        case CmdInputData:
            // Read player vector
            enterSPlayerData(players);
            break;

        case CmdDisplayOriginalData:
            // Show all players
            std::cout << "\n\nPlayer List\n\n";
            std::copy(players.begin(), players.end(), std::ostream_iterator<sPlayer>(std::cout, "\n"));
            break;

        case CmdSortByLastName:
            // Copy player list and sort the copy
            playersSorted.clear();
            std::copy(players.begin(), players.end(), std::back_inserter(playersSorted));
            std::sort(playersSorted.begin(), playersSorted.end(), 
                [](const sPlayer & sp1, const sPlayer & sp2) { return sp1.lname < sp2.lname; });
            break;

        case CmdDisplaySortedData:
            // Show the sorted data
            std::cout << "\n\nPlayer List Sorted\n\n";
            std::copy(playersSorted.begin(), playersSorted.end(), std::ostream_iterator<sPlayer>(std::cout, "\n"));
            break;

        case CmdSearchLastName:
            // Sear for a part of a name
            std::cout << "\n\nSearch Player name\n\nEnter some starting characters of Name:  ";
            std::cin >> searchString;
            playerFound = false;
            std::for_each(players.begin(), players.end(),
                [&searchString, &playerFound](const sPlayer & sp) {
                    if (sp.lname.find(searchString) != std::string::npos) {
                        std::cout << "Found Player\n" << sp << '\n';
                        playerFound = true;
                    }
                }
            );
            if (!playerFound) std::cout << "\nNo player found\n\n";
            break;
        default:
            selection = CmdExit;
            break;
        }
    } while (selection != CmdExit);
    return 0;
}