[英]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.