大數乘法(完全模擬手工乘法,弱爆了)

這是數據結構與算法的作業,要求實現一個能做任意的大數乘法的程序
當時完全不懂分治法和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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章