【问题标题】:Trouble in sorting vector strings using std::sort() using custom compare function使用自定义比较函数使用 std::sort() 对向量字符串进行排序时遇到问题
【发布时间】:2020-10-29 18:14:00
【问题描述】:

我正在尝试根据规则对字符串进行排序。 c++ 代码在大多数情况下都能正常工作,但在某些情况下会报错:

  terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid

我以前见过这个错误,当我们尝试将字符串初始化为空指针或 0(在内部转换为空指针)时会发生此错误。我已经检查了在排序过程中是否发生了错误,并且仅在我使用自定义函数进行比较时发生。再说一次,我不知道为什么它只在某些情况下发生。

代码是:

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

using std::vector;
using std::string;

bool greater(string a, string b) {
  int i = 0;
  a = a + a[0];
  b = b + b[0];
  while(i<a.size() && i<b.size()) {
    if(a[i] != b[i]) {
      if(a[i] - '0' > b[i] - '0')
      return true;
      else return false;
    }
    i++;
  }
  
}

string largest_number(vector<string> a) {
  std::sort(a.begin(), a.end(), greater);
  std::stringstream ret;
  for (size_t i = 0; i < a.size(); i++) {
    ret << a[i];
  }
  string result;
  ret >> result;
  return result;
}

int main() {
  int n;
  std::cin >> n;
  vector<string> a(n);
  for (size_t i = 0; i < a.size(); i++) {
    std::cin >> a[i];
  }
  std::cout << largest_number(a);
  return 0;
}

它给出错误的一种情况是:

100  
2 8 2 3 6 4 1 1 10 6 3 3 6 1 3 8 4 6 1 10 8 4 10 4 1 3 2 3 2 6 1 5 2 9 8 5 10 8 7 9 6 4 2 6 3 8 8 9 8 2 9 10 3 10 7 5 7 1 7 5 1 4 7 6 1 10 5 4 8 4 2 7 8 1 1 7 4 1 1 9 8 6 5 9 9 3 7 6 3 10 8 10 7 2 5 1 1 9 9 5

解决方案: 感谢帮助。发生错误是因为比较函数一旦退出循环就没有返回任何内容。这是有效的更新功能。

bool greater(string a, string b) {
  int i = 0;
  a = a + a[0];
  b = b + b[0];
  while(i<a.size() && i<b.size()) {
      if(a[i] > b[i])
        return true;
    i++;
  }
  return false; 
}

【问题讨论】:

  • 比较“app”和“apple”时,比较函数返回什么? ;) 我不知道这是否以及如何产生错误,但在我看来,缺少一个 return 语句。
  • 不是bug,但a[i] - '0' &gt; b[i] - '0'等价于a[i] &gt; b[i]if (x &gt; y) return true; else return false;等价于return x &gt; y;
  • a = a;b = b; 的意义何在?
  • 读取、排序和输出std::strings而不是ints是否有原因或特定要求?

标签: c++ string sorting


【解决方案1】:

我在代码中看到的唯一问题(实际上我在在线编译器中尝试过,它给了我这个警告)是如果两个字符串相等,你不会从greater 返回任何东西:

bool greater(string a, string b) {
  int i = 0;
  a = a;
  b = b;
  while(i<a.size() && i<b.size()) {
    if(a[i] != b[i]) {
      if(a[i] - '0' > b[i] - '0')
      return true;
      else return false;
    }
    i++;
  }
  // <---- what about here?
}

尝试插入一个 return 语句。 (当然,如果两件事相等,那么任何一个都不大于另一个,所以特别是你想要的 return false。)在没有 return 语句的情况下退出函数的末尾是 未定义的行为 em>(int main() 或任何返回 void 的函数除外),所以当这种情况发生时,您可能会看到任何东西,包括您遇到的崩溃类型。

[编辑:正如 gst 所说,如果一个字符串是另一个字符串的前缀,你也会到达这一点,例如"1""10"。所以你需要更多的代码来测试哪个是哪个,而不仅仅是return false。但是你可以看到这一行是否可以修复崩溃:它在逻辑上是错误的,但至少不是未定义的行为。]

【讨论】:

  • 谢谢,成功了。我不敢相信我错过了它。该错误让我认为它应该与字符串初始化有关。
猜你喜欢
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多