使用模式匹配交换列表中的元素对

问题描述 投票:0回答:1

我需要使用模式匹配技术,以递归方式交换列表中的每对元素。所以,[1, 2, 3, 4, 5]将返回[2, 1, 4, 3, 5]

我发现了两件事:

  • List.length:返回长度。这有助于处理偶数/奇数列表。
  • List.nth:在列表中的指定位置返回一个值。
  • drop.(list, i):在第一个i元素被删除后返回值。

使用这三件事,我可以找出一些递归方法,但我不理解模式匹配方面。下面是一些没有任何模式匹配的伪代码。

function(list):
  var a = first on list
  var b = second on list

  // odd case
  if(b = null | "")
  {
    list = drop.(list, 1) @ a
  }

  // even case
  else if(b = "" & a = "")
  {
    list = list
  }

  // recursive case
  else
  {
    list = function(drop.(list, 2) @ b @ a)
  }

实际上,这可以开始循环遍历列表,交换对,将它们放置(连接)在列表的末尾,并递归地重复它,直到它遍历所有对。

list recursion pattern-matching sml
1个回答
0
投票

函数List.lengthList.nthList.drop似乎可以解决你的任务,但这对你使用模式匹配的目标起反作用。通过模式匹配,您使用的列表是代数数据类型

datatype 'a list = [] | :: of 'a * 'a list

它为空列表生成值构造函数[],为现有列表前面的元素(可以是空的或以相同的方式创建)生成中缀::运算符,还有用于识别你的列表类型的模式构造函数重新处理。

示例:一个获取整数列表并对它们求和的函数:

fun sum [] = 0
  | sum (x::xs) = x + sum xs

示例:一个函数,它获取2元组的列表并返回类似的2元组列表,但每个2元组中的元素交换:

fun swap [] = []
  | swap ((x,y)::xys) = (y,x)::swap xys

示例:一个函数,它采用偶数大小的整数列表并返回一个列表,它们已成对添加到一起:

fun addpairs (x::y::xys) = x + y :: addpairs xys
  | addpairs [_x] = raise Fail "Odd-sized list"
  | addpairs [] = []

特别是,模式可以嵌套((x,y)::xys ~~“具有至少一个元素的列表,其中第一个元素是2元组,其第一部分命名为x,第二部分命名为y”和x::y::xys ~~“列表其中至少有两个元素,第一个元素名为x,第二个元素名为y“),顺序(从上到下匹配)可能很重要,如果模式重叠(它们不在上面的任何一个中)。

© www.soinside.com 2019 - 2024. All rights reserved.