scala-Problem06-10

本文介绍Scala中对列表进行的一系列操作,包括判断列表是否为回文、扁平化嵌套列表、消除连续重复元素、打包连续重复元素以及列表的游程长度编码。通过多种实现方式展示了Scala强大的列表处理能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

* 声明*
该系列文章来自:http://aperiodic.net/phil/scala/s-99/
大部分内容和原文相同,加入了部分自己的代码。
如有侵权,请及时联系本人。本人将立即删除相关内容。

P06 (*) Find out whether a list is a palindrome.

要求

判断一个list是不是回文

Example:

scala> isPalindrome(List(1, 2, 3, 2, 1))
res0: Boolean = true

方案

  • (1) 反转list之后和自身反转之前的元素顺序一致
def isPalindrome1[T](list: List[T]): Boolean =
    list == list.reverse

P07 (**) Flatten a nested list structure.

要求

将一个内嵌N重list的list所有元素提取至一个新的list,新的list不能嵌套list结构

Example:

scala> flatten(List(List(1, 1), 2, List(3, List(5, 8))))
res0: List[Any] = List(1, 1, 2, 3, 5, 8)

方案

  • (1) 递归+List.flatMap
def flatten(list: List[Any]): List[Any] = list.flatMap {
    case ls: List[_] => flatten(ls)
    case e           => List(e)
}

P08 (**) Eliminate consecutive duplicates of list elements.

要求

If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.

Example:

scala> compress(List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e))
res0: List[Symbol] = List('a, 'b, 'c, 'a, 'd, 'e)

方案

  • (1) List.dropWhile + recursive
def compressRecursive[T](list: List[T]): List[T] = list match {
    case Nil       => Nil
    case h :: tail => h :: compressRecursive(tail.dropWhile(e => e == h))
}
  • (2) List.dropWhile + tail-recursive
def compressTailRecursive[T](list: List[T]): List[T] = {
    def compressR(ret: List[T], ls: List[T]): List[T] = ls match {
        case Nil       => ret
        case h :: tail => compressR(ret ::: List(h), ls.dropWhile(_ == h))
    }

    return compressR(Nil, list)
}
  • (3) List.dropWhile + tail-recursive
def compressTailRecursive2[T](list: List[T]): List[T] = {
    def compressR(ret: List[T], ls: List[T]): List[T] = ls match {
        case Nil       => ret.reverse
        case h :: tail => compressR(h :: ret, ls.dropWhile(_ == h))
    }

    return compressR(Nil, list)
}
  • (4) foldRight
def compressFunctional[A](ls: List[A]): List[A] =
    ls.foldRight(List[A]()) { (h, r) =>
        if (r.isEmpty || r.head != h)
            h :: r
        else
            r
    }

P09 (**) Pack consecutive duplicates of list elements into sublists.

要求

If a list contains repeated elements they should be placed in separate sublists.

Example:

scala> pack(List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e))
res0: List[List[Symbol]] = List(List('a, 'a, 'a, 'a), List('b), List('c, 'c), List('a, 'a), List('d), List('e, 'e, 'e, 'e))

方案

  • (1) span + 普通递归
def pack2[T](list: List[T]): List[List[T]] = list match {
    case Nil => List(List())
    case ls: List[T] => {
        val (packed, tail) = ls.span(_ == ls.head)
        if (tail == Nil)
            List(packed)
        else packed :: pack2(tail)
    }
}
  • (2) span + 尾递归
def pack[T](list: List[T]): List[List[T]] = {
    def packR(ret: List[List[T]], ls: List[T]): List[List[T]] = ls match {
        case Nil => ret
        case head :: tail => {
            val (l, r) = (head :: tail).span(_ == head)
            packR(ret ::: List(l), r)
        }
    }
    return packR(Nil, list)
}

P10 (*) Run-length encoding of a list.

要求

Use the result of problem P09 to implement the so-called run-length encoding data compression method. Consecutive duplicates of elements are encoded as tuples (N, E) where N is the number of duplicates of the element E.

Example:

scala> encode(List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e))
res0: List[(Int, Symbol)] = List((4,'a), (1,'b), (2,'c), (2,'a), (1,'d), (4,'e))

方案

  • (1) map
def encode[T](list: List[T]): List[(Int, T)] =
    pack(list).map(e => (e.length, e.head))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值