使用 C#/Linq 累加序列的子序列
我试图根据以下要求找到一种更好的方法来处理数字序列: sequence[i]
的值是其自身值加上sequence[0]
到sequence[i-1]
的累加之和。
例如: 如果序列是一个列表,
List<double> list = new List<double> { 10.0, 20.0, 30.0, 40.0 };
则输出结果应该是
list[0] = 10.0
list[1] = 20.0 + 10.0
list[2] = 30.0 + 10.0 + 20.0
list[3] = 40.0 + 10.0 + 20.0 + 30.0
我知道使用多次迭代的强力方式,但我想知道一定有更好的解决方案(也许使用 LINQ)。
I'm trying to find a better way of processing a sequence of numbers based on the following requirement:
the value of sequence[i]
is the sum of its own value plus the accumulation from sequence[0]
to sequence[i-1]
.
For example:
if the sequence is a list
List<double> list = new List<double> { 10.0, 20.0, 30.0, 40.0 };
the output result should be
list[0] = 10.0
list[1] = 20.0 + 10.0
list[2] = 30.0 + 10.0 + 20.0
list[3] = 40.0 + 10.0 + 20.0 + 30.0
I know the brute force way which uses multiple iterations, but I wonder there must be some better solution (maybe with LINQ).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
假设您有权访问 LINQ:
Assuming you have access to LINQ:
我的版本是对我在注释中添加的内容的修改,并返回 IEnumerable 而不是 List,但 ToList() 会解决这个问题。
应该还是蛮有效率的。谁不喜欢使用
yield return
? ;-)这样做的主要优点是它只对输入数组执行一次循环。如果您实际上没有使用返回的所有内容(即您只查看前三个),那么它不会计算其余的内容。在较长的列表等中可能有用。Chris Doggett 的答案之类的内容也会如此,但并非所有此处使用 linq 的内容。
My version which is a modification of what I put in comments and returns an IEnumerable rather than a List but a ToList() will sort that out.
Should be pretty efficient. And who doesn't like using
yield return
? ;-)Main advantage of this is that it only does one loop over the input array. and if you don't actually use all of the stuff returned (ie you only look at the first three) then it won't calculate the rest. Potentially useful in longer lists, etc. The same will be said of things like Chris Doggett's answer but not all those here using linq.
使用相对未知的 Select 重载可以让您查看索引:
Use the relatively-unknown overload of Select that lets you see the index:
非 LINQ 版本,只是为了有所不同:
A non-LINQ version, just to be different:
这是另一种类似于其中一篇文章的方法,但这个方法是独立的:
如果我们切换到 int64,并使用 10,000,000 作为上限,并读取最终的累积结果,则代码在大约 450 毫秒内执行最终输出为 Corei5:
50000005000000
顺便说一句,对于 1,000,000 的执行上限约为 40 毫秒,因此将大小增加 10 会使时间增加 10。
Here is another way similar to one of the posts, but this one is self-contained:
If we switch to int64, and use 10,000,000 as the upper bound, and read the final accumulated result, the code executes in about 450 milli-seconds on a Corei5 with a final output of:
50000005000000
Incidentally, for an upper bound of 1,000,000 the execution is about 40 milli-seconds, so increasing the size by 10 increased the time by 10.
返回操作序列的中间结果:
我基于 APL 扫描运算符(类似于 Aggregate 本质上是 APL 归约运算符)构建了一个通用(有很多变体)扩展方法,该方法 然后可以像这样使用:
I built a general purpose (with lots of variations) extension method based on the APL scan operator (analogous to how
Aggregate
is essentially the APL reduce operator) that returns the intermediate results of the sequence of operations:Which can then be used like: