C语言使用栈实现String类型的两个大数相加
要开始找工作了,记录下学习的关于数据结构的应用~~从栈开始~~ 栈和指针的应用~~~
实现String类型的两个大数相加
主要思想是通过C语言的栈来实现,栈是后进先出的特点,因此很适合做这类计算。建立四个栈,分别按字符串字符先后顺序入栈大数的整数部分和小数部分,然后先计算小数部分的,由于小数部分是高位对齐,因此一直出栈最长小数栈的字符并进入小数结果的栈,小数位数对齐后,两个小数栈出栈进行相加。然后进行整数栈相加,由于整数部分是按低位对齐,因此直接出栈相加即可,将每位相加结果入结果整数栈。比如字符串A:123.666,字符串B:333.6665整部部分入栈A_IN顺序123, B_IN顺序333 小数部分A_point顺序666 B_point顺序6665 小数部分B比比A长,先出B_point的5入结果result_point 5,然后小数部分位数相等,相加结果入栈 result_point栈的入栈顺序为 5,2,3,3 进位为1 进行整数栈出栈相加入栈 result_IN为 7,5,4 进位为0,输出结果 457.3325
//源代码如下,可常运行
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_STACK_SIZE 20
#define STACKINCREMENT 10
//定义一个栈
typedef struct sqStack {
char *base;
char *top;
int stacksize;
}sqStack;
//初始化栈,给栈分配空间及追加空间
void initstack(sqStack *s) {
s->base = (char *)malloc(sizeof(char)*MAX_STACK_SIZE);
if (!s->base) exit(0);
s->top = s->base;
s->stacksize = MAX_STACK_SIZE;
}
//入栈
void push(sqStack *s, char c) {
if (s->top - s->base >= s->stacksize) {
s->base = (char *)realloc(s->base,(s->stacksize+ STACKINCREMENT)*sizeof(char));
if (!s->base) exit(0);
s->top = s->base;
s->stacksize = s->stacksize + STACKINCREMENT;
}
*(s->top) = c;
s->top++;
}
//出栈
void pop(sqStack *s, char *c) {
if (s->base == s->top) return;
*c = *--(s->top);
}
//将字符串分小数部分和整数部分按序入栈
void insertStack(sqStack *s, sqStack *sp, char **s1) {
int i = 0;
//整数部分入栈;
while (((*s1)[i]) != '\0')
{
if ((*s1)[i] >= '0'&& (*s1)[i] <= '9')
{
push(s, (*s1)[i]);
i++;
}
else {
//进入小数部分入栈
if ((*s1)[i] == '.')
break;
else
{//输入非法
printf("false\n");
exit(0);
}
}
}
i++;
//小数部分入栈
while (((*s1)[i]) != '\0') {
if ((*s1)[i] >= '0'&& (*s1)[i] <= '9')
{
push(sp, (*s1)[i]);
i++;
}
else {
//输入非法
printf("false\n");
exit(0);
}
}
}
//两个栈的数出栈做加法
void addTwoStrings(sqStack *s1, sqStack *s2, int *c,sqStack *result_po) {
char a, b, d, e;
while (s1->top != s1->base || s2->top != s2->base) {
if (s1->top != s1->base && s2->top != s2->base) {
pop(s1, &a);
pop(s2, &b);
push(result_po, ((a-'0') + (b- '0') + *c) % 10+ '0');
*c = ((a-'0') + (b -'0') + *c) / 10;
}
else {
if (s1->top != s1->base)
{
pop(s1, &a);
push(result_po, ((a -'0') + *c) % 10+'0');
*c = ((a -'0') + *c) / 10;
}
else {
pop(s2, &b);
push(result_po, (( b - '0' ) + *c) % 10 + '0');
*c = ((b - '0') + *c) / 10;
}
}
}
}
//主函数
void main() {
char num1[128] = { 0 }, num2[128] = {0}; //定义两个字符数组并初始化
int c = 0;//定义进位,初始化
char a, b, e, d,x; //定义中间变量
char *s1, *s2; //定义指针,分别指向两个字符串
sqStack S1_IN, S2_IN, S1_PO, S2_P0, result_in, result_po; //定义栈,输入大数的整数部分、小数部分、结果整数部分、小数部分栈
scanf("%s %s", num1, num2);
s1 = num1;
s2 = num2;
//初始化栈
initstack(&S1_IN);
initstack(&S1_PO);
initstack(&S2_IN);
initstack(&S2_P0);
initstack(&result_in);
initstack(&result_po);
//分别将大数的整数部分、小数部分存储到对应的整数栈、小数栈
insertStack(&S1_IN, &S1_PO, &s1);
insertStack(&S2_IN, &S2_P0, &s2);
//先进性小数部分的相加:因为小数部分是从高位对齐做加法,因此先出栈小数部分位数较大的栈。
while((S1_PO.top- S1_PO.base)!= (S2_P0.top - S2_P0.base))
{
if ((S1_PO.top - S1_PO.base) > (S2_P0.top - S2_P0.base))
{
pop(&S1_PO, &x);
push(&result_po, x);
}
else {
if ((S1_PO.top - S1_PO.base) < (S2_P0.top - S2_P0.base))
{
pop(&S2_P0, &x);
push(&result_po, x);
}
else
break;
}
}
//小数部分位数相等,进行小数部分相加,用c记录进位,并将计算结果入栈小数位结果栈
addTwoStrings(&S1_PO, &S2_P0, &c, &result_po);
//小数部分位数相等,进行整数部分相加,用c记录进位,并将计算结果入栈整数位结果栈
addTwoStrings(&S1_IN, &S2_IN, &c, &result_in);
//以下部分进行从高位到低位进行输出,首先判断最高位相加后的进位,如果是1则输出,如果是0则不输出
if (c == 1)
printf("%d", c);
//出整数栈
while (result_in.top != result_in.base)
{
pop(&result_in, &e);
printf("%c", e);
}
//输出小数点,出小数栈
printf(".");
while (result_po.top!= result_po.base)
{
pop(&result_po, &d);
printf("%c", d);
}
printf("\n");
}