使用链接列表添加和减去Bigints

时间:2010-09-12 18:22:33

标签: c linked-list

我差不多完成了这项任务,这让我很伤心。这是我关于三个不同部分的第三篇文章,我真的很尴尬,因为我在这项工作中苦苦挣扎。

赋值本身就是创建一个程序,使用链表执行大整数的加法和减法(我慢慢开始讨厌链接列表,在Lisp之外)。除了实际的加法和减法之外,现在一切似乎都在起作用。我不确定它是否是算术函数,因为它们之前有点工作(但从不100%),但是与S / O社区一起检查并没有什么坏处(通常我不会要求这么多帮助完成任务,因为我更喜欢自己解决问题,但这是一个非常糟糕和忙碌的一周,截止日期快到了。)

我写的算术函数如下,任何人都可以帮我找出错误吗?

/*
 * Function add
 *
 * @Paramater STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes two linked lists representing
 * big integers stored in reversed order,
 * and returns a linked list containing
 * the sum of the two integers.
 *
 * @Return STRUCT* Integer
 * 
 * TODO Comment me
 */
struct integer* add( struct integer *p, struct integer *q )
{
    int carry = 0;

    struct integer *sHead, *sCurr;
    struct integer *pHead, *qHead;

    pHead = p;
    qHead = q;

    sHead = NULL;

    while( p )
    {
        sCurr = ( struct integer* ) malloc (sizeof(struct integer));
        sCurr->digit = p->digit + q->digit + carry;
        sCurr->next = sHead;
        sHead = sCurr;

        carry = 0;

        /*
         * If the current digits sum to greater than 9,
         * create a carry value and replace the current
         * value with value mod 10.
         */
        if( sCurr->digit > 9 )
        {
            carry = 1;
            sCurr->digit = sCurr->digit % 10;
        }

        /*
         * If the most significant digits of the numbers
         * sum to 10 or greater, create an extra node
         * at the end of the sum list and assign it the
         * value of 1.
         */
        if( carry == 1 && sCurr->next == NULL )
        {
            struct integer *sCarry = ( struct integer* ) malloc (sizeof(struct integer));
            sCarry->digit = 1;
            sCarry->next = NULL;
            reverse( &sCurr );
            sCurr->next = sCarry;
            reverse( &sCurr );
        }

        p = p->next;
        if( q->next ) q = q->next; 
        else q->digit = 0; 
    }

    return sHead;
}

/*
 * Function subtract
 *
 * @Parameter STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes two linked lists representing struct integers.
 * Traverses through the lists, subtracting each
 * digits from the subsequent nodes to form a new
 * struct integer, and then returns the newly formed
 * linked list.
 *
 * @Return STRUCT* Integer
 * 
 * TODO Comment me
 */
struct integer* subtract( struct integer *p, struct integer *q )
{
    int borrow = 0;

    struct integer *dHead, *dCurr;
    struct integer *pHead, *qHead;

    pHead = p;
    qHead = q;

    dHead = NULL;

    while( p )
    {
        dCurr = (struct integer*) malloc (sizeof(struct integer));
        if( q )
        {
            dCurr->digit = p->digit - q->digit - borrow;
        }
        else
        {
            dCurr->digit = p->digit - borrow;
        }
        dCurr->next = dHead;

        if( dCurr->digit < 0 )
        {
            dCurr->digit += 10;
            borrow = 1;
        }

        dHead = dCurr;

        p = p->next;
        if( q->next) q = q->next;
    }

    return dHead;
}

<小时/> <小时/> 示例输出应如下所示:

8888888888 + 2222222222 = 11111111110
10000000000 – 9999999999 = 1
10000000000 – 9999999999 = 1

但相反,它看起来像这样:

8888888888 + 2222222222 = 1111111110
10000000000 - 9999999999 = 10000000001
10000000000 - 9999999999 = 10000000001

编辑整个节目在美国东部时间下午3:30以当前形式提供here以供参考,或者如果这些功能不是问题。

3 个答案:

答案 0 :(得分:1)

else q->digit = 0;
您正在更改函数内的参数。

尝试更改您的函数以接受const个参数并重新编译。

struct integer* add( const struct integer *p, const struct integer *q )
struct integer* subtract( const struct integer *p, const struct integer *q )

答案 1 :(得分:1)

读取的部分

if( dCurr->next == NULL && carry == 1 )
{
    struct integer *dCarry = (struct integer*) malloc (sizeof(struct integer));
    dCarry->digit = -1;
    dCarry->next = NULL;
    dCurr->next = dCarry;
}

看起来有点不合适。从上面的代码中,dCurr->next被设置为我们在先前循环中已经计算过的数字,因此它在第一个数字上仅为NULL。我想你的意思是检查p->next

我假设条件len(p) >= len(q)适用于此函数。如果没有,你将不得不做一些关于它不能保持的处理(在你用尽q节点之前耗尽p节点)。我还假设数字在列表中从最低有效数字到最重要数字。如果没有,您可能需要在处理之前反转p和q。

另一件我无法弄清楚的是你如何处理负数。或者即使你应该处理它们。添加到这样的结构并不容易,因为在减去时,添加一些东西的天真方法不起作用:当q为负时,你会遇到从p中减去q的所有麻烦,然后发现你应该添加。

答案 2 :(得分:1)

在功能compare()中,您“走路”p然后再尝试再次走路。

int compare( struct integer *p, struct integer *q )
{
    /* ... */
    while( p )
    {
        pCount++;
        p = p->next;
    }

p现在为NULL

    /* ... */
    while( p )
    {
        /* ... */
    }

while循环永远不会运行。