Предположим, мне дано целых чисел фиксированной ширины (т.е. они помещаются в регистр ширины ), , так что их сумма a 1 + a 2 + ⋯ + a n = S также помещается в регистр ширины ш .
Мне кажется, что мы всегда можем переставить числа в , чтобы каждая префиксная сумма также помещалась в регистр ширины .
По сути, мотивация состоит в том, чтобы вычислять сумму на машинах с фиксированной шириной, не беспокоясь о целочисленных переполнениях на любом промежуточном этапе.
Существует ли быстрый (предпочтительно линейное время) алгоритм для поиска такой перестановки (при условии, что заданы как входной массив)? (или скажем, если такой перестановки не существует).
algorithms
arrays
integers
numerical-analysis
Арьябхата
источник
источник
-2^(n-1)
до2^(n-1)-1
. Конечно, требуется два дополнения и четко определенное поведение переполнения, но в языке, подобном C #, это должно работать.Ответы:
Стратегия0
Следующий алгоритм линейного времени принимает стратегию зависания около , выбирая положительные или отрицательные числа на основе знака частичной суммы. Он предварительно обрабатывает список номеров; он вычисляет перестановку входных данных на лету при выполнении сложения.
Алгоритм
Корректность
Корректность может быть установлена с помощью прямого индуктивного аргумента длины списка чисел.
Прежде всего, докажите, что если все положительные (или все отрицательные) и их сумма не вызывает переполнения, то и суммы префиксов не делайте. Это просто.a1, ... ,N
Во-вторых, доказать, что находится в пределах границ, является инвариантом цикла алгоритма. Понятно, что это верно при входе в цикл, так как S u m = 0 . Теперь, если S u m > 0 , добавление отрицательного числа, которое находится в пределах границ к S u m , не приводит к тому, что S u m выходит за пределы. Аналогично, когда S u m ≤ 0, добавление к сумме положительного числа, которое находится в пределах границ, не приводит к выходу S u m за пределы. Таким образом, выходя из цикла,Sты м Su m = 0 Sты м > 0 Sты м Sты м Sи м ≤ 0 Sты м находитсяпределах границ.Sты м
Теперь можно применить первый результат, и их вместе достаточно, чтобы доказать, что сумма никогда не выходит за пределы.
источник