【问题标题】:Sorting a string vector in C++ with a special value to place at the end在 C++ 中使用特殊值对字符串向量进行排序以放在末尾
【发布时间】:2018-10-28 03:23:38
【问题描述】:

我正在尝试创建一个使用此标准对字符串向量进行排序的函数:

所有 strings= "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;}

提前致谢

【问题讨论】:

标签: c++ string sorting vector


【解决方案1】:

你可以做以下两件事之一:

  1. 首先处理“NULL”,然后按照我们通常的天真方式对其他字符串进行排序
  2. 使用您定义的更复杂的顺序对所有字符串进行排序

首先处理“NULL”

标准库有一个"partition" algorithm,它将所有符合某个条件的元素移动到字符串的末尾。

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() 函数只是没有给出符合您要求的答案。

【讨论】:

    【解决方案2】:

    可以使用分区算法:

    #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。

    【讨论】:

      【解决方案3】:

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

      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");
      

      【讨论】:

        猜你喜欢
        • 2022-07-05
        • 1970-01-01
        • 2021-03-18
        • 1970-01-01
        • 2021-07-26
        • 2016-09-13
        • 2020-07-29
        • 1970-01-01
        • 2011-02-23
        相关资源
        最近更新 更多