提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本人代码小白一个,在学校期间进行课程设计,网上资源繁多,但精品甚少,本着人人为我,我为人人的想法,把我以前完成过的课程设计发出来供大家参考。
一、项目背景
设计一个计算器,该计算器主要是用来进行数学计算,用过输入的数据进行运算,得出我们所需要的计算结果。采用的是栈的基本操作,通过栈实现先乘除后加减,括号优先的原则,得到用户所需要的结果,满足更多人的需求,增加计算器的可实用性。
二、项目功能
- 计算器可以进行基本运算
- 可以自动判断加减乘除优先级
- 可超大数据计算
- 可以判断用户的错误输入并且进行限制 提示,比如:输入的左右括号不匹配,除数为零,输入非法字符时,都会有相应的提示。
三、代码实现
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#include<iostream>
#include<cstdlib>
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define MAXSIZE 100
using namespace std;
typedef int Status;
typedef struct StackNode
{
int data;
struct StackNode *next;
int stacksize;//栈可用的最大容量
} StackNode,*LinkStack;
StackNode *p;
LinkStack OPND;
LinkStack OPTR;
LinkStack S;
char str[100];
//栈的初始化
Status InitStack (LinkStack &S)
{
S=NULL;
return OK;
}
//判断是否为空栈
bool StackEmpty(LinkStack S)
{
if (!S)
return true;
return false;
}
//入栈
Status Push(LinkStack &S,int e)
{
//在栈顶插入元素e
p=new StackNode;//生成新的节点
p->data=e;//将新数据域置为e
p->next=S;//将新的元素插入栈顶
S=p;//修改栈顶指针为p
return OK;
}
//出栈
int Pop(LinkStack &S,int e)
{
//删除S栈顶元素,用e返回其值
if(S==NULL)
return ERROR;//栈空
e=S->data;//将栈顶元素赋值给e
p=S;//用p临时保存栈顶空间,以被释放
S=S->next;//修改栈顶指针
delete p;//释放原栈顶元素的空间
return e;
}
//取栈顶元素
int GetTop(LinkStack S)
{
//返回S的栈顶元素,不修改栈顶指针
if(S!=NULL) //栈非空
return S->data;//返回栈顶元素的值,栈顶指针不变
}
//字符的判断
int ln(char ch)
{
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='#')
return 1;
else if(ch>='0'&&ch<='9')
return 0;
else
return -1;
}
char Precede(char theta1, char theta2) //判断运算符优先级
{
if ((theta1 == '(' && theta2 == ')') || (theta1 == '#' && theta2 == '#'))
{
return '=';
}
else if (theta1 == '(' || theta1 == '#' || theta2 == '(' || (theta1
== '+' || theta1 == '-') && (theta2 == '*' || theta2 == '/'))
{
return '<';
}
else
return '>';
}
//对两个数进行运算
int Operate(int a,char c,int b)
{
int t;
switch(c)
{
case '+':
t=a+b;
break;
case '-':
t=a-b;
break;
case '*':
t=a*b;
break;
case '/':
if(b==0)
{
printf("除数不能为零!\n");
return 0;
}
else
{
t=a/b;
break;
}
}
return t; //返回计算结果
}
int conversion(int N) //对于任意一个非负十进制数,打印输出与其等值的八进制数
{
int e;
InitStack(S); //初始化空栈S
while (N) //当N非零时,循环
{
Push(S, N % 8); //把N与8求余得到的八进制数压入栈S
N = N / 8; //N更新为N与8的商
}
while (!StackEmpty(S)) //当栈S非空时,循环
{
e=Pop(S, e); //弹出栈顶元素e
cout << e; //输出e
}
return N;
}
int Matching()
{
//检验表达式中所含括号是否正确匹配,如果匹配,则返回true,否则返回false
//表达式以“=”结束
char ch;
int i=0;
int x;
InitStack(S);//初始化空栈
int flag=2;//标记匹配结果以控制循环及返回结果
gets(str); //读入第一个字符
while(str[i]!='#'&&flag)//假设表达式以“#”结尾
{
ch=str[i];
switch(ch)
{
case '(': //若是左括号,则将其压入栈
Push(S,ch);
flag=1;
break;
case ')': //若是“)”,则根据当前栈顶元素的值分情况考虑
if(!StackEmpty(S)&&GetTop(S)=='(')
{
Pop(S,x);//若栈非空且栈顶元素是“(”,则正确匹配
flag=1;
}
else
flag=0; //若栈空或栈顶元素不是“(”,则错误匹配
break;
} //switch
i++; //继续读入下一个字符
} //while
if (StackEmpty(S)&&flag==1)
return 1;
else if(!StackEmpty(S)&&(flag==0||flag==1))
return 0;
else
return 2;
}
int EvaluateExpression()
{
//算术表达式求值的算法优先算法,设OPTR和OPEN分别为运算符站和操作数栈
InitStack(OPND);//初始化open栈
InitStack(OPTR);//初始化OPTR栈
Push(OPTR,'#');//将表达式起始符“#”压入OPTR栈底
char ch,theta,x;
int a,b,t,i=0;
string T="";
while(str[i]!='#' || GetTop(OPTR)!='#')//将表达式没有扫描完成的OPTR的栈顶元素不为“#”
{
if(ln(str[i])==0)
{
//ch不是运算符则进OPND栈并读取下一个字符
T+=str[i];
//cout<<"T+"<<str[i]<<endl;
i++;
}
else if(ln(str[i])==1)
{
int res=0;
for(int j=0; j<T.length(); j++)
{
res=res*10+T[j]-'0';
}
//cout<<res<<endl;
if(res||(T[0]=='0'&&T.length()==1))
Push(OPND,res);
T.clear();
switch(Precede(GetTop(OPTR),str[i]))
{
case'<':
{
Push(OPTR,str[i]);//当前字符ch压入OPTR栈,读入下一个字符
i++;
break;
}
case'>':
{
theta=Pop(OPTR,x);//弹出OPTR栈顶的运算符
a=Pop(OPND,x);//弹出OPND栈顶的两个运算数
b=Pop(OPND,x);
//cout<<b<<(char)theta<<a<<endl;
Push(OPND,Operate(b,theta,a));//将运算结果压入OPND栈
break;
}
case'='://OPTR的栈顶元素是“(”且ch是“)”
{
Pop(OPTR,x);//弹出OPTR栈顶的“(”,读入下一个字符ch
i++;
break;
}
}
}
else if(ln(str[i])==-1)
{
printf("输入了非法字符!");
return -1;
}
}
printf("计算结果为:%d",GetTop(OPND));//因为OPND里的数据为字符型,则再将其转化为整型
}
int menu()
{
int c;
cout << "1.(整数)多项式计算" << endl;
cout << "2.十进制转换为八进制计算" << endl;
cout << "0.退出\n" << endl;
cout << "选择:";
cin >> c;
getchar();
return c;
}
main()
{
printf("*****************************\n");
printf("*----------逆波兰-----------*\n");
printf("# 式 #\n");
printf("*----------计算器-----------*\n");
printf("*****************************\n");
while(1)
{
switch(menu())
{
case 1:
{
printf("请输入要计算的表达式:(以#结束)\n");
int flag = (int) Matching();
if (flag==1)
{
cout << "括号匹配成功!" << endl;
EvaluateExpression();
cout <<endl <<endl;
}
else if(flag==0)
{
cout << "括号匹配失败!" << endl<< endl;
}
else
{
EvaluateExpression();
cout <<endl <<endl;
}
}
break;
case 2:
{
int n;
cout << "输入一个非负十进制数:" << endl;
cin >> n;
conversion(n);
cout <<endl <<endl;
}
break;
case 0:
cout << "退出成功\n" << endl;
exit(0);
default:
break;
}
}
}
总结
代码如上,如果能有所帮助,可以点个赞支持一下,谢谢。