Я предполагаю, что мы храним цифры в списках от наименее значимой цифры до самой значимой цифры.Другими словами, число 143 будет представлено в виде списка следующим образом:
[3] -> [4] -> [1]
^ ^
| |
front back
Хранение старших значащих цифр в заголовке делает добавление менее эффективным, поскольку для определения длины списков необходимы дополнительные обходы.
В этом коде нужно разрешить несколько проблем:
while (xInter.hasNext()) { // check if there is any numbers
проверяет, есть ли у x
числа, что работает, только если списки совпадаютдлина или x
длиннее.Вместо этого продолжайте итерацию, пока либо xIt
, либо yIt
имеет число, потому что предстоит еще много работы. Вместо попытки добавить новый элемент результата, как только вы поймете, чтопора переносить с result.add(rem); // add remainder to result list.
, я рекомендую отложить добавление остатка до тех пор, пока он действительно не понадобится на следующей итерации.Кажется, проще строго придерживаться интуиции арифметического подхода, когда он выполняется вручную.
Кроме того, llist1.set(pos++, xInter.next() + 1); // add 1 to next int.
сложно, потому что вы сделали шаг вперед, не имея возможности вернуться назад.Логика становится запутанной, и на следующем шаге необходимо знать слишком много состояний.На любом шаге удалите только один элемент из каждого итератора и добавьте только один узел к результату.
Следуя последнему пункту, я бы также рекомендовал удалить большинство переменных иветвления.pos
и carryBool
не нужны и усложняют понимание кода.
В своем переписывании я продолжаю добавлять, пока оба итератора не опустеют.Любые пустые итераторы объединяются в 0, и мы можем продолжить нормальное вычисление.Для каждой операции сложения мы делаем две вещи: 1) вычисляем элемент для текущей цифры результата и 2) передаем остаток до следующей цифры, если необходимо.
Вот полный пример:
import java.util.*;
import static java.lang.System.out;
class Main {
public static LinkedList<Integer> add(
LinkedList<Integer> a, LinkedList<Integer> b
) {
LinkedList<Integer> result = new LinkedList<>();
Iterator<Integer> xIt = a.iterator();
Iterator<Integer> yIt = b.iterator();
int rem = 0;
while (xIt.hasNext() || yIt.hasNext()) {
int x = xIt.hasNext() ? xIt.next() : 0;
int y = yIt.hasNext() ? yIt.next() : 0;
result.add((x + y + rem) % 10);
rem = x + y + rem >= 10 ? 1 : 0;
}
if (rem > 0) {
result.add(rem);
}
return result;
}
public static void main(String[] args) {
int[][] tests = {
{143, 675},
{77666, 666},
{985, 824},
{9999, 1},
{1, 9999},
{667, 677},
};
for (int[] test : tests) {
LinkedList<Integer> a = itol(test[0]);
LinkedList<Integer> b = itol(test[1]);
LinkedList<Integer> sum = add(a, b);
int expected = test[0] + test[1];
out.println("a : " + a + "\n" + "b : " + b);
out.println("sum : " + sum);
out.println(test[0] + " + " + test[1] + " = " + ltoi(sum));
out.println("Correct? " + (ltoi(sum) == expected) + "\n");
}
}
private static LinkedList<Integer> itol(int i) {
LinkedList<Integer> res = new LinkedList<>();
for (; i > 0; i /= 10) res.offer(i % 10);
return res;
}
private static int ltoi(LinkedList<Integer> ll) {
String digits = "";
for (int i : ll) digits = i + digits;
return Integer.parseInt(digits);
}
}
Вывод:
a : [3, 4, 1]
b : [5, 7, 6]
sum : [8, 1, 8]
143 + 675 = 818
Correct? true
a : [6, 6, 6, 7, 7]
b : [6, 6, 6]
sum : [2, 3, 3, 8, 7]
77666 + 666 = 78332
Correct? true
a : [5, 8, 9]
b : [4, 2, 8]
sum : [9, 0, 8, 1]
985 + 824 = 1809
Correct? true
a : [9, 9, 9, 9]
b : [1]
sum : [0, 0, 0, 0, 1]
9999 + 1 = 10000
Correct? true
a : [1]
b : [9, 9, 9, 9]
sum : [0, 0, 0, 0, 1]
1 + 9999 = 10000
Correct? true
a : [7, 6, 6]
b : [7, 7, 6]
sum : [4, 4, 3, 1]
667 + 677 = 1344
Correct? true