【问题标题】:Sorting Structs and Arrays排序结构和数组
【发布时间】:2016-02-15 02:37:18
【问题描述】:

我的任务是读入一个包含游戏名称和分数的文件(文件看起来像)

5
John Doe 200
Chris Brown 340
Chris Brown 320
John Smith 300
John Doe 600

并按字母顺序(姓氏)打印出该人得分最高的姓名。所以输出看起来像:

Chris Brown 340
John Doe 600
John Smith 300

我想出了如何从最高到最低对分数进行排序和打印,但我不知道如何仅打印每个人的最高分数……任何帮助将不胜感激!

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

struct playerscore
{
    string first, last;
    int score;
};

bool score(playerscore a, playerscore b);
void selectionsort(playerscore *A, int n);

int main()
{
    string file;
    int n;
    cin >> file;
    ifstream fin(file.c_str());
    fin >> n;

    // read in the names and the scores in the form of struct playerscore
   playerscore *A = new playerscore[n];
    for(int i = 0; i < n; i++)
        fin >> A[i].first >> A[i].last >> A[i].score;

    // sort the data
    selectionsort(A, n);

    // print in sorted order
    for(int i = 0; i < n; i++)
        cout << A[i].score << " ";
    cout << endl;

    return 0;
}

bool before(playerscore a, playerscore b)
{
    return a.score > b.score;
}
void selectionsort(playerscore *A, int n)
{
    for(int length = n; length > 1; length--)
    {
        //find imax, index of largest
        int imax = 0, i;
        for(i = 1; i < length; i++)
            if(before(A[imax], A[i]))
                imax = i;
        // swap A[imax] and the last element
        playerscore temp = A[imax];
        A[imax] = A[length-1];
        A[length-1] = temp;
    }
}

【问题讨论】:

    标签: c++ arrays sorting struct selection-sort


    【解决方案1】:
    1. 按名称升序排序。 如果比较的名称相同,则得分较高的元素应位于数组的较早位置。
    2. 打印第一个元素和名称与前一个元素不同的元素。

    示例实现:

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    struct playerscore
    {
        string first, last;
        int score;
    };
    
    bool score(playerscore a, playerscore b);
    void selectionsort(playerscore *A, int n);
    
    int main()
    {
        string file;
        int n;
    #if 0
        cin >> file;
        ifstream fin(file.c_str());
    #else
    #define fin cin // to test with online compiler
    #endif
        fin >> n;
    
        // read in the names and the scores in the form of struct playerscore
       playerscore *A = new playerscore[n];
        for(int i = 0; i < n; i++)
            fin >> A[i].first >> A[i].last >> A[i].score;
    
        // sort the data
        selectionsort(A, n);
    
        // print in sorted order
        for(int i = 0; i < n; i++)
            if (i == 0 || A[i].first != A[i - 1].first || A[i].last != A[i - 1].last)
                cout << A[i].first << " " << A[i].last << " " << A[i].score << "\n";
        cout << endl;
    
        return 0;
    }
    
    bool before(playerscore a, playerscore b)
    {
        return a.first == b.first ? (a.last == b.last ? a.score > b.score : a.last < b.last) : a.first < b.first;
    }
    void selectionsort(playerscore *A, int n)
    {
        for(int length = n; length > 1; length--)
        {
            //find imax, index of largest
            int imax = 0, i;
            for(i = 1; i < length; i++)
                if(before(A[imax], A[i]))
                    imax = i;
            // swap A[imax] and the last element
            playerscore temp = A[imax];
            A[imax] = A[length-1];
            A[length-1] = temp;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您已经完成了困难的部分。

      假设((first, last), score)对已经排序,每个玩家的最高分是该玩家的第一条记录,所以访问数组时保持当前玩家的名字为curr_name

      1. 如果下一个名称与curr_name 相同,您可以放心地忽略此项。
      2. 如果没有,请打印此记录并更新curr_name

      代码就像自爆了:

      #include <iostream>
      #include <fstream>
      #include <algorithm>
      #include <vector>
      #include <string>
      #include <utility>
      using namespace std;
      bool mycmp (pair<pair<string, string>, int> a, pair<pair<string, string>, int> b) {
          return a.first < b.first || (a.first == b.first && a.second > b.second);
      }
      int main(int argc, char *argv[])
      {
          ifstream fin("data.txt");
          int n;
          fin>>n;
          vector<pair<pair<string, string>, int>> A(n);
          for(int i = 0; i < n; ++i){
              fin>>A[i].first.first>>A[i].first.second>>A[i].second;
          }
          sort(A.begin(), A.end(), mycmp);
          pair<string, string> cur_name;
          for(int i = 0; i < n; ++i){
              if(cur_name != A[i].first){
                  cout<<A[i].first.first<<" "<<A[i].first.second<<" "<<A[i].second<<endl;
                  cur_name = A[i].first;
              }
          }
          return 0;
      }
      

      【讨论】:

        【解决方案3】:

        如前所述,由于这是一项任务,我决定重写代码,它现在应该是这样的。

        1. 根据分数对数组进行排序

        2. 按字母顺序对数组进行排序

        3. 打印唯一条目

          #include <iostream>
          #include <fstream>
          using namespace std;
          
          struct playerscore
          {
              string first, last;
              int score;
          };
          
          bool score(playerscore a, playerscore b);
          void selectionsort(playerscore *A, int n);
          
          int main()
          {
              string file;
              int n;
              cin >> file;
              ifstream fin(file.c_str());
              fin >> n;
          
              // read in the names and the scores in the form of struct playerscore
              playerscore *A = new playerscore[n];
              for (int i = 0; i < n; i++)
                  fin >> A[i].first >> A[i].last >> A[i].score;
          
              // sort the data
              selectionsort(A, n);
              // sort alphabetically and print unique entries
              for (int i=0; i<n-1; i++)
              {
                  for (int j=i+1; j<n; j++)
                  {
                      if (A[j].last <= A[i].last && A[j].first < A[i].first)
                      {
                          playerscore tmp = A[i];
                          A[i] = A[j], A[j] = tmp;
                      }
               }
          
               playerscore max;
               int j = 0;
               for (int i=0; j+i<n; i++)
               {
                   max.score = -1;
          
                   while (j+i<n && A[j+i].last == A[i].last && A[j+i].first == A[i].first)
                   {
                       if (A[j+i].score >= A[i].score)
                           max = A[j+i];
                       j++;
                   }
                   j--;
          
                   if (max.score >= 0)
                       cout << max.last << " " << max.first << " " << max.score << endl;
               }
               cout << endl;
          
               return 0;
           }
          
           bool before(playerscore a, playerscore b)
           {
                return a.score > b.score;
           }
          
           void selectionsort(playerscore *A, int n)
           {
               for(int length = n; length > 1; length--)
               {
                   //find imax, index of largest
                   int imax = 0, i;
                   for(i = 1; i < length; i++)
                       if(before(A[imax], A[i]))
                           imax = i;
                   // swap A[imax] and the last element
                   playerscore temp = A[imax];
                   A[imax] = A[length-1];
                   A[length-1] = temp;
               }
           }
          

        【讨论】:

        • 由于问题以“我的任务”开头,那么我的假设是这是家庭作业,他们应该学习如何排序并且不允许使用内置的排序功能。
        • 好吧,那么您还应该建议他们使用std::vector 而不是原始数组:)
        • 由于您抱怨这是一项任务,我制作了另一个代码以解决您的投诉和 mid_code 的请求。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-24
        • 1970-01-01
        • 2015-09-01
        相关资源
        最近更新 更多