这是数据结构与算法的作业,要求实现一个能做任意的大数乘法的程序
当时完全不懂分治法和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;
}