标题有点误导:我想要的是有点复杂,但我不知道如何在标题中描述它。
我有两个序列(矢量,数组,列表)p
和q
个数字。除了第一个元素之外,我将 p 中的所有数字相加,然后执行测试。如果失败,我将 p 的第一个元素替换为 q 的第一个元素,并从第二个元素重新开始:总结 p的所有元素除了第二个(包括从 q 复制的新元素)。如果测试第二次失败,则将 p 中的第二个元素替换为 q 中的第二个元素,并使用第三个元素再次执行。测试总是在一些元素上成功。伪代码:
i = 0
if test(sum_except p i) then exit loop
else p[i] := q[i], and run again with i+1
这意味着如果我有1000个元素,我总计999个,然后下一次通过我总结998个加上一个新元素,依此类推。随着这个过程的继续,我也在从 q 而不是从原来的 p 中总结出越来越多的元素,但我以前也会对它们中的大部分进行求和。 。所以在每一步中,我总结了一堆我已经加在一起的数字。这似乎效率低下,但我还没有想出一个更明智的方式来写这个。
如果重要,测试的作用是检查 p 中值的总和,除了 i 的元素,加上 q的值 i 的大于或等于1(或小于或等于1 - 有两个变体)。即:
(sum_except p i) + q[i] > 1
这一切都发生在内部循环中,序列长度可能在500到5000之间,尽管可能有更大的数字。
(我的代码实际上是在OCaml,fwiw。)
答案 0 :(得分:3)
计算开始时所有数字的总和(以下称为sum
)。 sum_except p i
等同于sum - p[i]
。
当您更新列表中的项目时,也要更新总和,这样您就不必每次都通过遍历p
中的每个元素来重新计算它。
// Remove old value
sum := sum - p[i]
p[i] := q[i]
// Add new value
sum := sum + p[i]
由于您一次最多只能修改列表中的一个值,因此您只需手动更新总和以反映更改,而不是再次对列表中的所有元素求和,这使得循环体在恒定时间内运行。