matrix - 将 2 个 Int 列表一起添加 F#

标签 matrix vector f#

我正在做作业,问题是我们得到 2 个相同大小的 int 列表,然后将这些数字相加。示例如下。

    vecadd [1;2;3] [4;5;6];; would return [5;7;9]

我是新手,我需要保持我的代码非常简单,以便我可以从中学习。到目前为止我有这个。 (不工作)
    let rec vecadd L K =
         if L <> [] then vecadd ((L.Head+K.Head)::L) K else [];;

我基本上只想用添加的数字替换第一个列表(L)。我还尝试使用匹配案例以不同的方式对其进行编码。
    let rec vecadd L K =
       match L with
         |[]->[]
         |h::[]-> L
         |h::t -> vecadd ((h+K.Head)::[]) K

他们都没有工作,我会很感激我能得到的任何帮助。

最佳答案

第一 ,您关于修改第一个列表而不是返回新列表的想法是错误的。突变(即修改数据)是当今出现错误的第一大原因(曾经是 goto,但现在已经被禁止了很长时间)。让每个操作都产生一个新的数据而不是修改现有的数据要安全得多。在某些情况下,它的性能可能会更高,这完全违反直觉(见下文)。
第二 ,你试图这样做的方式,你没有做你认为你正在做的事情。双冒号并不意味着“修改第一项”。它的意思是“在前面附加一个项目”。例如:

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::[] .
那么,你问我如何修改列表?答案是,你没有! F# 列表是不可变的数据结构。创建列表后,您将无法对其进行修改。
这种不变性允许进行有趣的优化。再看一下我上面发布的示例,它包含三个列表 a , b , 和 c .你认为这三个列表占用了多少内存单元?第一个列表有 3 个项目,第二个 - 4,第三个 - 5,所以占用的内存总量必须是 12,对吧?错误的!这三个列表占用的内存总量实际上只有 5 个单元格。这是因为列表 b不是长度为 4 的内存块,而只是数字 4与指向列表 a 的指针配对.号码4被称为列表的“头”,而指针被称为它的“尾”。同样,列表 c由一个数字组成5 (它的“头”)和指向列表 b 的指针,这是它的“尾部”。
如果列表不是不可变的,就不能像这样组织它们:如果有人修改了我的尾部怎么办?每次都必须复制列表(谷歌“防御性副本”)。
因此,处理列表的唯一方法是返回一个新列表。您尝试做的事情可以这样描述:如果输入列表为空,则结果为空列表;否则,结果是尾部总和加上正面总和。你可以用 F# 几乎一字不差地写下来:
let rec add a b =
    match a, b with
    | [], [] -> []   // sum of two empty lists 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
请注意,这个程序是不完整的:它没有指定当一个输入为空而另一个不为空时的结果应该是什么。编译器将对此产生警告。我将把解决方案留给读者作为练习。

关于matrix - 将 2 个 Int 列表一起添加 F#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41728398/

相关文章:

algorithm - 动态规划获取最大钻石

c - 使用动态分配的 C 矩阵乘法(程序崩溃)

c++ - 计算复数的乘法

syntax - 为什么我的F#代码中的空格会导致错误?

haskell - 在 F# 中实现 Haskell-MaybeMonad - 我们如何才能变得懒惰?

list - 为什么不能压缩两个不同长度的列表?

C++:提高现有 C 程序的性能

c# - 几乎正确的矩阵分解代码在否定情况下失败

c++ - vector 元素是否保证有序?

c++ - 统一迭代 std::vector<T> 和 std::vector<unique_ptr<T>>