大数乘法(完全模拟手工乘法,弱爆了)

这是数据结构与算法的作业,要求实现一个能做任意的大数乘法的程序
当时完全不懂分治法和FFT,后来还是听一个学长说,可以快速大数乘法(汗)
一并写到笔记里吧

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct data
{
    int a;
    data *next;
}data;

typedef struct big
{
    data head;
    int length;
}big;

big add(big *a0, big *b0)
{
    big result;//定义结果指针
    data *k;//存储result信息,尾部插入
    data *m, *n, *p;//定义操作指针
    k = &result.head;
    result.head.next = NULL;
    if (a0->length >= b0->length)
    {
        result.length = a0->length;
    }
    else
    {
        result.length = b0->length;
    }

    m = a0->head.next;//a0

    n = b0->head.next;//b0

    int mark = 0;
    for (int i=1;i<=result.length;i++)
    {
        p = (data*)malloc(sizeof(data));//建立节点
        p->next = NULL;
        //基础运算
        if (m == NULL)
        {
            p->a = 0 + n->a;
        }
        if (n == NULL)
        {
            p->a = 0 + m->a;
        }
        if (m != NULL&&n != NULL)
        {
            p->a = m->a + n->a;
        }
        //判断是否要进位
        if (mark)
        {
            p->a += mark;
        }
        if (p->a > 9)
        {
            mark = p->a / 10;
            p->a = p->a % 10;
        }
        else
        {
            mark = 0;
        }
        p->next = NULL;
        if (m != NULL)
        {
            m = m->next;
        }
        if (n != NULL)
        {
            n = n->next;
        }

        k->next= p;
        k = p;
        //p->next
        //result.head.next;
    }
    if (mark)
    {
        p = (data*)malloc(sizeof(data));//建立节点
        p->a = mark;
        p->next = NULL;
        k->next = p;
    }
    return result;
}
big single_ride(data *a1, big *b1)
{
    big result;//返回结果链表

    data *p1;//文件节点指针,用于建立新节点
    data *b2;//操作指针,用于寻找b1节点
    data *r;//文件操作指针用于暂存result信息,进行尾部插入
    int mark = 0;
    r = &result.head;
    b2 = b1->head.next;
    result.head.next = NULL;
    result.length = b1->length;
    for (int i = 1; i <= b1->length; i++)
    {
        p1 = (data*)malloc(sizeof(data));
        p1->next = NULL;
        p1->a = a1->a*b2->a;
        if (mark)
        {
            p1->a += mark;
        }
        if (p1->a>9)
        {
            mark = p1->a / 10;
            p1->a = p1->a % 10;
        }
        else
        {
            mark = 0;
        }
        b2 = b2->next;
        r->next = p1;
        p1->next = NULL;
        r = p1;
        //
        //p1->next = result.head.next;
        //result.head.next = p1;

    }
    if (mark)
    {
        p1 = (data*)malloc(sizeof(data));
        p1->next = NULL;
        p1->a = mark;
        r->next = p1;
        //
        //p1->next = result.head.next;
        //result.head.next = p1;
        result.length++;
    }
    return result;
}

void input(big *a1, char *b1)
{
    a1->head.next = NULL;
    a1->length = 0;//不含头节点
    int i, j, k;
    data *p;
    for (i = 0; i<strlen(b1); i++)
    {
        p = (data*)malloc(sizeof(data));
        p->a = (int)(b1[i] - '0');
        p->next = a1->head.next;
        a1->head.next = p;
        a1->length++;
    }
}
big ride(big *a0, big *b0)
{
    big single_ride(data *a1, big *b1);
    big result;
    big mid_result;
    big *mid1, *re1;
    //big mid_result;//
    data *p;//对result操作
    big *len, *shor;//储存大数,小数
    data *short1;//用于拆分小的数的节点使之与大的数相乘
    int l;//存储小的数的位数
    result.length = 0;
    result.head.next = NULL;
    if (a0->length >= b0->length)
    {
        len = a0;
        shor = b0;
        l = b0->length;
    }
    else
    {
        len = b0;
        shor = a0;
        l = a0->length;
    }
    short1 = shor->head.next;
    for (int i = 0; i < l; i++)
    {
        mid_result = single_ride(short1, len);
        short1 = short1->next;
        //给每节点乘大数补零(错位)
        for (int k = 0; k < i; k++)
        {
            p = (data*)malloc(sizeof(data));
            p->a = 0;
            p->next = mid_result.head.next;
            mid_result.head.next = p;
            mid_result.length++;
        }
        mid1 = &mid_result;
        re1 = &result;
        result = add(re1, mid1);
    }
    return result;
}

int output(big *a,char *b1)
{
    //big *a1 = &a;
    int m = a->length;
    data *p;
    p = a->head.next;
    int i = 0;
    for (; i < a->length; i++)
    {
        p = a->head.next;
        for (int k = 0; k < m-1; k++)
        {
            p = p->next;
        }
        printf("%d", p->a);
        b1[i] = char(p->a + '0');
        m--;
    }
    b1[i] = '\0';
    printf("\n");
    return 0;
}
int main()
{
    FILE *p;
    p = fopen("1.txt", "r+");
    char a[100], b[100];
    char c[100];
    fscanf(p, "%s", a);
    fscanf(p, "%s", b);
    big a0;
    big b0;
    big k0;
    input(&a0, a);
    input(&b0, b);
    //k=single_ride(a0.head.next, &b0);
    //k = add(&a0, &b0);
    k0 = ride(&a0, &b0);
    output(&k0, c);
    fprintf(p, "\n%s" , c);
    //printf("%s\n%s", a, b);
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值