1 概述
开发编译环境为Visual Studio 2017,此外,本文还提供Linux系统中的实现
2 代码
Calculator.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include "Stack_calculator.h"
//操作符判断
int is_operation(char ch)
{
int f = 0;
switch (ch)
{
case '+':
case '-':
case '*':
case '/':
f = 1;
break;
default:
f = 0;
break;
}
return f;
}
//优先级
int priority(char ch)
{
int f = -1;
switch (ch)
{
case '#':
f = -1;
break;
case '(':
case ')':
f = 0;
break;
case '+':
case '-':
f = 1;
break;
case '*':
case '/':
f = 2;
break;
default:
break;
}
return f;
}
//表达式转换
void post_to_fix(const char *src, char *dest)
{
sequence_stack opt;
sequence_stack *p = &opt;
int i = 0;
int j = 0;
init(p); //初始化栈
push(p, '#');
while (src[i] != '#')
{
if (src[i] >= '0'&&src[i] <= '9')
{
while ((src[i] >= '0'&&src[i] <= '9') || src[i] == '.')
dest[j++] = src[i++];
}
else if (is_operation(src[i]))
{
dest[j++] = ' ';
while (priority(src[i]) <= priority(read(p)))
{
dest[j++] = read(p);
pop(p);
}
push(p, src[i]);
i++;
}
else if (src[i] == '(')
push(p, src[i++]);
else if (src[i] == ')')
{
while (read(p) != '(')
{
dest[j++] = read(p);
pop(p);
}
if (read(p) == '(')
pop(p);
i++;
}
}
while (empty(p) != 1)
{
dest[j++] = read(p);
pop(p);
}
dest[j] = '\0';
}
//读后缀表达式
double read_number(char *dest, int *i)
{
double x = 0;
int num = 0;
int j;
while (dest[*i]<'0' || dest[*i]>'9') (*i)++;
while (dest[*i] >= '0'&&dest[*i] <= '9')
{
x = x * 10 + (dest[*i] - '0');
(*i)++;
}
if (dest[*i] == '.')
{
(*i)++;
while (dest[*i] >= '0'&&dest[*i] <= '9')
{
num++;
x = x * 10 + (dest[*i] - '0');
(*i)++;
}
}
for (j = 0; j<num; j++)
x = x / 10;
return x;
}
//计算后缀表达式
double calculate_answer(char *dest)
{
double xs[50];
int len = 0;
int i = 0;
while (dest[i] != '#')
{
if (dest[i] >= '0'&&dest[i] <= '9')
xs[len++] = read_number(dest, &i);
else if (is_operation(dest[i]))
{
switch (dest[i])
{
case '+':
xs[len - 2] = xs[len - 2] + xs[len - 1];
len--;
i++;
break;
case '-':
xs[len - 2] = xs[len - 2] - xs[len - 1];
len--;
i++;
break;
case '*':
xs[len - 2] = xs[len - 2] * xs[len - 1];
len--;
i++;
break;
case '/':
xs[len - 2] = xs[len - 2] / xs[len - 1];
len--;
i++;
break;
}
}
else i++;
}
return xs[len - 1];
}
//检测表达式
void match(const char *src)
{
int i = 0;
sequence_stack stack;
sequence_stack *p = &stack;
init(p);
while (src[i] != '#')
{
//检测字符合法
if ((is_operation(src[i]) != 1 && src[i] != '('&&src[i] != ')' &&src[i] != '.') && (src[i]<'0' || src[i]>'9'))
{
printf("输入错误!!");
exit(1);
}
switch (src[i])
{
case '(':
push(p, src[i]);
break;
case ')':
if (is_operation(src[i - 1]) || src[i - 1] == '(')
{
printf("括号输入有误!");
exit(1);
}
if (read(p) == '(')
pop(p);
else
{
printf("括号输入有误!");
exit(1);
}
break;
case '+':
case '-':
case '*':
case '/':
if (src[i - 1] == '(' || is_operation(src[i - 1]))
{
printf("运算符输入问题!");
exit(1);
}
break;
default:break;
}
i++;
}
}
double expr(const char* src)
{
char dest[MAX];//后缀表达式
char src_[MAX];
double n = 0;
int length = strlen(src);
strcpy_s(src_,strlen(src)+1,src);
src_[length] = '#';
src_[length+1] = '\0';
match(src_);
post_to_fix(src_, dest);
n = calculate_answer(dest);
return n;
}
//int main()
//{
// assert(expr("1") == 1);
// assert(expr("1+2") == 3);
// assert(expr("3-2") == 1);
// assert(expr("1+2+3") == 6);
// assert(expr("1+2-3") == 0);
// assert(expr("(1+2)-3") == 0);
// assert(expr("3-2-1") == 0);
// assert(expr("1+3*2-(1+1+2)/4") == 6);
// assert(expr("4+(1+1)*4-10/2") == 7);
// assert(expr("10-(2+1+7)/2+(2-1+3)*2") == 13);
//
// return 0;
//}
int main()
{
char src[MAX] = "1+3*2-(1+1+2)/4";
char src1[MAX] = "4+(1+1)*4-10/2";
char src2[MAX] = "10-(2+1+7)/2+(2-1+3)*2";
double n = 0, n1 = 0, n2 = 0;
n = expr(src);
n1 = expr(src1);
n2 = expr(src2);
printf("中缀表达式: %s\n", src);
printf("answer = %.2f\n", n);
printf("中缀表达式: %s\n", src1);
printf("answer = %.2f\n", n1);
printf("中缀表达式: %s\n", src2);
printf("answer = %.2f\n", n2);
return 0;
}
Stack_calculator.c
#include "Stack_calculator.h"
//栈初始化
void init(sequence_stack *s)
{
s->size = 0;
}
//空栈
int empty(sequence_stack *s)
{
return s->size ? 0 : 1;
}
//读栈顶
datatype read(sequence_stack *s)
{
if (empty(s))
{
printf("read函数错误, 为空栈!!");
exit(1);
}
return s->a[s->size - 1];
}
//出栈
void pop(sequence_stack *s)
{
if (empty(s))
{
printf("pop函数错误, 为空栈!!");
exit(1);
}
s->size--;
}
//入栈
void push(sequence_stack *s, datatype d)
{
if (s->size == MAX)
{
printf("push函数错误, 栈已满!!");
exit(1);
}
s->a[s->size++] = d;
}
Stack_calculator.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef char datatype;
typedef struct
{
datatype a[MAX];
int size;
}sequence_stack; //Υ»½αΉΉΜε
void init(sequence_stack *);
int empty(sequence_stack *);
void pop(sequence_stack *);
void push(sequence_stack *, datatype);
datatype read(sequence_stack *s);
3 工程压缩包
VS解决方案
https://download.csdn.net/download/yuyehui/11716286
linux系统解决方案
https://download.csdn.net/download/yuyehui/11716307
csdn提供的下载需要积分,如果不想花积分,请留言
4 参考
https://blog.csdn.net/native_lee/article/details/52452948