添加两个数字时出错(链表中的数字)

时间:2015-03-03 14:04:00

标签: c++ list

这是关于https://oj.leetcode.com/problems/add-two-numbers/

的问题
  

您将获得两个代表两个非负数的链表。   数字以相反的顺序存储,并且每个节点都包含   一位数。添加两个数字并将其作为链接列表返回。

     

输入:(2 - > 4 - > 3)+(5 - > 6 - > 4)

     

输出:7 - > 0 - > 8

我跟随的逻辑是我假设list1比list2长,否则交换它们。然后,通过在list2的末尾添加包含零的节点,使list2的长度等于list1。 (然后代码打印这两个列表以检查是否存在错误)。在此之后,我从头开始遍历列表,添加个别数字,用模数为10的数字之和覆盖链表1中的值。还记录进位值。这一直到列表结束。如果最后一个进位值不为零,则创建一个包含进位值的新节点,并将其插入到链表1的末尾。返回链表1的头部。

代码在所有情况下都能正常工作,除了必须在最后用进位值添加新节点的情况。我在返回值之前打印链表1,并且在那时它是正确的。然而,返回头部并在main函数中打印它会给出应该包含进位数的节点中的垃圾值给出错误的答案。这几乎就像带有进位数的节点被2-3个带有垃圾值的节点所取代。有人可以解释一下吗?

我观察到的另一个问题是在打印最终的ans时,如果我使用cout << ans->val << " " << endl代码正确终止(返回0)但输出的输出不正确。如果我删除endl,即使用cout << ans->val << " ",那么代码termminates会抛出运行时错误(seg fault)。我无法想出合适的理由。

感谢您的时间和帮助。

#include <iostream>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode *addTwoNumbers(ListNode *l1, ListNode *l2)
    {
      ListNode* l1_mover = l1;
      ListNode* l2_mover = l2;
      while ((l1_mover->next != NULL) && (l2_mover->next != NULL))
      {
        l1_mover = l1_mover->next;
        l2_mover = l2_mover->next;
      }
      if ((l1_mover->next == NULL) && (l2_mover->next != NULL))
      {
        // Call the function after swapping the lists if the first one is smaller
        cout << "calling function with swapped lists " << endl;
        return addTwoNumbers(l2, l1);
      }
      while (l1_mover->next != NULL)
      {
        ListNode emp(0);
        l2_mover->next = &emp;
        l1_mover = l1_mover->next;
      }
      // Till now, I have equated the lengths of both the lists, by padding the shorter one with zeros.

      cout << "printing list 1 inside. " << endl;
      l1_mover = l1;
      while (l1_mover != NULL)
      {
        cout << l1_mover->val << " ";
        l1_mover = l1_mover->next;
      }
      cout << endl;

      cout << "printing list 2 inside. " << endl;
      l2_mover = l2;
      while (l2_mover != NULL)
      {
        cout << l2_mover->val << " ";
        l2_mover = l2_mover->next;
      }
      cout << endl;
      // The above two print statements show that the lists are still correct
      l1_mover = l1;
      l2_mover = l2;
      int carry = 0;
      while (l1_mover != NULL)
      {
        int digit_sum = l1_mover->val + l2_mover->val + carry;
        carry = digit_sum / 10;
        l1_mover->val = digit_sum % 10;
        //cout << "sum is " << digit_sum << " and l2 val is " << l2_mover->val << endl;
        if (l1_mover->next == NULL)
          break;
        // the above break is so that l1 is not NULL at end of loop.
        l1_mover = l1_mover->next;
        l2_mover = l2_mover->next;
      }
      if (carry != 0)
      {
        cout << "carry not zero " << carry  << endl;
        ListNode last_one(carry);
        l1_mover->next = &(last_one);
      }
      cout << endl << "printing ans inside. " << endl;
      l1_mover = l1;
      while (l1_mover != NULL)
      {
        cout << l1_mover->val << " ";
        l1_mover = l1_mover->next;
      }
      cout << endl << endl;
      // The above lines print the linked list containing the sum. It is observed to be correct.
      return l1;
    }
};

int main()
{
  ListNode a1(8);
  ListNode b1(7);
  ListNode b2(9);
  b1.next = &b2;
  Solution object;
  ListNode* ans = object.addTwoNumbers(&a1, &b1);
  cout << "printing ans " << endl;
  while (ans != NULL)
  {
    cout << ans->val << " " << endl;
    // cout << ans->val << " "; // if this line is used, instead of the above one,
    // the program terminates with an error message. It doesn't give an error if the other line
    // is used.
    ans = ans->next;
  }
}

2 个答案:

答案 0 :(得分:1)

ListNode last_one(carry);
l1_mover->next = &(last_one);

然后你return l1 ;,而最后一个节点是本地的

编辑:我改变了这一点,现在工作得很好,但我只是指出了问题,如果你想要解决方案,那就告诉我,我已经

void print( ListNode * l )
{
    if( l )
    {
        print( l->next ) ;
        cout << l->val ;
    }
}

答案 1 :(得分:0)

为什么不只是阅读每个链表,提取其预期值,执行操作(添加),然后将其重新编码为链表?

链接列表已经反向排序,这使逻辑更容易添加其他位置。

即。如果您将链表概念化为数组......

(linked_list[0] * 1) + (linked_list[1] * 10) + (linked_list[2] * 100)

依此类推。

然后,你将它们加在一起,因为它们都是整数,我们可以使用模数并重新编码:

sum = linked_list_num_1 + linked_list_num_2;

int n = 0;

while (sum != 0)
{ 
    result_linked_list[n] = sum % 10;
    sum = sum / 10;
    ++n;
}

我现在正在自己的类中执行链表容器,看起来你可以为列表编写一个轻量级容器,这样你至少可以轻松地添加和提取节点。