对字符串向量进行排序,C++具有要放在末尾的特殊值

Sorting a string vector in C++ with a special value to place at the end

本文关键字:向量 字符串 排序 C++      更新时间:2023-10-16

我正在尝试创建一个函数,该函数使用以下条件对字符串向量进行排序:

所有字符串 = "NULL" 必须转到向量的末尾并从那里减少。其余字符串必须保持其顺序。

例如给出:

{"Potato", "NULL", "NULL", "Charmander" , "Spaghetti", "NULL"}

输出应为:

{"Potato","Charmander","Spaghetti","NULL","NULL","NULL"}

我尝试过这个,但它没有完全起作用:

bool comp(string i, string j){
if(i=="NULL"){return i>j;}
if (j=="NULL") {return i<j;}

提前致谢

您可以执行以下两项操作之一:

  1. 首先处理"NULL",然后以我们通常的幼稚方式对其他字符串进行排序
  2. 使用您定义的更复杂的顺序对所有字符串进行排序

首先处理"空">

标准库有一个"分区"算法,它将所有匹配某个条件的元素移动到字符串的末尾。

std::vector<string> vec {
"Potato", "NULL", "NULL", "Charmander" , "Spaghetti", "NULL"
};
auto is_not_null = [](const std::string& s) { return s != "NULL"; } 
auto nulls_start = std::partition(vec.begin(), vec.end(), is_not_null);
auto non_nulls_end = nulls_start;
std::sort(vec.begin(), non_nulls_end);

使用复杂比较进行排序

std::vector<string> vec {
"Potato", "NULL", "NULL", "Charmander" , "Spaghetti", "NULL"
};
auto comparator = 
[](const std::string& lhs, const std::string& rhs)
{
return rhs == "NULL" or lhs <= rhs; 
};
std::sort(vec.begin(), vec.end(), comparator);

请注意此处的比较与comp()函数之间的差异。比较器回答问题"我得到的第一个字符串应该在第二个字符串之前吗?"——而你的comp()函数只是没有给出符合你要求的答案。

您可以使用分区算法:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, const char * argv[]) {
vector<string> vec {
"Potato", "NULL", "NULL", "Charmander" , "Spaghetti", "NULL"
};
partition(begin(vec), end(vec), // Partition the values
[](const string& s) { return s != "NULL"; });

copy(begin(vec), end(vec), ostream_iterator<string>{cout, " "});
cout << endl;
return 0;
}
// RESULT: Potato Spaghetti Charmander NULL NULL NULL 

注意:如果您需要保持相对顺序,请改用stable_partition。

您可以编写自己的函数版本,将一些字符串放在末尾,即:

namespace myAlgo {
template<typename ForwardIter, class T >
ForwardIter moveToEnd(ForwardIter first, ForwardIter last, const T& value) {
if (first == last) {
return first;
}
ForwardIter fasterFirst = first;
//Shift strings that do not match value to the left in stable manner
while (++fasterFirst != last) {
if (*fasterFirst != value) {
*++first = *fasterFirst;
}
}
ForwardIter pivot = first;
//Fill rest with value
while (first != last) {
*++first = value;
}
return pivot;
}
}

然后只是:

myAlgo::moveToEnd(vec.begin(), vec.end(), "NULL");