【问题标题】:How to Sort 2D Array in C#如何在 C# 中对二维数组进行排序
【发布时间】:2012-01-14 23:55:10
【问题描述】:

我已经阅读了很多关于对二维数组进行排序的帖子,但我仍然无法掌握它,所以我想知道是否有人可以给我一些建议...

我有一个列出字母和数量的数组(我正在对一段文本进行频率分析)。我已将此数据读入一个矩形数组,需要先按最高频率对其进行排序。到目前为止,这是我的代码:

    //create 2D array to contain ascii code and quantities
    int[,] letterFrequency = new int[26, 2];

    //fill in 2D array with ascaii code and quantities
    while (asciiNo <= 90)
     {

       while ((encryptedText.Length - 1) > counter)
      {
                if (asciiNo == (int)encryptedText[index])
               {
                      letterCount++;
               }
                counter++;
                index++;
      }

    letterFrequency[(storeCount), (0)] = (char)(storeCount+66);
    letterFrequency[(storeCount), (1)] = letterCount;
    storeCount++;
    counter=0;
    index=0;
    letterCount = 0;
    asciiNo++;
    }

【问题讨论】:

  • 您使用的是最新版本的 C# 吗?
  • 是的,我使用的是 VS 2010?
  • 你能举一个例子(也许更小)一个有序的二维数组是什么样子的吗?例如,您的意思是对每一行进行单独排序吗?
  • 看起来你得到了一些很好的反馈,所以我会退出。我问了 C# 问题以确保您可以利用 Linq Lambda 表达式。
  • 该数组将包含两列 - 一列用于字符,另一列用于该字符的频率。所以总的来说,它存储了 26 个不同的字母及其相关频率。

标签: c# arrays sorting


【解决方案1】:

您正在使用 2D 数组来表示 2 个单独的向量 - 符号和计数。相反,使用 2 个单独的数组。 Array.Sort 有一个重载,需要 2 个数组,并在 一个 数组上排序,但将更改应用于 both,实现您想要的。

这也将允许您对字符使用 char[] 而不是 int[]:

char[] symbols = ...
int[] counts = ...
...load the data...
Array.Sort(counts, symbols);
// all done!

此时 点,计数已排序,符号仍将按索引与它们相关的计数匹配。

【讨论】:

    【解决方案2】:

    您可以将字母计数对包装在一个结构中并使用 linq 方法来操作数据:

    struct LetterCount {
        public char Letter { get; set; }
        public int Count { get; set; }
    }
    

    按计数排序将如下所示:

    List<LetterCount> counts = new List<LetterCount>();
    //filling the counts
    counts = counts.OrderBy(lc => lc.Count).ToList();
    

    【讨论】:

    • 这与使用通用的KeyValuePair&lt;TKey, TValue&gt; 相同,只是您可以命名它。
    • 是的,但是命名提供了更多的可读性,现在制作一个结构可以为将来的新逻辑准备代码。
    • Imo 它只是使代码混乱,但就像我说的那样,这是我的观点。就像带有 typedef 的 C++ 一样。如果您有无数类型都引用相同的类型。然后它只会变得混乱。再说一次,我的意见。
    • 在这种情况下,这是一个品味问题,我同意。
    【解决方案3】:
    public static void Sort2DArray<T>(T[,] matrix)
    {
        var numb = new T[matrix.GetLength(0) * matrix.GetLength(1)];
    
        int i = 0;
        foreach (var n in matrix)
        {
            numb[i] = n;
            i++;
        }
        Array.Sort(numb);
    
        int k = 0;
        for (i = 0; i < matrix.GetLength(0); i++)
        {
            for (int j = 0; j < matrix.GetLength(1); j++)
            {
                matrix[i, j] = numb[k];
                k++;
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      替代方法:

      var counts = new Dictionary<char,int>();
      foreach(char c in text) {
          int count;
          counts.TryGetValue(c, out count);
          counts[c] = count + 1;
      }
      var sorted = counts.OrderByDescending(kvp => kvp.Value).ToArray();
      foreach(var pair in sorted) {
          Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
      }
      

      (未经测试)

      【讨论】:

      • 那么最好使用SortedDictionary&lt;TKey, TValue&gt;。但是您的其他解决方案是最好的:P。
      • @Aidiakapi 没有;按键排序;我们要对值进行排序
      • 对不起,我是想说SortedList&lt;TKey, TValue&gt; ;)
      【解决方案5】:

      在这种情况下,我会选择使用KeyValuePair&lt;TKey, TValue&gt;,而是使用类似这样的东西:

      //create 2D array to contain ascii code and quantities
      KeyValuePair<char, int>[] letterFrequency = new KeyValuePair<char, int>[26];
      
      //fill in 2D array with ascaii code and quantities
      while (asciiNo <= 90)
       {
      
         while ((encryptedText.Length - 1) > counter)
        {
                  if (asciiNo == (int)encryptedText[index])
                 {
                        letterCount++;
                 }
                  counter++;
                  index++;
        }
      
      letterFrequency[storeCount] = new KeyValuePair<char, int>((char)(storeCount+66), letterCount);
      storeCount++;
      counter=0;
      index=0;
      letterCount = 0;
      asciiNo++;
      }
      

      然后使用Array.Sort:

      Array.Sort(letterFrequency, (i1, i2) => i2.Value.CompareTo(i1.Value));
      

      【讨论】:

        【解决方案6】:

        这将对二维数组进行排序,布尔值指定是否按第二维排序,但默认按第一维排序。

        void SortDoubleDimension<T>(T[,] array, bool bySecond = false)
        {
            int length = array.GetLength(0);
            T[] dim1 = new T[length];
            T[] dim2 = new T[length];
            for (int i = 0; i < length; i++)
            {
                dim1[i] = array[i, 0];
                dim2[i] = array[i, 1];
            }
            if (bySecond) Array.Sort(dim2, dim1);
            else Array.Sort(dim1, dim2);
            for (int i = 0; i < length; i++)
            {
                array[i, 0] = dim1[i];
                array[i, 1] = dim2[i];
            }
        }
        

        【讨论】:

          【解决方案7】:

          为什么要存储角色?您可以从数组索引中推断出来,不需要存储它!改用一维数组。

          string encryptedText = "Test".ToUpper();
          int[] frequency = new int[26];
          foreach (char ch in encryptedText) {
              int charCode = ch - 'A';
              frequency[charCode]++;
          }
          var query = frequency
              .Select((count, index) => new { Letter = (char)(index + 'A'), Count = count })
              .Where(f => f.Count != 0)
              .OrderByDescending(f => f.Count)
              .ThenBy(f => f.Letter);
          foreach (var f in query) {
              Console.WriteLine("Frequency of {0} is {1}", f.Letter, f.Count);
          }
          

          【讨论】:

            猜你喜欢
            • 2021-11-07
            • 2019-05-17
            • 2015-01-30
            • 2012-12-15
            • 2018-05-14
            • 2019-06-08
            • 1970-01-01
            • 2014-08-10
            相关资源
            最近更新 更多