一个链表由一个十进制整数字符串构建,各个节点内部使用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;
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
}
代码省略了与文章无关的部分。
