思路:

之前写的乘法有点小问题,现在更正了

普通表达式运算:

采用字符串的形式输入一个表达式和栈结构来存储中间运算结果,可以参照《数据结构(严慧敏)》,依次从字符串中读取字符,如果是数字则读取整个数字,如果是运算符则判断优先级(出栈\压栈\计算)......

大整数表达式运算:

与普通的表达式同一个思路,只不过现在的数变成了大整数,所以得自己分别实现大整数的四则运算(另外说明下单词都是百度来的...)大致的说明下思路:

加法:

将数字字符串提取出来后从每个数字的最后一位开始相加,用一个变量t来存储是否进位,一开始没有进位所以我给t赋初值为0,每一次我都会判断是否有进位,如果有就让t=1(最多进一位),因为是字符所以运算的时候减去字符‘0’以方便运算。

    while (lena >= 0 && lenb >= 0) {
                        result[i] = a[lena] + b[lenb] - 2 * '0' + t;
                        t = result[i] / 10;
                        result[i] = result[i] % 10 + '0';
                        i++; lena--; lenb--;
                 }

要考虑其中一位加完后另外一位没有加完的情况,这个时候直接将没有加完的加到结果上去就好了

    while (lena >= 0) {//a没加完的情况
        result[i] = a[lena] + t - '0';
        t = result[i] / 10;
        result[i] = result[i] % 10 + '0';
        i++; lena--;
    }
    while (lenb >= 0) {//b没加完的情况
        result[i] = b[lenb] + t - '0';
        t = result[i] / 10;
        result[i] = result[i] % 10 + '0';
        i++; lenb--;
    }
    if (t)result[i++] = t + '0';
    result[i] = '\0';//不要忘了最后加上‘\0’
    BigIntegerResultReverse(result);//同时计算出来的结果其实是倒过来的,再次将结果反转

乘法:

static void BigIntegerMulti(char a[], char b[], char result[])
{
    memset(result, '0', 1000);//先将结果数组初始化一波做准备
    int lena = strlen(a) - 1;
    int lenb = strlen(b) - 1;
    int k = lenb, j = lena, t = 0, temp;//同样的t表示进位
    while (k >= 0) {//数字(组)b的最后一位分别乘以a的每一位
        for (j = lena; j >= 0; j--) {
            temp = (b[k] - '0')*(a[j] - '0') + t + result[lenb - k + lena - j] - '0';//lenb-k表示计算到b的第k位
            result[lenb - k + lena - j] = temp % 10 + '0'; //lena-j表示计算到a的第j位
            t = temp / 10;//lenb - k + lena - j则表示此时正在计算的这一位应该加到结果的第lenb - k + lena - j位上去,想一想你手算的过程
        }

if (k == 0)break;
        if (t) {
            result[lenb - k + lena + 1] = t + '0';
            t = 0;
        }
        k--;
    }
    if (t) {
        result[lena + lenb + 1] = t + '0';
        result[lena + lenb + 2] = '\0';
    }
    else result[lena + lenb + 1] = '\0';
    BigIntegerResultReverse(result);
}

(本人算法小白,存在的bug还请大佬指点一二),下面给出代码,如果要计算大整数记得在输入的时候加上'L';例如:“L132465454561231+45613465*15341865465”

