闲着无聊打开了软基的课本 看见了后缀表达式 就没事写了个计算器玩玩 大神勿喷
我还是先说一下算法的原理吧
此计算机器只适用于正数之间的 加减乘除计算
新增功能:
1.新增加了小数的计算
2.提升了计算的稳定性
3.新增计算运行时间
4.可输入大于9的操作数
暂不支持有关的负数运算
版本号1.02
#include
#include
#define MAXSIZE 100
#define MAXSIZEOFDATA 10
#define IsSymbol 0
#define IsData 1
using namespace std;
typedef float typedata;
typedef struct
{
char top;
typedata data[MAXSIZE][2];
//data[x][0] 记录的是数据
//data[x][1] 记录的是数据类型 数据或者操作符
}stack;
char StackIsEmpty(stack &st)
{
if (st.top == -1)
return 1;
return 0;
}
void StackInit(stack &st)
{
st.top = -1;
}
void StackPush(stack &st, typedata dat,char symbol )
{
st.top++;
st.data[st.top][0] = dat;
st.data[st.top][1] = symbol;
}
typedata StackPop(stack &st)
{
if (StackIsEmpty(st)==0)
{
--st.top;
return st.data[st.top + 1][0];
}
return -1;
}
float PowFloat(int y)
{
if (y == 0)
return 1;
return 0.1*PowFloat(--y);
}
typedata StringToData(char *dat, int count)
{
char i,j;
typedata sum;
sum = 0;
if (count == 0)
return 0;
//遍历找到小数点的位置 位置记录为i
for (i = 0; i < count; i++)
{
if (dat[i] == '.')
break;
}
//没有小数点
if (count == i)
{
for (i = 0; i < count;i++)
{
sum = sum * 10;
sum = sum + dat[i] - '0';
}
return sum;
}
//有小数点
if (i < count)
{
//计算整数部分
for (j = 0; j < i; j++)
{
sum = sum * 10;
sum = sum + dat[j] - '0';
}
//计算小数部分
for (++j; j < count; j++)
{
sum = sum + (dat[j]-'0') * PowFloat( j-i);
}
return sum;
}
return -1;
}
void ConvertionSuffixExpression(char *str, stack &st)
{
char count,flag;
char dat[MAXSIZEOFDATA];
stack buffer;
typedata sum;
flag = 0;
StackInit(buffer);
while (*str != '\0'||*str=='\n')
{
count = 0;
//检测含字符串 是否有可能是计算数据
while ( (*str) <= '9' &&(*str) >= '0'||*str=='.')
{
//防止野指针的产生
if (*str == '\0' || *str == '\n')
{
//标志位 字符串使用已经结束
flag = 1;
break;
}
dat[count++] = *str;
str++;
}
//获数字
if (count)
{
sum = StringToData(dat, count);
StackPush(st, sum, IsData);
}
//标志位 字符串使用已经结束
if (flag==1||*str=='\0')
break;
//左括号直接进栈
if (*str == '(')
StackPush(buffer, *str, IsSymbol);
else if (*str==')')//右括号直接退栈 直至遇到左括号
{
StackPush(buffer, *str, IsSymbol);
do
{
StackPush(st, StackPop(buffer),IsSymbol);
} while (buffer.data[buffer.top][0] != '(');
} //遇到了加减运算
else if (*str == '+' || *str == '-')
{
if (StackIsEmpty(buffer)==1)
StackPush(buffer, *str,IsSymbol);
else if (buffer.data[buffer.top][0] == '+' || buffer.data[buffer.top][0] == '-')
{
StackPush(buffer, *str, IsSymbol);
}
else if (buffer.data[buffer.top][0] == '/' || buffer.data[buffer.top][0] == '*')
{
StackPush(st, StackPop(buffer), IsSymbol);
StackPush(buffer, *str,IsSymbol);
}
else //栈顶元素为括号
{
StackPush(buffer, *str,IsSymbol);
}
}
else //遇到了乘除运算
{
if (StackIsEmpty(buffer)==1)
StackPush(buffer, *str, IsSymbol);
else if (buffer.data[buffer.top][0] == '+' || buffer.data[buffer.top][0] == '-')
{
StackPush(buffer, *str, IsSymbol);
}
else if (buffer.data[buffer.top][0] == '/' || buffer.data[buffer.top][0] == '*')
{
StackPush(st, StackPop(buffer), IsSymbol);
StackPush(buffer, *str, IsSymbol);
}
else //栈顶元素为括号
{
StackPush(buffer, *str, IsSymbol);
}
}
str++;
}
while (StackIsEmpty(buffer)==0)
{
count = StackPop(buffer);
StackPush(st,count, IsSymbol);
}
}
void SmartCounter(char *str)
{
typedata countleft, countright,count;
stack dat, counter, draft;
StackInit(dat);
StackInit(counter);
StackInit(draft);
ConvertionSuffixExpression(str, draft);
//由于draft中 后缀表达式是反的 因此需要将顺序颠倒一下
while (StackIsEmpty(draft)==0)
{
StackPush(dat, StackPop(draft),draft.data[draft.top][1]);
}
//开始正式的计算过程
while (StackIsEmpty(dat)==0)
{
count = StackPop(dat);
//直接判断是不是计算数据
if (dat.data[dat.top+1][1]==IsData)
{
StackPush(counter, count,IsData);
}//不是数据那么就是运算符了
else if (count == '+' || count == '-' || count == '*' || count == '/')
{
countright = StackPop(counter) ;
countleft = StackPop(counter);
if (count == '+')
{
count = countleft + countright;
StackPush(counter, count,IsData);
}
else if (count == '-')
{
count = countleft - countright ;
StackPush(counter, count, IsData);
}
else if (count == '*')
{
count = countleft * countright;
StackPush(counter, count, IsData);
}
else if (count == '/')
{
count = countleft / countright;
StackPush(counter, count, IsData);
}
}
else{}
}
while (StackIsEmpty(counter)==0)
{
cout << "您输入的算术表达式为: \n"<
}
}
void main()
{
char str[MAXSIZE];
DWORD t1, t2;
t1 = GetTickCount();
cout << "请输入计算式" << endl;
cin >> str;
SmartCounter(str);
t2 = GetTickCount();
cout << "本次计算用时:"<<(double)t2-t1<<"ms" << endl;
}