【问题标题】:Sorting strings in C++ using operator <在 C++ 中使用运算符 < 对字符串进行排序
【发布时间】:2011-07-27 05:38:35
【问题描述】:

以下数组是用 C++ 代码给出的:

char strings[105][105];

编写operator&lt; 以使用STL sort 函数对字符串进行排序的正确方法是什么,这可能吗?

【问题讨论】:

  • 这看起来有点像家庭作业问题。
  • 为什么要对字符数组使用 stl 排序?不使用 std::strings?
  • 什么字符串。我没有看到任何字符串(只是一个大的(2-D)字符数组)。
  • @Leonid:您是否描述并证明 std::string 对于您的使用来说太慢了?
  • 要使用 std::sort ,您需要编写自己的专用迭代器,将数组用作其中的成员并提供一些漂亮的复制解决方案。正如已经多次说过的那样,现在 std::string 将变得更容易编写和维护,并且可能更高效。

标签: c++ string sorting stl operators


【解决方案1】:

该代码实际上看起来很像 C 代码,而不是使用 std::string 的 C++。

没有办法编写可以与std::sort 一起使用的operator&lt;,因为除非你也写了,否则没有任何交换可以正常工作。

使用std::string 会使这变得非常简单,否则您将不得不编写自己的operator&lt;(查看C 函数strcmp)和swap 函数。

编辑:请注意,交换 std::strings 几乎肯定会比交换 char 数组中的大量内存更快。

【讨论】:

  • 目标是使用 STL 中的 sort 函数,这在 C 中不可用。由于迭代器的工作方式,这可能是不可能的。 std::string 提供了我想避免的不必要的开销。在 struct 中包装字符数组提供了一种使用 sort 函数重载 operator&lt; 的方法。想知道是否有更多方法可以使用sort 对字符数组进行排序。
  • @Leonid 您是否分析并表明std::string 与您想象的一样慢,并且是您应用程序的实际瓶颈?奇怪的是,更简单的程序(例如使用 string 之类的抽象)往往表现得更好,因为您能够专注于高级算法而不是低级细节。
  • 在我的情况下,std::string 必须进行动态内存分配,我想通过使用静态字符数组来避免这种情况。对于this question的目的,我一点也不好奇找到哪个更快。我很想知道是否可以在字符数组上使用sort
  • @Leonid:动态内存分配允许简单地交换指向字符串的内部指针,而不是来回复制所有这些字符。请记住,std::string 通常不会对短字符串使用动态分配(动态分配的成本超过其收益)。
【解决方案2】:

无法编写operator&lt; 来处理char 数组。

【讨论】:

    【解决方案3】:

    假设您确实确实需要按行对二维数组进行排序,即使给定一个有效的比较器函子,让std::sort() 为您执行此操作有点困难:它需要某种排序迭代器适配器。

    但是,您可以轻松使用其他就地排序算法,例如选择排序:

    #include <iostream>
    #include <algorithm>
    #include <string>
    
    template<int N>
    bool char_array_less(const char(&l)[N], const char(&r)[N])
    {
       return std::char_traits<char>::compare(&l[0], &r[0], N) < 0;
    // for a more general solution
    // return std::lexicographical_compare(&l[0], &l[0]+N, &r[0], &r[0]+N);
    }
    
    template<int N>
    void swap_char_arrays( char(*l)[N], char(*r)[N])
    {
        std::swap_ranges(&(*l)[0], &(*l)[0]+N, &(*r)[0]);
    }
    
    const int ROWS = 105;
    const int COLS = 105;
    int main()
    {
        char a[ROWS][COLS] = {"foo", "bar", "whatever" };
    
        for(char(*i)[COLS] = a; i != a+ROWS; ++i)
            swap_char_arrays(i,
                             std::min_element(i, a+ROWS, char_array_less<COLS>));
    
        for(int i=0; i<ROWS; ++i)
            std::cout << a[i] << '\n';
    }
    

    试运行:https://ideone.com/15hRB

    【讨论】:

      【解决方案4】:

      你不能为指针重载operator&lt;,但你不需要,因为 std::sort 可以接受任何比较函数(或函子)。

      另一个问题是排序算法不能交换数组,因为它们是不可赋值的。但是你可以将一个指针数组排序到二维数组中(保持原来的数组不变)。

      #include <algorithm>
      #include <cstring>
      #include <cstdio>
      
      bool compare_cstring(const char* a, const char* b)
      {
          return strcmp(a, b) < 0;
      }
      
      int main()
      {
          const int count = 5;
          char strings[count][10] = { "One", "Two", "Three", "Four", "Five" };
          char* sorted_view[count];
          for (int i = 0; i != count; ++i) {
              sorted_view[i] = strings[i];
          }
      
          std::sort(sorted_view, sorted_view + count, compare_cstring);
          for (int i = 0; i != count; ++i) {
              puts(sorted_view[i]);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-21
        • 1970-01-01
        • 1970-01-01
        • 2012-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多