排序字符串指针的矢量

时间:2018-03-07 00:02:33

标签: c++ sorting vector

如果已经在某个地方提出这个问题,我很抱歉,但我找不到我正在寻找的答案。

我有一个std :: string指针的向量,我想按字母顺序排序,我无法弄清楚如何做到这一点。我正在使用std :: sort。

我写了一个quick program来测试我想要做的事情(因为在实际实现中,我的代码是在子进程中运行的,所以它很难调试):

#include <string>
#include <algorithm>
#include <vector>
#include <string.h>

bool cmpStrPtrs(std::string *a, std::string *b) {
  std::string a1 = *a;
  std::string a2 = *b;
  if(a1 == a2) return 0;
  return a1 > a2 ? 1 : -1;
}

int main(int argc, char *argv[]) {
  std::vector<std::string *> vec;
  std::string *str1 = new std::string("AAAAA");
  std::string *str2 = new std::string("aaaaa");
  std::string *str3 = new std::string("xxxxx");
  std::string *str4 = new std::string("bfuen");
  std::string *str5 = new std::string("xylophone");
  vec.push_back(str1);
  vec.push_back(str2);
  vec.push_back(str3);
  vec.push_back(str4);
  vec.push_back(str5);

  std::sort(vec.begin(), vec.end(), cmpStrPtrs);
  for(std::string *str : vec) {
    printf("%s\n", str->c_str());
  }
  return 0;
}

当我运行它时,我得到了这个输出:

$ ./strsort
xylophone
bfuen
xxxxx
aaaaa
AAAAA

这似乎没有任何字母顺序,所以我可以假设我使用sort()错误或我的比较器函数有问题。我也尝试过它没有比较器功能,我认为只是根据它们的内存位置从最小到最大排序它们,这实际上并没有改变任何东西。我也尝试过使用

bool cmpStrPtrs(std::string *a, std::string *b) {
  return a->compare(*b);
}

但它给了我相同的结果。

如果它是相关的,我正在使用c ++ 17标准编译g ++。

4 个答案:

答案 0 :(得分:4)

np.meshgrid会返回std::string::compare,而非int。根据{{​​3}},返回值为

  

负值if * this出现在参数指定的字符序列之前,按字典顺序

     如果两个字符序列都比较等价

,则

为零      

正值如果*出现在参数指定的字符序列之后,按字典顺序排列强文

返回的值转换为bool,对于所有非零值,其值为bool。这意味着您的函数会为每个不相同的字符串对返回true

C ++标准实际上为字符串定义了true,因此您可以将函数更改为

operator<

但这仍然会在您的代码中留下一个大问题。你绝对不需要指针。事实上,你现在正在泄露记忆,因为你忽视了bool cmpStrPtrs(std::string *a, std::string *b) { return *a < *b; } 他们。适合这项工作的工具是delete。这具有额外的好处,即没有额外的间接级别,std::vector<std::string>可以在没有辅助函数的情况下隐式调用std::sort,从而导致以下解决方案。

operator<

答案 1 :(得分:2)

你可以用lambda:

来做
std::sort(vec.begin(), vec.end(), [](std::string * a, std::string * b) {
    return *a < *b;    
  });

答案 2 :(得分:2)

你的比较函数是meant to simulate the less-than operator - 这意味着如果a在b之前,它应该返回true。如果不等于b。

,则当前实现返回true

你有:

if(a1 == a2) return 0;
return a1 > a2 ? 1 : -1;

应该是:

if(a1 == a2) return false;
return a1 > a2 ? false : true;

或只是:

return a1 < a2;

答案 3 :(得分:2)

std::sort期待Strict Weak Ordering.它不会给出平等的废话;它只关心前后。

如果右手边在左手边之前,比较功能应该返回true。不幸的是

bool cmpStrPtrs(std::string *a, std::string *b) {
  std::string a1 = *a;
  std::string a2 = *b;
  if(a1 == a2) return 0;
  return a1 > a2 ? 1 : -1;
}
对于任何非0的值,

bool都为真。这意味着大于和小于都为真。这使逻辑排序几乎不可能,因为大于和小于之前。

改进剪切1:根据词典(按字母顺序)排序返回bool。 String已经实现了一个小于运算符,它完全符合您的要求。我们来使用它。

bool cmpStrPtrs(std::string *a, std::string *b) {
  std::string a1 = *a;
  std::string a2 = *b;
  return a1 < a2;
}

改进剪辑2:std::string a1 = *a;创建一个全新的字符串,它是原始字符串的副本。由于您有一个指向原始的指针,您可以取消引用指针并使用原始指针。无需复制。

bool cmpStrPtrs(std::string *a, std::string *b) {
  return *a < *b;
}