簡體   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