【问题标题】:Vector of strings works correctly before sorting, but afterwards it can't do anything字符串向量在排序之前可以正常工作,但之后它不能做任何事情
【发布时间】:2021-04-10 14:47:43
【问题描述】:

我正在解决一个问题,该问题需要我在某个点对字符串向量进行排序。它给我带来了很多问题,所以我决定提取有问题的部分,但我无法弄清楚似乎是什么问题。

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

using namespace std;

bool myComp(string a, string b){
    return a<b;
}

int main(){
    
    vector<string> students(50000);

    int i = 0;
    while(true){
        string input;
        getline(cin, students[i]);
        if(!students[i].empty()){
            i++;
        }
        else{
            break;
        }
    }
    cout << students[2] << endl << students[1] << endl;
    sort(students.begin(), students.end());
    cout << students[2] << endl << students[1];

    return 0;
}

起初我认为输入是错误的(问题特别要求读取直到空行),但结果证明程序在排序之前可以正常工作。如果有人能帮我解决这个问题,我将不胜感激。我已经敲了一个多小时。

【问题讨论】:

  • 您的输入是什么,您的预期输出与实际输出是什么?另外,myComp() 的作用是什么?看起来你从未使用过它。
  • 为什么你认为它不起作用?请注意,在对向量中的第一个50000 - i 字符串进行排序后,将为空。
  • 我猜这里的问题是你用 50000 个空字符串创建了一个 vector,实际上只填充了 10-20 个值。因此,当您排序时,前 48980 个值将是空字符串。您是否有理由不只是从空向量开始并使用push_back()
  • 您可以edit 您的问题包含预期的输出。如果你知道你不使用myComp,那么也将其删除,这样你的代码就会变成minimal reproducible example。作为这里的新用户,也请带上tour并阅读How to Ask
  • 这是学习使用调试器的好时机,这样您就可以在排序前后检查向量的内容。

标签: c++ string sorting vector


【解决方案1】:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

int main()
{
   std::vector<std::string> students;
   students.reserve(50000);  // want to avoid `students` reallocation for first
                             // 50'000 entries but size is still zero (`0`)
   std::string line;
   // read until end-of-input or empty line
   while(std::getline(std::cin, line) && !line.empty())
      students.push_back(line);  // no reallocation for first 50'000 entries!
   if(students.size() < 3)
   {
      std::cerr << "Need at least three students for example\n";
      return EXIT_FAILURE;
   }
   std::cout << students[2] << '\n' << students[1] << '\n';
   std::partial_sort(    // Only pick out three "smallest" strings for example
      students.begin(),  // no need to sort more than necessary with 50'000 :-)
      std::next(students.begin(), 3),
      students.end());
   std::cout << students[2] << '\n' << students[1] << std::endl;
   return EXIT_SUCCESS;
}

【讨论】:

    【解决方案2】:

    您的代码的明显问题是您有一个包含 50000 个字符串的向量。然后,您尝试对包含 50000 个字符串的向量进行排序。很明显,您确实希望向量的大小等于输入的字符串数。最简单的方法是在输入字符串时增大向量。为此使用push_back 方法。

    这里有一些代码

    vector<string> students; // initial size of vector is zero
    
    int i = 0;
    while(true){
        string input;
        getline(cin, input); // read into the input variable
        if (input.empty())   // break if input is empty
            break;
        students.push_back(input); // add the input to the vector
    }
    

    现在矢量大小正确,您应该会发现对其进行排序没有问题

    cout << students[2] << endl << students[1] << endl;
    sort(students.begin(), students.end());
    cout << students[2] << endl << students[1];
    

    【讨论】:

      【解决方案3】:

      问题是在std::sort 的调用中使用了不正确的参数。

      sort(students.begin(), students.end());
      

      向量学生包含50000个元素

      vector<string> students(50000);
      

      看来你的意思

      #include <iterator>
      
      //...
      
      sort(students.begin(), std::next( students.begin(), i ));
      

      sort(students.begin(), std::next( students.begin(), i ), myComp );
      

      myComp 的定义至少应该像这样

      bool myComp( const string &a, const string &b){
          return a<b;
      }
      

      【讨论】:

        【解决方案4】:

        您已经编写了一个比较器函数myComp(),但您还没有使用它。我建议将它用作sort() 的第三个参数,看看情况是否会好转。即;

        #include<iostream>
        #include<vector>
        #include<algorithm>
        #include<string>
        
        using namespace std;
        
        bool myComp(string a, string b){
            return a<b;
        }
        
        int main(){
            
            vector<string> students(50000);
        
            int i = 0;
            while(true){
                string input;
                getline(cin, students[i]);
                if(!students[i].empty()){
                    i++;
                }
                else{
                    break;
                }
            }
            cout << students[2] << endl << students[1] << endl;
            sort(students.begin(), students.end(), myComp);
            cout << students[2] << endl << students[1];
        
            return 0;
        }
        

        【讨论】:

        • 比较器 myComp 的作用与默认比较器完全相同。
        • 我们不知道 OP 期望的输出是什么。但我可以自信地说,这将提供与他们现在所拥有的完全相同的输出。
        • myComp的不同之处在于,通过值而不是const引用获取参数的额外成本。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-02
        • 1970-01-01
        • 2022-07-06
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        相关资源
        最近更新 更多