【C语言】无符号大数的加减问题

1 篇文章 0 订阅

无符号大数加、减运算。。题目要求输入两个无符号大数,保证一个大数不小于第二个大数,输出它们的和、差。

输入样例:

1234567890987654321333888999666
147655765659657669789687967867

输出样例:

1234567890987654321333888999666+147655765659657669789687967867=1382223656647311991123576967533
1234567890987654321333888999666-147655765659657669789687967867=1086912125327996651544201031799

 代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

//createNew 申请空间
struct Node *_createNew();

//_createUmBigNumber 申请大数链表
struct unBigNumber *_createUnBigNumber();

//add 做加法
struct unBigNumber *_add(struct unBigNumber *List1, struct unBigNumber *List2, struct unBigNumber *List3);

//minus 做减法
struct unBigNumber *_minus(struct unBigNumber *List1, struct unBigNumber *List2, struct unBigNumber *List3);

//input 输入数据
struct unBigNumber *_input(struct unBigNumber *List);

//print 打印链表
void _print(struct unBigNumber *List);

//destroy 销毁链表
void _destroy(struct unBigNumber *List);

//createNew 一个节点结构体
struct Node {
    int data;
    struct Node *next, *prev;//指向前和后
};

//无符号大数结构体
struct unBigNumber {
    int digitCount;//位数
    struct Node *phead, *ptail;//指向头和尾
};

int main()
{
    //创建三个无符号大数的链表
    struct unBigNumber *List1, *List2, *List3;
    List1 = _createUnBigNumber();
    List2 = _createUnBigNumber();
    List3 = _createUnBigNumber();

    //输入进行运算的两个无符号大数
    List1 = _input(List1);
    List2 = _input(List2);

    //进行加法并打印
    List3 = _add(List1,List2,List3);
    _print(List1);
    printf("+");
    _print(List2);
    printf("=");
    _print(List3);
    printf("\n");

    //减法运算
    List3 = _minus(List1,List2,List3);
    _print(List1);
    printf("-");
    _print(List2);
    printf("=");
    _print(List3);
    printf("\n");

    //销毁
    _destroy(List1);
    _destroy(List2);
    _destroy(List3);

    return 0;
}
//_createUnBigNumber();
struct unBigNumber *_createUnBigNumber() {
    struct unBigNumber *pnew;
    pnew = (struct unBigNumber *)malloc(sizeof(struct unBigNumber));

    struct Node *p;
    p = _createNew();
    pnew -> phead = p;
    pnew -> ptail = p;
    return pnew;
};

//createNew
struct Node *_createNew() {
    struct Node *p;
    p = (struct Node *)malloc(sizeof(struct Node));
    p -> next = NULL;
    p -> prev = NULL;

    return p;
};

//_appendFront
struct unBigNumber *_appendFront(struct unBigNumber *List, int ch) {
    struct Node *pnew;
    pnew = _createNew();
    pnew -> data = ch;

    //进行插入
        //尾节点没有数据
    if(List -> digitCount == 0){
        List -> ptail = pnew;
        List -> phead = pnew;
    }
    else {
        //将头节点指向pnew
            //储存phead
        struct Node *temp;
        temp = _createNew();//避免空指针
        temp = List -> phead;

        //插入pnew
        List -> phead = pnew;
        pnew -> next = temp;
        temp -> prev = pnew;
    }

    //位数加一
    ++List -> digitCount;
    return List;
}

//_appendTail
struct unBigNumber *_appendTail (struct unBigNumber *List, int ch) {
    struct Node *pnew;
    pnew = _createNew();
    pnew -> data = ch;
    //如果未储存数字
    if(List -> digitCount == 0) {
        List -> phead = pnew;
        List -> ptail = pnew;
        //位数加一
        ++List -> digitCount;
    }
    //如果只有一个数字0那么位数不变
    else if(List -> digitCount == 1 && List -> ptail -> data == 0) {
        List -> ptail = pnew;
        List -> phead = pnew;
    }
    else {
        List -> ptail -> next  = pnew;
        pnew -> prev = List -> ptail;
        List -> ptail = List -> ptail -> next;
        //位数加一
        ++List -> digitCount;
    }
//printf("_appendTailed\n");
    return List;
}

//_normalize
struct unBigNumber *_normalize(struct unBigNumber *List) {
    //如果位数为0即phead为空
    if(List -> digitCount == 0) {
        List = _appendTail(List,0);
    }

    //除去最高位数的0
    while(List -> phead -> data == 0 && List -> digitCount > 1) {
        struct Node *temp;
        temp = List -> phead;
        List -> phead = temp -> next;
        temp -> next -> prev = List -> phead;
        --List -> digitCount;
    }
//printf("normalized\n");
    return List;
}

//_doublyLink
struct unBigNumber *_doublyLink(struct unBigNumber *List) {
    struct Node *pnew;
    pnew = _createNew();

    //将大数链表进行头尾节点以及位数的处理
    List -> phead = pnew;//建立头节点
    List -> ptail = pnew;//建立尾节点
    List -> digitCount = 0;//位数为0
    return List;
}

//_input
struct unBigNumber *_input(struct unBigNumber *List) {
    List = _doublyLink(List);

    //过滤掉非数
    char ch;
    do {
        ch = getchar();
    }
    while(ch < '0' || ch > '9');