#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>static int charactor[256];static void CharactorInit()
{charactor['+'] = 1;charactor['-'] = 2;charactor['*'] = 3;charactor['/'] = 4;charactor['('] = 5;charactor[')'] = 6;//charactor[' '] = 7;
}static int PriorityJudge(char x1, char x2)
{ //-1:x1<x2  0:x1=x2  1:x1>x2if (charactor[x1] >= 1 && charactor[x1] <= 4 && charactor[x2] >= 1 && charactor[x2] <= 4 && x1 == x2)return 1;if (charactor[x1] == 5){if (charactor[x2] == 6)return 0;return -1;}if (charactor[x1] == 3 || charactor[x1] == 4){if (charactor[x2] == 5)return -1;return 1;}if (charactor[x1] == 1 || charactor[x1] == 2){if (charactor[x2] <= 5 && charactor[x2] >= 3)return -1;return 1;}return -1;
}// <-------------------------StatementCompulation------------------------------>#define EMPTY 0
#define StackGrewSpeed 100typedef struct CompulationStack
{int *p = (int *)malloc(sizeof(int) * 1000);int *top = p;int AllLength = 1000;int CurLength = 0;
} CompulationStack;static int Pop(CompulationStack *stack);
static int Push(CompulationStack *stack, int x);
static int ResizeStack(CompulationStack *stack);
static int IsEmpty(CompulationStack *stack);
static int GetTop(CompulationStack *stack, int *x);
static int Caculator(int a, int b, char method);
static int JudgeCharactor(char x);
static int PriorityJudge(char x1, char x2);/*
static void InitStatement(int cha) {int length = sizeof(cha) / sizeof(int);for(int i=0;i<length;i++)cha=
}
*/static int Pop(CompulationStack *stack)
{if (IsEmpty(stack))return EMPTY;stack->CurLength--;return *--stack->top;
}static int Push(CompulationStack *stack, int x)
{if (stack->CurLength >= stack->AllLength)ResizeStack(stack);*stack->top++ = x;stack->CurLength++;return 1;
}static int ResizeStack(CompulationStack *stack)
{stack->AllLength += StackGrewSpeed;stack->p = (int *)realloc(stack->p, stack->AllLength);return 1;
}static int IsEmpty(CompulationStack *stack)
{if (stack->top == stack->p)return !EMPTY;return EMPTY;
}static int GetTop(CompulationStack *stack, int *x)
{if (!IsEmpty(stack)){return *x = *(stack->top - 1);}return 0;
}static int Caculator(int a, int b, char method)
{int a1 = a;int a2 = b;switch (method){case '+':return a1 + a2;case '-':return a1 - a2;case '*':return a1 * a2;case '/':return a1 / a2;}return -1;
}static int JudgeCharactor(char x)
{if (x - '0' >= 0 && x - '0' <= 9)return 8;return charactor[x];
}int Compulation(char statement[])
{CharactorInit();int p, x, result = 0;int statementLength = strlen(statement);CompulationStack DigitStack;CompulationStack CharactorStack;for (int i = 0, j; i < statementLength;){j = JudgeCharactor(statement[i]);if (!j)continue;if (j == 8){int k = i, temp = 0;while (JudgeCharactor(statement[i + 1]) == 8)i++;for (int l = 0; l <= i - k; l++)temp += (statement[i - l] - '0') * (int)pow(10, l);Push(&DigitStack, temp);i++;}else{p = PriorityJudge(GetTop(&CharactorStack, &x), statement[i]);if (p == 1){Push(&DigitStack, Caculator(Pop(&DigitStack), Pop(&DigitStack), Pop(&CharactorStack)));//                Push(&CharactorStack, statement[i]);}else if (p == 0){//Push(&DigitStack, Caculator(Pop(&DigitStack), Pop(&DigitStack), Pop(&CharactorStack)));Pop(&CharactorStack);i++;}else if (p == -1){Push(&CharactorStack, statement[i]);i++;}}}if (IsEmpty(&CharactorStack))return Pop(&DigitStack);while (!IsEmpty(&CharactorStack))Push(&DigitStack, Caculator(Pop(&DigitStack), Pop(&DigitStack), Pop(&CharactorStack)));return Pop(&DigitStack);return result;
}// <------------------------BigInteger------------------------------------------>
#define Max_Biginteger_length 100000
static char result_temp[Max_Biginteger_length];static void BigIntegerResultReverse(char result[]);static void BigIntegerAdd(char a[], char b[], char result[]);static void BigIntegerSub(char a[], char b[], char result[]);static void BigIntegerMulti(char a[], char b[], char result[]);//static void BigIntegerdevi(char a[], char b[], char result[]);typedef struct BigIntegerStack
{char *p[5000];char **top = p;int stackLength = 5000;int CurLength = 0;
} BigIntegerStack;static void B_Pop(BigIntegerStack *big_integer_stack, char p[])
{if (big_integer_stack->top == big_integer_stack->p){printf("something warning\n");exit(0);}elsestrcpy(p, *--big_integer_stack->top);big_integer_stack->CurLength--;
}static void B_Push(BigIntegerStack *big_integer_stack, char p[])
{int len = strlen(p);if (*big_integer_stack->top != NULL)free(*big_integer_stack->top);*big_integer_stack->top = (char *)malloc(sizeof(char) * (len + 1));strcpy(*big_integer_stack->top++, p);big_integer_stack->CurLength++;
}static void BigIntegerResultReverse(char result[])
{int start = 0, end = strlen(result) - 1;char temp;for (; start < end; start++, end--) {temp = result[start];result[start] = result[end];result[end] = temp;}//reverse the result array
}static void BigIntegerAdd(char a[], char b[], char result[])
{int lena = strlen(a) - 1;int lenb = strlen(b) - 1;int t = 0, i = 0;while (lena >= 0 && lenb >= 0) {result[i] = a[lena] + b[lenb] - 2 * '0' + t;t = result[i] / 10;result[i] = result[i] % 10 + '0';i++; lena--; lenb--;}while (lena >= 0) {result[i] = a[lena] + t - '0';t = result[i] / 10;result[i] = result[i] % 10 + '0';i++; lena--;}while (lenb >= 0) {result[i] = b[lenb] + t - '0';t = result[i] / 10;result[i] = result[i] % 10 + '0';i++; lenb--;}if (t)result[i++] = t + '0';result[i] = '\0';BigIntegerResultReverse(result);
}static void BigIntegerSub(char a[], char b[], char result[])
{int lena = strlen(a) - 1;int lenb = strlen(b) - 1;int t = 0, i = 0, flag = 0;if (lena < lenb || (lena == lenb && strcmp(a, b) < 0)) {char *p = b; b = a; a = p;lena ^= lenb;lenb ^= lena;lena ^= lenb;flag = 1;}while (lena >= 0 && lenb >= 0) {result[i] = a[lena] - b[lenb] + '0' + t;if (result[i] < '0') {result[i] += 10;t = -1;}else t = 0;i++; lena--; lenb--;}while (lena >= 0) {result[i] = a[lena--] + t;if (result[i] < '0') {result[i] += 10;t = -1;}else t = 0;i++;}if (flag)result[i++] = '-';result[i] = '\0';BigIntegerResultReverse(result);
}static void BigIntegerMulti(char a[], char b[], char result[])
{memset(result, '0', 1000);int lena = strlen(a) - 1;int lenb = strlen(b) - 1;int k = lenb, j = lena, t = 0, temp;while (k >= 0) {for (j = lena; j >= 0; j--) {temp = (b[k] - '0')*(a[j] - '0') + t + result[lenb - k + lena - j] - '0';result[lenb - k + lena - j] = temp % 10 + '0';t = temp / 10;}if (k == 0)break;if (t) {result[lenb - k + lena + 1] = t + '0';t = 0;}k--;}if (t) {result[lena + lenb + 1] = t + '0';result[lena + lenb + 2] = '\0';}else result[lena + lenb + 1] = '\0';BigIntegerResultReverse(result);
}static char *B_Caculator(char a[], char b[], char method, char result[])//method参数为计算方法(+、-、*),通过对不同计算方法调用不同的大整数运算函数,同时对运算做一些预处理(比如两个负数相加就相当于两个正数相加,最后在所得的结果前面加上负号)
{//char result[100000];switch (method){case '+':if (a[0] == b[0] && a[0] == '-') {BigIntegerAdd(&a[1], &b[1], result);BigIntegerResultReverse(result);result[strlen(result) + 1] = '\0';result[strlen(result)] = '-';BigIntegerResultReverse(result);}else if (a[0] == '-'&&b[0] != '-')BigIntegerSub(b, &a[1], result);else if (b[0] == '-'&&a[0] != '-')BigIntegerSub(a, &b[1], result);else BigIntegerAdd(a, b, result);break;case '-':if (a[0] == b[0] && a[0] == '-')BigIntegerSub(&b[1], &a[1], result);else if (a[0] == '-'&&b[0] != '-') {BigIntegerAdd(&a[1], b, result);BigIntegerResultReverse(result);result[strlen(result) + 1] = '\0';result[strlen(result)] = '-';BigIntegerResultReverse(result);}else if (b[0] == '-'&&a[0] != '-')BigIntegerAdd(a, &b[1], result);else BigIntegerSub(a, b, result);break;case '*':if (a[0] == b[0] && a[0] == '-')BigIntegerMulti(&a[1], &b[1], result);else if (a[0] == '-' || b[0] == '-') {if (a[0] == '-')BigIntegerMulti(&a[1], b, result);else BigIntegerMulti(a, &b[1], result);BigIntegerResultReverse(result);result[strlen(result) + 1] = '\0';result[strlen(result)] = '-';BigIntegerResultReverse(result);}else BigIntegerMulti(a, b, result);break;default:printf("--> unknown error(maby you input a unkonw charactor\n)");break;}return result;
}void BigIntegerCompulation(char statement[], char result_buff[])
{CharactorInit();int p, x, result = 0;int statementLength = strlen(statement);BigIntegerStack big_integer_stack;CompulationStack CharactorStack;memset(big_integer_stack.p, NULL, 5000);char temp[100000], temp_result[100000];for (int i = 0, j; i < statementLength;){j = JudgeCharactor(statement[i]);if (!j)continue;if (j == 8){int k = i, temp_index = 0;while (JudgeCharactor(statement[i]) == 8)//copy the next numbertemp[temp_index++] = statement[i++];temp[temp_index] = '\0';B_Push(&big_integer_stack, temp);}else{p = PriorityJudge(GetTop(&CharactorStack, &x), statement[i]);if (p == 1){char a[100000], b[100000];B_Pop(&big_integer_stack, b);//notice:pop b first,you subtract a subtrahend from a minuendB_Pop(&big_integer_stack, a);//a is minuend,b is subtrahendB_Push(&big_integer_stack, B_Caculator(a, b, Pop(&CharactorStack), temp_result));}else if (p == 0){//Push(&DigitStack, Caculator(Pop(&DigitStack), Pop(&DigitStack), Pop(&CharactorStack)));Pop(&CharactorStack);i++;}else if (p == -1){Push(&CharactorStack, statement[i]);i++;}}}if (IsEmpty(&CharactorStack))B_Pop(&big_integer_stack, result_buff);else{while (!IsEmpty(&CharactorStack)){char a[100000], b[100000];B_Pop(&big_integer_stack, b);B_Pop(&big_integer_stack, a);B_Push(&big_integer_stack, B_Caculator(a, b, Pop(&CharactorStack), temp_result));}B_Pop(&big_integer_stack, result_buff);}//BigIntegerResultReverse(result_buff);if (result_buff[0] == '0')result_buff[1] = '\0';//if the result is equal to 0
}int main() {char statement[50000], result[2000];gets_s(statement);if (statement[0] == 'L') {BigIntegerCompulation(&statement[1], result);printf("%s\n", result);}else printf("%d\n", Compulation(statement));return 0;
}

表达式运算(包含大整数加减乘)相关推荐

  1. c语言任意两个整数相减_大整数加减运算的C语言实现

    大整数加减运算的 C 语言实现 一 . 问题提出培训老师给出一个题目:用 C 语言实现一 个大整数计算器.初步要求支持大整数的加.减运算,例如 8888888888888+1112=888888889 ...

  2. Python练习:整数加减和

    描述 编写程序计算如下数列的值: 1-2+3-4...966 其中,所有数字为整数,从1开始递增,奇数为正,偶数为负 输入格式 该题目没有输入. 输入输出示例   输入 输出 示例 1 无 111(仅 ...

  3. 大整数运算之 大整数加法、减法、乘法

    其实大整数的问题都是在像我们打草稿的时候列竖式一样的,不要告诉我你不知道什么叫竖式~!其实我开始也不知道它叫这个名字: 所谓竖式,就是你打草稿算算术的方法,小学知识:比如你写 11+9: 11 +   ...

  4. 整数加减运算的二进制表示

    两位整数的加减都可看做 一个数加上另一个数,首先我们要把数据的二进制表示转化成补码,因为在计算机内部,数据的加减是按补码进行运算的. A补+B补=(A+B)补(mod 2^n+1) 连同符号位相加,符 ...

  5. 表达式求值:从“加减”到“带括号的加减乘除”的实践过程

    本文乃Siliphen原创,转载请注明出处:http://blog.csdn.NET/stevenkylelee ● 为什么想做一个表达式求值的程序 最近有一个需求,策划想设置游戏关卡的某些数值,这个 ...

  6. java大整数类减1,自己写Java大整数《1》表示和加减

    自己写Java大整数<一>表示和加减 上周粗略计划自己写Java下的大整数运算. 后来仔细想想其实自己动手写大整数运算有1好2不好.2个不好分别是: 1,肯定没有Java内置的BigInt ...

  7. 计组之数据运算:5、加减运算与溢出判断

    5.加减运算与溢出判断 思维导图 原码的加减运算 补码的加减运算 溢出判断 1.采用一位符号位直接判断 2.采用一位符号位用进位判断 3.采用双符号位判断 符号扩展 思维导图 原码的加减运算 补码的加 ...

  8. java 整数加减_Java计算长整数加减(字符串表示)

    1 /** 2 * Created by areful on 2019/11/133 */ 4 public classCalcStringNumber {5 private static final ...

  9. 常见的几种求模运算(mod)——加减乘、除的小费马定理、指数的欧拉降幂

    在C/C++中,+,-的优先级低于/,*,%,而/,*,%优先级一样,所以就从左到右 1.乘法 我们在做题的时候,遇到(a*b)%c,由于可能a*b先计算的话,会超精度,所以我们可以这么转化 (a*b ...

最新文章

  1. 我们已经不用AOP做操作日志了!
  2. 微生物群落来自哪里,我们说了算-FEAST or SourceTracker
  3. 利用 Arthas 解决启动 StandbyNameNode 加载 EditLog 慢的问题
  4. Python: 大型数组运算
  5. golang变量定义细节及beego环境搭建细节记录
  6. rust go java 性能_Java,Go和Rust之间的比较 - Dexter
  7. Java中的访问者设计模式–示例教程
  8. excel和python建模_利用Excel学习Python:准备篇
  9. Oracle传输表空间介绍
  10. STM32利用光敏二极管实现光度测量
  11. python 绘制二维曲面_用python绘制曲面[复制]
  12. 计算机通讯端口怎么增加,plc通讯接口如何添加删除方法
  13. BZOJ 3097 Hash Killer I
  14. 研究生如何写好毕业论文?(上)【中国人民大学龚新奇】
  15. 农用化学活性成分的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  16. 当系统logoff或shutdown时,让应用程序正常关闭
  17. 计算机打字键盘怎么控制,键盘不受控制怎么办?
  18. Camera摄像头模组硬件
  19. java获取Ip工具类
  20. 怎样提高团队管理能力3

热门文章

  1. 极端类别不平衡数据下的分类问题研究综述,终于有人讲全了!
  2. android bks证书生成方式
  3. msm8916 lcd 相关调试点指导
  4. 吉他入门乐理知识精髓篇
  5. Impala: Reducing query concurrency or configuring admission control may help avoid this error
  6. SQL server Date函数之CONVERT()函数
  7. python合并多个pdf_python使用PyPDF2把多个pdf文件合并成一个
  8. H5案例分享—你的数学是语文老师教的吗?
  9. fly.js 的二次封装
  10. Android 10 手机端控制车载蓝牙音乐上一首、暂停、下一首、获取音乐信息等流程