将两个链表中的数相加

发布时间 2023-06-07 20:16:34作者: 汀洲杜若

一个链表由一个十进制整数字符串构建,各个节点内部使用32位压缩BCD码。例如:由字符串“12345678901234567890”构建出的链表的形式是:[0x00001234-0x56789012-0x34567890-NULL]。

列表的构建过程可简单描述为:

List NewNumber(const char *s) {
Head=NULL;
right = s + strlen(s);
while(s < right) {
Temp = new node;
left = right < s+8 ?s : right-8;//每次尽量取8个字符
k = right - left, v = 0;//k是字符数,v存BCD码
for(i=0; i<k; i++)  v |= (*(--right) - '0') << (4*i);
Temp->val = v;
Temp->Next = Head;//加入节点
Head = Temp;
}//end while
return Head  }

 

将这两个列表表示的数字相加:

List AddNumber(List a, List b) {
    Head = cin = 0;
    反转a和b,a和b分别指向各自最低8位bcd;
    while(a && b) {
        Temp = new node;
        Temp->Next = Head,  Head = Temp;
        // ↓ 将a和b指向的节点的值相加(进位cin),结果写入新节点, 进位再存入cin
        add2(a->val, b->val, cin, &Temp->val, &cin);
        a = a->Next,  b = b->Next;  }
    if(a) {
        while(a) {
            Temp = new node
            Temp->Next = Head,  Head = Temp;
            add2(a->val, 0, cin, &Temp->val, &cin);
            a = a->Next  }  }
    if(b)...//类似if(a)
    if(cin) {
        Temp = new node
        Temp->val = cin;
        Temp->Next = Head, Head = Temp;  }
    反转a和b,使其恢复原样
    return Head;
}

最后一步,两个数相加:

void add2(加数 x,加数 y,进位 c, 和:unsigned *z,进位:unsigned *cout) {
    *z = 0;
    for(i = 0; i<8; i++) {
        c = (x & 0xf) + (y & 0xf) + c;//取低四位二进制进行运算
        if(c > 9)   c += 6;//调整结果
        *z |= ((c & 0xf) << (4* i ));//和写z
        c >>= 4;//进位写c
        x >>= 4,y >>= 4   }
    if(cout)     *cout = c;//进位写cout
}
代码省略了与文章无关的部分。