繁体   English   中英

如何对存储在字符串数组中的大数进行排序?

[英]How to sort large numbers stored in a string array?

我需要对以字符串形式存储在字符串数组中的大数进行排序,但我的算法和 .net 构建的数组排序方法不起作用。

我试图将数字转换为longulong但抛出溢出异常。

这是我尝试过的代码:

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

注意:为了使用OrderByThenBy功能,我们必须在我们的程序中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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM