从反向链表中提取值

时间:2017-08-14 20:47:21

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

问题:

  

您有两个由链表表示的数字,其中每个节点包含一个数字。数字以相反的顺序存储,使得1的数字位于列表的开头。编写一个函数,添加两个数字并将总和作为链表返回。

一个例子:

  

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

     

那是:617 + 295。

     

输出:2 - > 1 - > 9。

     

那是:912。

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

第1步:定义链表

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

然后我继续使用以下功能反转链表。

第3步:反转链表

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

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

1 个答案:

答案 0 :(得分:0)

除了打印结果之外,不需要在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 - &gt; 1 - &gt; 6 - &gt;零

     

5 - &gt; 9 - &gt; 2 - &gt;零

     

2 - &gt; 1 - &gt; 9 - &gt;零