如何在C#中对2D数组进行排序

我已经阅读了很多关于排序2D数组的post,但我仍然无法掌握它,所以我想知道是否有人可以给我一些建议……

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

//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  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++; } 

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

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

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

此时,计数已经被排序,并且符号仍然将索引与它们相关的计数匹配。

您可以在字母结构中包含字母数对,并使用linq方法来处理数据:

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

按计数排序将如下所示:

 List counts = new List(); //filling the counts counts = counts.OrderBy(lc => lc.Count).ToList(); 
 public static void Sort2DArray(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++; } } } 

替代方法:

 var counts = new Dictionary(); 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); } 

(另)

在这种情况下,我会选择使用KeyValuePair ,而是使用以下内容:

 //create 2D array to contain ascii code and quantities KeyValuePair[] letterFrequency = new KeyValuePair[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)(storeCount+66), letterCount); storeCount++; counter=0; index=0; letterCount = 0; asciiNo++; } 

然后使用Array.Sort

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

这将对二维数组进行排序,bool指定它是否在第二维上排序,但默认情况下它在第一维上排序。

 void SortDoubleDimension(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]; } } 

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

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