【问题标题】:add two numbers represented by linked list in scala在scala中添加两个由链表表示的数字
【发布时间】:2018-09-03 17:20:20
【问题描述】:

我是 scala 的新手,想编写一个代码,按照下面给出的示例在 scala 中添加两个由链表表示的数字

输入: 第一个列表:5->6->3 //代表数字 365 第二个列表:8->4->2 //代表数字 248 输出 结果列表:3->1->6 //代表数字 613

我已经在 Scala 中实现了一个可变单链表代码,用于向链表添加、更新和插入元素。在下面找到我的代码

    class SinglyLinkedList[A] extends ListADT[A] {
  private class Node(var data: A,var next: Node)
  private var head: Node = null
  def apply(index: Int): A = {
    require(index >= 0)
    var rover = head
    for (i <- 0 until index) rover = rover.next
    rover.data
  }
  def update(index: Int,data: A): Unit = {
    require(index >= 0)
    var rover = head
    for (i <- 0 until index) rover = rover.next
    rover.data = data
  }

  def insert(index: Int,data: A): Unit = {
    require(index >= 0)
    if(index == 0) {
      head = new Node(data, head)
    }
    else{
      var rover = head 
      for (i <- 0 until index-1) 
        rover = rover.next
        rover.next = new Node(data, rover.next)
    }
  }
  def remove(index: Int): A = {
    require(index >= 0)
    if(index == 0){
      val ret = head.data
      head = head.next
      ret
      } else {
   var rover = head 
      for (i <- 0 until index-1) rover = rover.next
        val ret = rover.next.data
        rover.next = rover.next.next
        ret
      }
  }


}

谁能告诉我我将如何执行链表表示的两个数字的相加。

【问题讨论】:

  • 您的问题是什么?你卡在哪一部分?我建议你用文字写出解决问题所需的步骤。想想你如何手动添加数字。
  • 你试过什么方法吗?怎么手动加法?你能把手动加法转换成代码吗?
  • 您的问题是什么?你卡在哪里了?

标签: scala singly-linked-list


【解决方案1】:

加法是如何工作的?我的意思是纸上的加法:一个数字低于另一个数字?

让我们试试 465 + 248

  465
+ 248
  ---

我们从最低有效数字开始:5 + 8。但是 5 + 8 = 13,因此结果不会包含单个数字。这就是为什么我们就像幼儿园老师教我们的那样:我们留下个位,将十位带到下一列

   1
  465
+ 248
  ---
    3

现在十。 6 + 4 + (carried) 1 = 11。同样,我们留下 1 并将 1 带到下一列:

  11
  465
+ 248
  ---
   13

最后一栏。 4 + 2 + 1 = 7。

  11
  465
+ 248
  ---
  713

因此结果是 713。如果这 2 个数字中的一个有更多的列,或者您将在最后一个加法中进行,您可以重写剩余的数字。

对于不可变的点赞列表,它的工作方式相同(稍后我会解释为什么我使用不可变的):

  1. 获取两个列表
  2. 获取两个列表的头部(如果其中一个为空,您可以将另一个作为相加的结果返回)
  3. 添加头,并将结果拆分为进位和当前位(进位为 0 或 0,位 0 到 9)
  4. 如果有carry &gt; 0,则递归地将列表carry :: Nil添加到尾部之一
  5. 将数字添加到递归添加的尾部

你应该得到类似的结果:

val add: (List[Int], List[Int]) => List[Int] = {
  case (a :: as, b :: bs) => 
    val digit = (a + b) % 10
    val carry = (a + b) / 10
    if (carry > 0) digit :: add(add(as, carry :: Nil), bs)
    else digit :: add(as, bs)
  case (as, Nil)   => as
  case (Nil, bs) => bs
} 

add(5 :: 6 :: 4 :: Nil, 8 :: 4 :: 2 :: Nil) // 3 :: 1 :: 7 :: Nil

现在,如果您使用可变列表,它会变得更加棘手。如果你想使用可变列表,你想更新其中之一,对吧?哪一个 - 第一个?第二?两个都?您的算法可能会计算出正确的结果,但会扼杀输入。

假设您总是将第二个列表添加到第一个列表中,并且希望保留第二个列表不变。如果第二个列表更长,并且您必须为数字添加一些新位置,则必须复制所有剩余的段(否则您可以例如更新第二个列表中的一个数字并更改第一个)。您还必须使用手提箱处理角箱。

相当违反直觉的行为 - 数字是不可变的,而您想要表示数字。

【讨论】:

    【解决方案2】:

    试试这个:

    def add(a: List[Int], b: List[Int], o: Int): List[Int] = (a,b,o) match {
      case (x::xs, y::ys, d) =>
        val v = d + x + y
        (v%10)::add(xs, ys, v/10)
      case (Nil, Nil, 0) => Nil
      case (Nil, Nil, d) => d::Nil
      case (xs, Nil, d) => add(xs, 0::Nil, d)
      case (Nil, ys, d) => add(0::Nil, ys, d)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      • 2015-05-04
      相关资源
      最近更新 更多