    //从最高位读取数字
    while(ch >= '0' && ch <= '9') {
        List = _appendTail(List,ch - '0');
        ch = getchar();
    }

    //规范化去掉最高位多余的0
    List = _normalize(List);
//printf("inputed\n");
    return List;
}

//_add
struct unBigNumber *_add(struct unBigNumber *List1, struct unBigNumber *List2, struct unBigNumber *List3) {
    //双向化链表C
    List3 = _doublyLink(List3);

    //进行加法运算
    int iCarry = 0;//进位储存
    int temp;//储存两数相加的结果
    int result;//储存余数
    struct Node *p1, *p2;//进行操作的节点
    p1 = List1 -> ptail;//从尾节点开始处理
    p2 = List2 -> ptail;

    //进行循环计算
    while(p1 != List1 -> phead && p2 != List2 -> phead) {
        //进行余数和进位的计算
        temp = p1 -> data + p2 -> data + iCarry; //加上进位
        iCarry = temp / 10;
        result = temp % 10;

        //将操作所得到的余数添加到List3
        List3 = _appendFront(List3,result);

        //两个链表都向前移动一位
        p1 = p1 -> prev;
        p2 = p2 -> prev;
    }

    //如果位数相同
    if(p1 == List1 -> phead && p2 == List2 -> phead) {
        temp = p1 -> data + p2 -> data + iCarry;
        iCarry = temp / 10;
        result = temp % 10;
        List3 = _appendFront(List3,result);
        return List3;
    }

    int x = p2 -> data;//储存p2 -> phead的值,只做一次运算,避免改掉phead的值
    //处理List1剩余位
    while(p1 != List1 -> phead ) {
        temp = p1 -> data + x + iCarry;
        iCarry = temp / 10;
        result = temp % 10;
        x = 0;
        List3 = _appendFront(List3,result);
        p1 = p1 -> prev;

        //加上phead的值
        if(p1 == List1 -> phead) {
                result = p1 -> data + iCarry;
            List3 = _appendFront(List3,result);
        }
    }

    int y = p1 -> data;
    //处理List2剩余位
    while(p2 != List2 -> phead) {
        temp = p2 -> data + y + iCarry;
        iCarry = temp / 10;
        result = temp % 10;
        y = 0;
        List3 = _appendFront(List3,result);
        p2 = p2 -> prev;
        if(p2 == List2 -> phead) {
                result = p2 -> data + iCarry;
            List3 = _appendFront(List3,result);
        }
    }

    //如果两个链表都已经遍历完仍有进位则List3在加一位
    if(iCarry != 0) {
        List3 = _appendFront(List3,iCarry);
    }

    return List3;
};

//minus 做减法
struct unBigNumber *_minus(struct unBigNumber *List1, struct unBigNumber *List2, struct unBigNumber *List3) {
    //双向化链表C
    List3 = _doublyLink(List3);

    //进行减法运算
    int iCarry = 0;//借位储存
    int temp;//储存两数相减的结果
    int result;//储存余数
    struct Node *p1, *p2;//进行操作的节点
    p1 = List1 -> ptail;//从尾节点开始处理
    p2 = List2 -> ptail;

    //进行循环计算
    while(p1 != List1 -> phead && p2 != List2 -> phead) {
        //进行余数和进位的计算
        temp = p1 -> data  - p2 -> data - iCarry; //借位减去1
        if(temp < 0) {
            temp += 10;
            iCarry = 1;
        }
        else
            iCarry = 0;
        result = temp;

        //将操作所得到的余数添加到List3
        List3 = _appendFront(List3,result);

        //两个链表都向前移动一位
        p1 = p1 -> prev;
        p2 = p2 -> prev;
    }

    //位数相同
    if(p1 == List1 -> phead && p2 == List2 -> phead) {
        temp = p1 -> data - p2 -> data - iCarry;
        result = temp % 10;
        List3 = _appendFront(List3,result);
        List3 = _normalize(List3);

        return List3;
    }

    //处理List1剩余位
    int x = List2 -> phead -> data;//同上
    while(p1 != List1 -> phead) {
        //减去减数的第一个数
        if(p2 -> data != 0) {
            temp = p1 -> data - x - iCarry;
            if(temp < 0) {
                temp += 10;
            }
            else
                iCarry = 0;
            result = temp;

            List3 = _appendFront(List3,result);
            p1 = p1 -> prev;
            x = 0;
        }

        //将List1剩余的值进行拷贝
        else {
            temp = p1 -> data - iCarry;
            if(temp < 0) {
                temp += 10;
            }
            else
                iCarry = 0;

            result = temp;
            List3 = _appendFront(List3,result);
            p1 = p1 -> prev;

        }

        //加上phead的值
        if(p1 == List1 -> phead) {
            List3 = _appendFront(List3,List1 -> phead -> data);
            break;
        }
    }
    List3 = _normalize(List3);

    return List3;
};

//_print
void _print(struct unBigNumber *List) {
    struct Node *p;
    p = List -> phead;
    while(p) {
        printf("%d",p -> data);
        p = p -> next;
    }
}

//_destroy
void _destroy(struct unBigNumber *List) {
    struct Node *p;
    p = List -> phead;

    while(p) {
        List -> phead = p -> next;
        free(p);
        p = List -> phead;
    }
}




  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值