【问题标题】:Sort two dimensional array with different lengths对不同长度的二维数组进行排序
【发布时间】:2020-04-05 14:02:47
【问题描述】:

各位程序员们好,

我正在尝试对二维数组进行排序。这个数组表示一个对象的集合,这些对象的属性在下面的列表中具有一个值。因此不必保存原始列表。

起始情况是:

var list = new List<string>
        {
            "10-158-6",
            "11-158-6",
            "90-158-6",
            "20-15438-6",
            "10-158-6",
            "10-158-6-3434",
            "10-1528-6"
        };

结果应该是

var list = new List<string>
            {
                "10-158-6",
                "10-158-6",
                "10-1528-6"
                "10-158-6-3434",
                "11-158-6",
                "20-15438-6",
                "90-158-6",
            };

它应该首先在第一部分订购 -> 然后是第二部分 -> 等等。

我认为对这些字符串进行排序几乎是不可能的,所以我将其转换为二维列表。我找到了对多维列表进行排序的不同解决方案,但没有一个可以用于这个问题。我也不知道从哪里开始......

有人知道如何编写一个没有不必要的大 O 的排序算法吗?

提前致谢!

杰伦

【问题讨论】:

  • 字典序有什么区别?您是否尝试直接对字符串进行排序?
  • Jep,这是我尝试的第一件事。除数字外的其他字符始终排在数字之前。所以 10-1528 排在 10-158 之前- 排序时,应该是其他的
  • 为什么写这个问题不能对多维列表进行排序呢?你能展示你的尝试吗?
  • 使用版本可以吗? var versions = list.Select(x =&gt; new Version(x.Replace('-','.'))).ToList(); versions.Sort(); 这样做会成功吗,或者从破折号切换到点是不行的。

标签: c# .net algorithm sorting


【解决方案1】:

您可以使用Sort 方法;让我们用任意长个数字来实现一个一般情况:

代码:

  var list = new List<string>() {
    "10-158-6",
    "11-158-6",
    "90-158-6",
    "20-15438-6",
    "10-158-6",
    "10-158-6-3434",
    "10-1528-6",
    "123456789012345678901234567890"
  };

  list.Sort((left, right) => {
    var x = left.Split('-');
    var y = right.Split('-');

    // Compare numbers:
    for (int i = 0; i < Math.Min(x.Length, y.Length); ++i) {
      // Longer number is always bigger: "123" > "99"
      int r = x[i].Length.CompareTo(y[i].Length);

      // If numbers are of the same length, compare lexicographically: "459" < "460"
      if (r == 0)
        r = string.CompareOrdinal(x[i], y[i]);

      if (r != 0)
        return r;
    }

    // finally, the more items the bigger: "123-456-789" >  "123-456"
    return x.Length.CompareTo(y.Length);
  });

  // Let's have a look at the list after the sorting
  Console.Write(string.Join(Environment.NewLine, list));

结果:

10-158-6
10-158-6
10-158-6-3434  // <- please, note that since 158 < 1528
10-1528-6      // <- "10-158-6-3434" is before "10-1528-6" 
11-158-6
20-15438-6
90-158-6
123456789012345678901234567890

【讨论】:

  • 不,这是@Dmitry 说得对!非常感谢!
【解决方案2】:

那些看起来像版本号。如果从 Dash 到 Dot 的变化不是很大,您可以简单地使用 C# Version

var list = new List<string>
{
    "10-158-6",
    "11-158-6",
    "90-158-6",
    "20-15438-6",
    "10-158-6",
    "10-158-6-3434",
    "10-1528-6"
};

var versions = list.Select(x => new Version(x.Replace('-','.'))).ToList();
versions.Sort();

LiveDemo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 2013-08-17
    • 2015-09-17
    • 2014-04-23
    • 2022-10-06
    相关资源
    最近更新 更多