对于序列中的每个元素,将序列的其余部分加起来

时间:2017-09-09 04:14:46

标签: algorithm

标题有点误导:我想要的是有点复杂,但我不知道如何在标题中描述它。

我有两个序列(矢量,数组,列表)pq个数字。除了第一个元素之外,我将 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。)

1 个答案:

答案 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]

由于您一次最多只能修改列表中的一个值,因此您只需手动更新总和以反映更改,而不是再次对列表中的所有元素求和,这使得循环体在恒定时间内运行。