我正在做作业,问题是我们得到2个相同大小的int列表,然后将数字加在一起.示例如下.
I am working on homework and the problem is where we get 2 int lists of the same size, and then add the numbers together. Example as follows.
vecadd [1;2;3] [4;5;6];; would return [5;7;9]我对此并不陌生,我需要使代码保持简单,以便我可以从中学习.到目前为止,我已经知道了. (不起作用)
I am new to this and I need to keep my code pretty simple so I can learn from it. I have this so far. (Not working)
let rec vecadd L K = if L <> [] then vecadd ((L.Head+K.Head)::L) K else [];;我实质上只是想用添加的数字替换第一个列表(L).另外,我还尝试使用匹配用例对它进行编码.
I essentially want to just replace the first list (L) with the added numbers. Also I have tried to code it a different way using the match cases.
let rec vecadd L K = match L with |[]->[] |h::[]-> L |h::t -> vecadd ((h+K.Head)::[]) K他们俩都没有工作,我将不胜感激.
Neither of them are working and I would appreciate any help I can get.
推荐答案第一个,您关于修改第一个列表而不返回新列表的想法被误导了.变异(即就地修改数据)是当今发生错误的第一大原因(以前是goto,但很长一段时间以来一直被禁止使用).使每个操作产生一个新的基准而不是修改现有的基准要安全得多.在某些情况下,它的性能可能更高,这与直觉相反(请参阅下文).
First, your idea about modifying the first list instead of returning a new one is misguided. Mutation (i.e. modifying data in place) is the number one reason for bugs today (used to be goto, but that's been banned for a long time now). Making every operation produce a new datum rather than modify existing ones is much, much safer. And in some cases it may be even more performant, quite counterintuitively (see below).
第二,您尝试执行此操作的方式没有执行您认为正在执行的操作.双冒号并不意味着修改第一项".它的意思是在前面附加一个项目".例如:
Second, the way you're trying to do it, you're not doing what you think you're doing. The double-colon doesn't mean "modify the first item". It means "attach an item in front". For example:
let a = [1; 2; 3] let b = 4 :: a // b = [4; 1; 2; 3] let c = 5 :: b // c = [5; 4; 1; 2; 3]这就是列表的实际构建方式:从一个空列表开始,然后在其前面添加项目.您正在使用的[1; 2; 3]语法只是一个语法糖.即[1; 2; 3] === 1::2::3::[].
That's how lists are actually built: you start with a empty list and prepend items to it. The [1; 2; 3] syntax you're using is just a syntactic sugar for that. That is, [1; 2; 3] === 1::2::3::[].
您问我如何修改列表?答案是,你不知道! F#列表是不可变的数据结构.创建列表后,您将无法再对其进行修改.
So how do I modify a list, you ask? The answer is, you don't! F# lists are immutable data structures. Once you've created a list, you can't modify it any longer.
这种不变性允许进行有趣的优化.再看一下我上面发布的示例,其中有三个列表,分别是a,b和c.您认为这三个列表占用多少存储单元?第一个列表包含3个项目,第二个-4和第三个-5,因此占用的内存总量必须为12,对吗?错误的!这三个列表占用的内存总量实际上只有5个单元.这是因为列表b不是长度为4的内存块,而只是数字4与指向列表a的指针配对.数字4被称为列表的头",而指针被称为其尾".同样,列表c由一个数字5(其头部")和一个指向列表b的指针(即其尾巴")组成.
This immutability allows for an interesting optimization. Take another look at the example I posted above, the one with three lists a, b, and c. How many cells of memory do you think these three lists occupy? The first list has 3 items, second - 4, and third - 5, so the total amount of memory taken must be 12, right? Wrong! The total amount of memory taken up by these three lists is actual just 5 cells. This is because list b is not a block of memory of length 4, but rather just the number 4 paired with a pointer to the list a. The number 4 is called "head" of the list, and the pointer is called its "tail". Similarly, the list c consists of one number 5 (its "head") and a pointer to list b, which is its "tail".
如果列表不是一成不变的,则无法像这样组织它们:如果有人修改了我的尾巴怎么办?每次都必须复制列表(Google防御性副本").
If lists were not immutable, one couldn't organize them like this: what if somebody modifies my tail? Lists would have to be copied every time (google "defensive copy").
因此处理列表的唯一方法是返回一个新列表.您要尝试执行的操作可以这样描述:如果输入列表为空,则结果为空列表;如果输入列表为空,则结果为空.否则,结果是尾数之和与头数之和相加.您可以用F#几乎逐字记录下来:
So the only way to do with lists is to return a new one. What you're trying to do can be described something like this: if the input lists are empty, the result is an empty list; otherwise, the result is the sum of tails prepended with the sum of heads. You can write this down in F# almost verbatim:
let rec add a b = match a, b with | [], [] -> [] // sum of two empty list is an empty list | a::atail, b::btail -> (a + b) :: (add atail btail) // sum of non-empty lists is sum of their tails prepended with sum of their heads请注意,该程序是不完整:它没有指定当一个输入为空而另一输入为空时结果应该是什么.编译器将对此发出警告.我会将解决方案留给读者练习.
Note that this program is incomplete: it doesn't specify what the result should be when one input is empty and the other is not. The compiler will generate a warning about this. I'll leave the solution as an exercise for the reader.
更多推荐
将2个Int列表加在一起F#
发布评论