排序相对路径

时间:2017-04-17 00:20:57

标签: c++ qt

我的问题非常简单,但我无法想到一个优雅的解决方案 在我的应用程序中,从用户输入中收集了一堆相对路径(它们实际上并不存在于文件系统中)。
举个例子:

  • somefile.ext
  • Z / file.ext
  • A / B / file2.ext
  • A / B / Z / file.ext
  • file1.ext
  • A / B / file.ext

这些收集在一个QList中(其中包含指向具有路径作为QString成员的类实例的指针),但容器对我来说并不重要。
理想的结果是将列表以有序的形式存在,文件上的目录(正如我们从大多数文件管理器中使用的那样),基本上就像你将树真实的文件系统一样。

  • A / B / Z / file.ext
  • A / B / file.ext
  • A / B / file2.ext
  • Z / file.ext
  • file.ext
  • somefile.ext

显然,基于正常字符串的排序不起作用,但是对这样的列表进行排序的最优雅/最简单的方法是什么?

2 个答案:

答案 0 :(得分:1)

我会为内置排序编写自定义comparator函数。这样的事情可能有用:

auto cmp = [](const string& lhs, const string& rhs) {
    int len = min(lhs.size(), rhs.size());
    for (int i = 0; i < len; i++) {
        if (lhs[i] = rhs[i]) continue;

        // check if there is a '/' starting from position i in both paths
        // put directory first (if only one is a directory)
        // or return lhs[i] < rhs[i]
};

完成此代码应该相当容易, 然后

sort(begin(paths), end(paths), cmp);

请注意,我正在使用c ++ 11

答案 1 :(得分:1)

退后一步,花一点时间用简单的英语总结您想要的分类标准:

  1. 目录排在第一位,文件排在第二位。

  2. 目录按字母顺序排序,文件按字母顺序排序。

  3. 现在,一旦你的逻辑被简化为这种简单直接的定义,只需将这个逻辑直接转换为C ++代码。

    首先,将每个字符串转换为单个值0或1,表示字符串是否具有路径名组件。

    排序。然后,如果两个字符串的值相等,则像往常一样对字符串本身进行排序。简单:

    std::sort(container.begin(),
              container.end(),
              []
              (const QString &a,
               const QString &b)
              {
                 // Compute whether a or b is a subdirectory, representing
                 // each as:
                 //
                 // 0: directory
                 // 1: file
    
                 int a_hier=a.contains('/') ? 0:1;
                 int b_hier=b.contains('/') ? 0:1;
    
                 if (a_hier != b_hier)
                      return a_hier < b_hier;
    
                 return a < b;
             });
    

    这是您基本的初步方法。如果有必要,可以调整这个以对目录的路径名进行略微不同的排序(因为路径名中的/组件参与相对排序顺序,您可能想要也可能不想要,这在您的问题中不清楚)。