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");
    
}

原文地址:https://www.cnblogs.com/feifiefighting/p/9028263.html

时间: 2024-10-12 23:37:53

C语言使用栈实现String类型的两个大数相加的相关文章

数据结构(java语言描述)顺序栈的使用(两个大数相加)

利用http://www.cnblogs.com/xleer/p/5289661.html中对顺序栈以及栈的进本方法的定义,实现超过整数上限的两个数的加法计算. 算法: package stack;/********************************************************************** * @author sch ********利用栈,计算两个大数的和.大数的值超过int存储的范围******************************

栈实现两个大数相加

import java.util.Scanner; import java.util.Stack; public class JavaDemo { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); /** * 第一个大数入栈 */ System.out.println("输入第一个大数:"); String firstNum = scanner.nextLine(); I

关于C中字符数组,字符指针以及C++中string类型的两两转换及排序

// practise.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <string.h> #include <string> #include <algorithm> #include <iostream> using namespace std; int main() { /* 字符串转字符数组,使用strncpy_s(),比strncpy()安全*/ string str

c/c++中关于String类型的思考

首先说明:String并不是一种内置类型,因此任何通过String声明出来的实例都不是一个变量,不同于内置类型因此String仅仅能称之为一种特殊的型别,没错String是一个类类型. 一般来说c语言里面是没有类和对象概念的,那么提供给c语言一个<string.h>头文件是做什么用的呢,如果研究过C++中String的构造那么应该会清楚string的底层依赖的就是内置类型的型别char *指针,所以显而易见开放<string.h>接口库给c语言就是为了处理char *字符串时能够很

C# string类型遇到的两个问题

最近在维护一位离职的同事写的WPF代码,偶然发现他使用C# string类型的两个问题,在这里记录一下. 1. 使用Trim函数移除字串中的空格.换行符等字符串. csRet.Trim(new char[] { '\r', '\n', '\t', ' ' });if (!csRet.Equals(string.Empty)) statement1; else statement2; 上述代码的意图为:移除string类型变量csRet开头和结尾处的换行符.制表符.空格符之后,判断该字符串是否是空

[每天一个知识点]18-Java语言-在switch中接受String类型

在Java7中增加了一个新特性,switch可以接受String类型的变量,这就省下了书写大量if ("xxx".equals(yyy))的繁复工作.示例代码就免了,仅仅是一个数据类型的改变而已,如果会用原来的switch而在5分钟内搞不定String类型的switch,建议还是放弃做程序员吧-- 至于内部实现,java一点都没增加新内容,其实代码是被转换成了这个样子 switch (xxx.hashCode()) { case 1024: // 假设原来是"aaa"

java内存分配和String类型的深度解析(转)

一.引题 在java语言的所有数据类型中,String类型是比较特殊的一种类型,同时也是面试的时候经常被问到的一个知识点,本文结合java内存分配深度分析 关于String的许多令人迷惑的问题.下面是本文将要涉及到的一些问题,如果读者对这些问题都了如指掌,则可忽略此文. 1.java内存具体指哪块内存?这块内存区域为什么要进行划分?是如何划分的?划分之后每块区域的作用是什么?如何设置各个区域的大小? 2.String类型在执行连接操作时,效率为什么会比StringBuffer或者StringBu

【转】java内存分配和String类型的深度解析

一.引题 在java语言的所有数据类型中,String类型是比较特殊的一种类型,同时也是面试的时候经常被问到的一个知识点,本文结合java内存分配深度分析关于String的许多令人迷惑的问题.下面是本文将要涉及到的一些问题,如果读者对这些问题都了如指掌,则可忽略此文. 1.java内存具体指哪块内存?这块内存区域为什么要进行划分?是如何划分的?划分之后每块区域的作用是什么?如何设置各个区域的大小? 2.String类型在执行连接操作时,效率为什么会比StringBuffer或者StringBui

Java内存分配和String类型的深度解析

一.引题 在java语言的所有数据类型中,String类型是比较特殊的一种类型,同时也是面试的时候经常被问到的一个知识点,本文结合java内存分配深度分析关于String的许多令人迷惑的问题.下面是本文将要涉及到的一些问题,如果读者对这些问题都了如指掌,则可忽略此文. 1.java内存具体指哪块内存?这块内存区域为什么要进行划分?是如何划分的?划分之后每块区域的作用是什么?如何设置各个区域的大小? 2.String类型在执行连接操作时,效率为什么会比StringBuffer或者StringBui