2013-05-17 2 views
0

Каков наилучший способ сравнения двух очень больших чисел, содержащихся в строковых литералах?Сравнение очень больших чисел, хранящихся в строке

Например, я хочу, чтобы сравнить следующее: "90000000000000000000000000000000000000000000000000000000000000000000000000001" "100000000000000000000000000000000000000000000000000000000000000000000000000009"

или

"0000000000111111111111111111111111111111111111111111111111111111111111111111" "0000001111111111111111111111111111111111111111111111111111111111111111111111"

В обоих случаях, очевидно, второй один Greate r, но как я могу найти это эффективно без повторения элементов?

+0

BigDecimal или BigInteger. – Shark

ответ

2

Вот еще одно решение:

public static int CompareNumbers(string x, string y) 
    { 
     if (x.Length > y.Length) y = y.PadLeft(x.Length, '0'); 
     else if (y.Length > x.Length) x = x.PadLeft(y.Length, '0'); 

     for (int i = 0; i < x.Length; i++) 
     { 
      if (x[i] < y[i]) return -1; 
      if (x[i] > y[i]) return 1; 
     } 
     return 0; 
    } 
8

Я бы взял простейший подход: используйте BigInteger для анализа обоих значений и сравните эти результаты. То, что не будет быть ужасно эффективным, но это было бы очень просто - и тогда вы могли бы проверить, быстро ли это .

В противном случае вы можете найти эффективную длину, игнорируя ведущие нули - и если один номер длиннее другого, то это все, что вам нужно знать. Или напишите метод, чтобы получить «эффективную» цифру строки, которая может быть короче, при необходимости возвращая 0, а затем сравнивая длину длинной строки вниз, пока одна строка не даст большее значение. Что-то вроде:

// Return the digit as a char to avoid bothering to convert digits to their 
// numeric values. 
private char GetEffectiveDigit(string text, int digitNumber) 
{ 
    int index = text.Length - digitNumber; 
    return index < 0 ? '0' : text[index]; 
} 

private int CompareNumbers(string x, string y) 
{ 
    for (int i = int.Max(x.Length, y.Length); i >= 0; i--) 
    { 
     char xc = GetEffectiveDigit(x, i); 
     char yc = GetEffectiveDigit(y, i); 
     int comparison = xc.CompareTo(yc); 
     if (comparison != 0) 
     { 
      return comparison; 
     } 
    } 
    return 0; 
} 

Обратите внимание, что это не проверить, что это правильный номер на всех, и это, безусловно, не пытается справиться с отрицательными числами.

+0

Если он уже использует строки, не будет ли работать простая «строка, которая короче, это меньшее число»? – Shark

+0

@Shark: Нет. Какое число больше, «2» или «000001»? –

+0

Согласны, завершающие нули нужно сначала усечь, моя ошибка для предполагаемого «поведения нормального числа» и пропуская эту часть :) – Shark

1

Если по сравнению вы имеете в виду булево чек, это будет работать:

public class Program 
{ 
    static void Main(string[] args) 
    { 
     string a = "0000000090000000000000000000000000000000000000000000000000000000000000000000000000001"; 

     string b = "000100000000000000000000000000000000000000000000000000000000000000000000000000009"; 

     Console.WriteLine(FirstIsBigger(a, b)); 

     Console.ReadLine(); 
    } 

    static bool FirstIsBigger(string first, string second) 
    { 
     first = first.TrimStart('0'); 
     second = second.TrimStart('0'); 
     if (first.Length > second.Length) 
     { 
      return true; 
     } 
     else if (second.Length == first.Length) 
     { 
      for (int i = 0; i < first.Length; i++) 
      { 
       double x = char.GetNumericValue(first[i]); 
       double y = char.GetNumericValue(second[i]); 
       if (x > y) return true; 
       else if (x == y) continue; 
       else return false; 
      } 
     } 

     return false; 
    } 
}