将2个Int列表加在一起F# [英] Adding 2 Int Lists Together F#

查看:99
本文介绍了将2个Int列表加在一起F#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做作业,问题是我们得到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.

这种不变性允许进行有趣的优化.再看一下我上面发布的示例,其中有三个列表,分别是abc.您认为这三个列表占用多少存储单元?第一个列表包含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#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