【问题标题】:Extracting values from a reversed linked list从反向链表中提取值
【发布时间】:2017-08-14 20:47:20
【问题描述】:

问题:

您有两个由链表表示的数字,其中每个节点包含一个数字。数字以相反的顺序存储,因此 1 的数字位于列表的头部。编写一个函数,将两个数字相加并以链表的形式返回总和。

一个例子:

输入:(7-> 1 -> 6) + (5 -> 9 -> 2)。

即:617 + 295。

输出:2 -> 1 -> 9.

即:912。

为了开始这个问题,我首先创建了一个类来定义链表:

第一步:定义链表

class Node: CustomStringConvertible{
    var value: Int
    var next: Node?
    var description: String{
        if next != nil {
          return "\(value) -> \(next!)"
        }
        else{
            return "\(value) -> \(next)"
        }
    }
    init(value: Int) {
        self.value = value
    }
}

步骤:2 - 根据用户输入的整数值生成链表

func generateList (num: Int) -> Node {
    var stringNum = Array(String(num).characters)
    let head = Node.init(value:Int(String(stringNum.first!))!)
    var current = head

    for i in 1..<stringNum.count{
        let num = Int(String(stringNum[i]))
        current.next = Node.init(value: num!)
        current = current.next!
    }
    return head
}

let list = generateList(num: 716)

// The following prints out: 7 -> 1 -> 6 -> nil

然后我继续使用以下函数反转链表。

第三步:反转链表

func reverseLinkedList (head: Node?) -> Node?{

    var current = head
    var prev: Node?
    var next: Node?

    while current != nil {
        next = current?.next
        current?.next = prev
        prev = current
        current = next
    }
    return prev
}

let reversedList = reverseLinkedList(head: list)

// The following prints out is: 6 -> 1 -> 7 -> nil

步骤 4:这一步背后的想法是提取每个节点上的值,将它们转换为字符串,然后将它们连接到字符串变量,然后最后将字符串值转换为 Int,然后使用该 Int值并最终添加它们。

func getValuesFrom (head: Node?) -> Int {

    var string = ""
    var current = head

    while current != nil {
        var stringVal = String(describing: current?.value)
        string += stringVal
        current = current?.next
    }

    return Int(string)!
}

这是我遇到问题的地方:

当我像这样将以下内容插入此函数时:

getValuesFrom(head: reversedList)

我收到以下错误:

致命错误:在展开可选值时意外发现 nil

而且我似乎无法弄清楚我为什么会遇到问题,并且非常感谢任何形式的见解。

【问题讨论】:

    标签: swift string linked-list singly-linked-list


    【解决方案1】:

    不需要在String和链表之间来回转换,除了打印结果。这样做很简单:

    class Node {
      var value: Int
      var next: Node?
    
      // init and generator can be the same method
      init(value: Int) {
        // store ones place and divide by 10
        self.value = value % 10
        var nextValue = value / 10
    
        // set up for loop
        var currentNode = self
    
        while nextValue > 0 {
          // create a new Node
          // store ones place and divide by 10
          let next = Node(value: nextValue % 10)
          nextValue /= 10
    
          // make the new Node the next Node
          currentNode.next = next
    
          // set up for next iteration
          currentNode = next
        }
      }
    }
    
    // make the list printable
    extension Node: CustomStringConvertible {
      var description: String{
        if let next = next {
          return "\(value) -> \(next)"
        }
        else {
          return "\(value) -> nil"
        }
      }
    }
    

    现在你可以这样做了:

    print(Node(value: 671)) // prints "7 -> 1 -> 6 -> nil"
    

    鉴于您的问题,也无需颠倒列表。

    如您所说,总结您可以做的列表,转换为Int,添加它们,然后生成一个新列表:

    extension Node {
      func toValue() -> Int {
        var place = 10
        var current = self
        // add each value and multiply by the place value
        // first is 1, second 10, third 100, etc.
        var result = current.value
        while let next = current.next {
          result += next.value * place
          place *= 10
          current = next
        }
        return result
      }
    }
    

    那么你只需要重载加法运算符...

    func +(lhs: Node, rhs: Node) -> Node {
      return Node(value: lhs.toValue() + rhs.toValue())
    }
    

    然后测试...

    let first = Node(value: 617)
    let second = Node(value: 295)
    print(first)
    print(second)
    print(first + second)
    

    结果:

    7 -> 1 -> 6 -> 无

    5 -> 9 -> 2 -> 无

    2 -> 1 -> 9 -> 无

    【讨论】:

    • 非常感谢!我真的很感激!
    • 如果您的问题有答案,最好接受。这样,其他正在寻找类似问题的人会发现这个问题的答案已被接受。
    • 我一定会牢记这一点并继续这样做,感谢您的帮助!!!
    猜你喜欢
    • 2013-07-28
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 2011-05-03
    • 2011-06-21
    • 2022-09-30
    • 2016-08-29
    相关资源
    最近更新 更多