2017-02-21 26 views
0

У меня есть массив строк, содержащих 50 + -значных чисел. Мне нужно преобразовать их в целые числа реального мира и упорядочить их. Это работает, когда у меня есть номера с разным размером количеством цифр, но в этом случае, когда все числа, имеющие одинаковое число размера цифр он не будет работать:Сортировка 50 + -разрядных чисел в массиве

string[] unsorted = {"324141241413213123123123132131451231231321363435243321413153412465745238454211425241244252423234234", "324141241413213123123123132131451231231321363435243321413153412465745238454211425241244252423234235" 
     ,"324141241413213123123123132131451231231321363435243321413153412465745238454211425241244252423234200","324141241413213123123123132131451231231321363435243321413153412465745238454211425241244252423234100","324141241413213123123123132131451231231321363435243321413153412465745238454211425241244252423234731"}; 
var sorted = unsorted.OrderBy(s => double.Parse(s)); 

Что самое лучшее решение?

+1

Какой тест не проходит? – epascarello

+0

Какие цифры, которые можно разобрать BigInteger? – harold

+0

Есть ли у вас несколько примеров чисел? – mmenschig

ответ

3

Если вы работаете с целых вы можете разбор их BigInteger (как double и decumal являются слишком коротким для таких чисел, например Decimal.MaxValue == 79228162514264337593543950335, который является только цифры):

using System.Numerics; 

... 

string[] data = ... 

var ordered = data 
    .OrderBy(item => BigInteger.Parse(item)) 
    .ToArray(); // if you want materialization to array 

Если вы работаете с неотрицательными целыми числами, вы можете сортировать их по длине, а затем лексикографически (нет необходимости в конвертации):

string[] data = ... 

var ordered = data 
    .OrderBy(item => item.Length) 
    .ThenBy(item => item) 
    .ToArray(); // if you want materialization to array 

Тот же подход для любых целых (см комментарий Jason P Sallinger в) также возможно, но не так элегантна:

var ordered = data 
    .Where(item => item.StartsWith("-")) 
    .OrderByDescending(item => item.Length) 
    .ThenByDescending(item => item) 
    .Concat(data 
     .Where(item => !item.StartsWith("-")) 
     .OrderBy(item => item.Length) 
     .ThenBy(item => item)) 
    .ToArray(); 

Наконец, пожалуйста, посмотрите на Natural Sort Order in C#

+1

Если у вас есть отрицательные целые числа, вы можете разбить набор, сделать это за два прохода, а затем объединить два массива –

+0

@Jason P Sallinger: Спасибо, я вижу! Но реализация идеи будет сложной. –

+0

true. По крайней мере, это был бы шаг в направлении отказоустойчивости. –

-1

Try это; (Простое решение в linq) оно работает как для положительных, так и для отрицательных целых чисел.

string[] array = { "2525213", "2525211", "-2525214" }; 

     var result = array.OrderBy(x => BigInteger.Parse(x)); 

     foreach (var item in result) 
     { 
      Console.WriteLine(item); 
     } 
    } 
+0

Ну, это в основном скопировано и вставлено из ответа @Dmitry, и это не 50 + -значные числа. – gagro

0

Предполагая, что они не обрезаны (без ведущих нулей) целые положительные числа без запятых затем:

unsorted.OrderBy(s => s.Length).ThenBy(s => s) 

будет работать, потому что необрезные целое число, которое больше, чем другой неухоженной числа будет больше, чем это.

Для негативов тоже:

unsorted.Order(s => s[0] != '-').ThenBy(s => s.Length).ThenBy(s => s) 

Поскольку булевы сортировать ложные, прежде чем правда, и вы хотите строки, начинающиеся с - прийти перед теми, которые не делают.

Если что-то более сложным, чем я бы использовать IEqualityComparer<string> с Compare методом, который:

  1. Если только один был - тогда он приходит первым.
  2. Иначе, если оба они имеют -, то обрезайте -, назовите себя результатом и затем отрицайте этот результат.
  3. Обрежьте любые тысячи групп (, на английском языке).
  4. Получите длину в десятичном разделителе (. на английском языке) в каждой или полной длине, если их нет. Если другое, самое короткое - самое маленькое.
  5. Порядковый номер сравнения.
+0

Проблема: я использовал double вместо BigInteger, потому что double не может обрабатывать эти большие числа. Изменение параметра Double to BigInteger устраняет проблему. – gagro

 Смежные вопросы

  • Нет связанных вопросов^_^