Было на одном из собеседований. Сделать сложение очень больших чисел, которые не влезают в long и int64, заходят как строка, при этом должны быть следующие ограничения:
-Не отрицательное число
-В аргументе только цифры
-Нет ведущих нолей
-Не пустая строка
-Целое
Нужно создать класс BigNumber и 3 его метода
Тест класса мог бы выглядеть так
1 2 3 4 5 6 7 8 9 10 |
BigNumber a = new BigNumber("175872"); BigNumber b = new BigNumber("1234567890123456789012345678901234567890"); //BigNumber a = new BigNumber("19"); //BigNumber b = new BigNumber("2"); Console.WriteLine(a.ToString()); Console.WriteLine(b.ToString()); var r = a + b; Console.WriteLine(r); |
Далее мои решения
Есть 2 решения, но на собеседовании – самое простое и элегантное не засчитали. Не дали воспользоваться библиотекой System.Numerics;
Итак, боевое решение. Класс BigNumber, идея в том. чтобы складывать числа из строк столбиком, как это нас учили в школе – за это отвечает метод Sum.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace JobInterview2 { class BigNumber { public string Value { get; set; } public BigNumber(string str) { if (str[0] == '-') throw new ArgumentException("Отрицательное число"); if (!IsDigitsOnly(str)) throw new ArgumentException("В аргументе не только цифры"); if (str[0] == '0') throw new ArgumentException("Есть ведущие нули"); if (str == "") throw new ArgumentException("Пустая строка"); if (str.Contains(",") || str.Contains(".")) throw new ArgumentException("Не целое"); Value = str; } public BigNumber(string a, string b) { int[] A = new int[a.Length]; int[] B = new int[b.Length]; for (int i = 0; i < a.Length; i++) { A[i] = (int)Char.GetNumericValue(a[i]); } for (int i = 0; i < b.Length; i++) { B[i] = (int)Char.GetNumericValue(b[i]); } Value = Sum(A, B); } public static string Sum(int[] a, int[] b) { var rList = new List<int>(); var rest = 0; Array.Reverse(a); Array.Reverse(b); for (int i = 0; i < Math.Max(a.Length, b.Length); i++) { var n1 = i < a.Length ? a[i] : 0; var n2 = i < b.Length ? b[i] : 0; var sum = n1 + n2 + rest; rList.Add(sum % 10); rest = sum / 10; } if (rest > 0) rList.Add(rest); // to array and reverse int[] resultArray = rList.ToArray(); Array.Reverse(resultArray); StringBuilder sb = new StringBuilder(); for (int i = 0; i < resultArray.Length; i++) { sb.Append(resultArray[i]); } return sb.ToString(); } public override string ToString() { return Value; } public static BigNumber operator +(BigNumber a, BigNumber b) { return new BigNumber(a.Value, b.Value); } // bool IsDigitsOnly(string str) { foreach (char c in str) { if (c < '0' || c > '9') return false; } return true; } } } |
Тест класса
1 2 3 4 5 6 7 8 9 10 |
BigNumber a = new BigNumber("175872"); BigNumber b = new BigNumber("1234567890123456789012345678901234567890"); //BigNumber a = new BigNumber("19"); //BigNumber b = new BigNumber("2"); Console.WriteLine(a.ToString()); Console.WriteLine(b.ToString()); var r = a + b; Console.WriteLine(r); |
Способ №2 Элегантный
добавить
1 |
using System.Numerics; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
public class BigNumber2 { // !!! в hackerrank не смог подключить using System.Numerics; // В студии скомпилировалось и работает. BigInteger Value { get; set; } = 0; public BigNumber2(string str) { if (str[0] == '-') throw new ArgumentException("Отрицательное число"); if ((str[0] == '0') || (str[1] == '1')) throw new ArgumentException("Есть ведущие нули"); if (str == "") throw new ArgumentException("Пустая строка"); if (str.Contains(",") || str.Contains(".")) throw new ArgumentException("Не целое"); if (!IsDigitsOnly(str)) throw new ArgumentException("В аргументе не только цифры"); Value = BigInteger.Parse(str); } public BigNumber2() { } public override string ToString() { return Value.ToString(); } public static BigNumber2 operator +(BigNumber2 a, BigNumber2 b) { return new BigNumber2() { Value = a.Value + b.Value }; } // bool IsDigitsOnly(string str) { foreach (char c in str) { if (c < '0' || c > '9') return false; } return true; } } |