[英]How to sort large numbers stored in a string array?
我需要對以字符串形式存儲在字符串數組中的大數進行排序,但我的算法和 .net 構建的數組排序方法不起作用。
我試圖將數字轉換為long
或ulong
但拋出溢出異常。
這是我嘗試過的代碼:
string[] unsorted = { "1","2","100","12303479849857341718340192371",
"3084193741082937","3084193741082938","111","200" };
for (int index = 0; index < unsorted.Length - 1; index++)
{
for (int count = 0; count < unsorted.Length - index - 1; count++)
{
if (string.Compare(unsorted[count], unsorted[count + 1]) == 1)
{
string temp = unsorted[count];
unsorted[count] = unsorted[count + 1];
unsorted[count + 1] = temp;
}
}
}
還使用了以下方法:
Array.Sort(unsorted);
數組應該正確排序。
您可以使用BigInteger.Parse
並在其上使用 Linq 的OrderBy
。 例如:
var sorted = unsorted.Select(BigInteger.Parse).OrderBy(e => e).ToArray();
如果您需要將其作為字符串返回:
var sorted = unsorted.Select(BigInteger.Parse).OrderBy(e => e).Select(e => e.ToString()).ToArray();
這首先將其轉換為BigInteger
有一個缺點,但可能無論如何你都需要它。 然而,與 IO 和數據庫訪問相比,這並沒有增加典型的應用程序性能。
嘗試以下:
string[] unsorted = { "1","2","100","12303479849857341718340192371",
"3084193741082937","3084193741082938","111","200" };
var groups = unsorted.OrderBy(x => x.Length).GroupBy(x => x.Length).ToArray();
List<string> results = new List<string>();
foreach (var group in groups)
{
string[] numbers = group.ToArray();
for(int i = 0; i < numbers.Count() - 1; i++)
{
for(int j = i + 1; j < numbers.Count(); j++)
{
if(numbers[i].CompareTo(numbers[j]) == 1)
{
string temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
}
}
results.AddRange(numbers);
}
你沒有一個數字數組,你有一個字符串數組。 所以它們是按字母數字排序的。
一種選擇是使用BigInteger
類將它們存儲為數字:
BigInteger[] unsorted = {
BigInteger.Parse("1"),
BigInteger.Parse("2"),
BigInteger.Parse("100"),
BigInteger.Parse("12303479849857341718340192371"),
BigInteger.Parse("3084193741082937"),
BigInteger.Parse("3084193741082938"),
BigInteger.Parse("111"),
BigInteger.Parse("200")
};
如果失敗,如果您想將它們保留為字符串,那么您可以用零左填充它們以使長度一致,以便字母數字排序可以工作:
string[] unsorted = {
"00000000000000000000000000001",
"00000000000000000000000000002",
"00000000000000000000000000100",
"12303479849857341718340192371",
"00000000000003084193741082937",
"00000000000003084193741082938",
"00000000000000000000000000111",
"00000000000000000000000000200"
};
如果您選擇前者,只需將if
塊中的類型也更改為BigInteger
。
如果我們想對存儲為字符串的非常大的數字進行排序,而不將 string 更改為BigInteger
,最好先根據它的長度對其進行排序,然后根據字典順序對其進行排序。 我們可以看到下面的示例代碼:
using System;
using System.Linq;
public class Test
{
public static void Main()
{
string[] unsorted = { "1","2", "100","12303479849857341718340192371",
"3084193741082937","3084193741082938","111","200" };
unsorted.OrderBy(s => s.Length).ThenBy(s => s);
Console.WriteLine("Sorted numbers are:");
foreach (var x in unsorted) {
Console.WriteLine(x);
}
}
}
注意:為了使用OrderBy
和ThenBy
功能,我們必須在我們的程序中using System.Linq
。
對於一個優雅的解決方案,您可以使用linq ,您將擁有具有良好性能的最少代碼。
var result = unsorted.Select(e => decimal.Parse(e)).OrderBy(e => e);
該系統必須如下所示。 您可以將數組中的值傳輸到數組列表,然后您可以通過 for 循環將它們全部解析為BigInteger 。 最后你可以對列表進行排序:
BigInteger[] unsorted;
var bigIntegers = new List<System.Numerics.BigInteger>();
for (int index = 0; index < unsorted.Length - 1; index++)
{
bigIntegers[i] = BigInteger.Parse[i]
}
bigIntegers.sort();
另一種變體:
static void Main(string[] args)
{
List<string> unsorted = new List<string>(new string[] {"1","2","100","12303479849857341718340192371",
"3084193741082938","3084193741082937", "111","200" });
unsorted.Sort((x, y) => (x.Length != y.Length ? x.Length.CompareTo(y.Length) : x.CompareTo(y)));
foreach(string number in unsorted)
{
Console.WriteLine(number);
}
Console.Write("Press Enter to quit");
Console.ReadLine();
}
以@jdweng 的回答為基礎,但通過消除“手動”冒泡排序進一步減少它:
string[] result =
unsorted.OrderBy(x => x.Length)
.GroupBy(x => x.Length)
.SelectMany(x => x.OrderBy(y => y))
.ToArray();
或同一主題的其他一些變體:
using System.Collections.Generic;
using System.Linq;
...
string[] result =
unsorted.OrderBy(x => x, Comparer<string>.Create((a, b) => a.Length == b.Length ? a.CompareTo(b) : a.Length - b.Length))
.GroupBy(x => x.Length)
.SelectMany(x => x)
.ToArray();
(正如@jdweng 答案下面的@fester 評論所指出的,如果某些字符串是帶有前導零的數字,例如“ 00123 ”,則此方法將無法可靠地工作。)
package com.solution.sorting;
import java.util.Arrays;
import java.util.Comparator;
public class ArraySort {
public static void main(String[] args) {
String[] number = { "3", "2", "4", "10", "11", "6", "5", "8", "9", "7" };
String[] unsorted = { "8", "1", "2", "100", "12303479849857341718340192371", "3084193741082937",
"3084193741082938", "111", "200" };
Arrays.sort(number);
for (String s : number)
System.out.println("number="+s);
//
Arrays.sort(unsorted, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return compareStrings(o1,o2);//Integer.valueOf(o1).compareTo(Integer.valueOf(o2));
}
});
for (String s : unsorted)
System.out.println("number1=" + s);
}
private static int compareStrings(String s1, String s2) {
//
if (s1.length() < s2.length()) {
return -1;
} else if (s1.length() > s2.length()) {
return 1;
}
for (int i = 0; i < s1.length(); i++) {
if ((int) s1.charAt(i) < (int) s2.charAt(i))
return -1;
if ((int) s1.charAt(i) > (int) s2.charAt(i))
return 1;
}
return 0;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.