?? main.cpp
字號:
#include<iostream>
#include<math.h>
#include <string>
#include <cstdlib>
#include<ctype.h>
using namespace std;
const int SIZE=20;
template <class T> class Queue;
template <class T> class SeqQueue;
enum ResultCode{Underflow,Overflow,Success,Duplicate,NotPresent,Inputwrong};
bool IsNumber(const char *s){
bool Numberdoor=0,Indexdoor=0,NePositivedoor=0;
bool Decimaldoor=0;
int i=0;
char c;
while(*(s+i)!='\0'){
c=*(s+i);
if(isdigit(c)) {
Numberdoor=1;
NePositivedoor=1;
}
else if(c=='.'){
if(Decimaldoor==1) return false;
Numberdoor=0;
Decimaldoor=1;
}
else if(c=='+'||c=='-'){
if(NePositivedoor==1) return false;
if(Numberdoor==1) return false;
NePositivedoor=1;
Numberdoor=0;
}
else if(c=='e'||c=='E'){
if(Indexdoor==1) return false;
if(Numberdoor==0) return false;
Indexdoor=1;
Numberdoor=0;
NePositivedoor=0;
Decimaldoor=1;
}
else return false;
i++;
}
if(Numberdoor==0) return false;
return true;
}
int icp(const char *c)
{ // 計算運算符c的棧外優先級
int priority;
switch(c[0]){
case '(': priority=8; break;
case ')': priority=1;break;
case '+':
case '-': priority=2; break;
case '*':
case '/': priority=4; break;
case '^': priority=6; break;
case '#': priority=0; break;
}
return priority;
}
int isp(const char *c)
{ // 計算運算符c的棧內優先級
int priority;
switch(c[0]){
case '(': priority=1; break;
case ')': priority=8; break;
case '+':
case '-': priority=3; break;
case '*':
case '/': priority=5; break;
case '^': priority=7; break;
case '#': priority=0; break;
}
return priority;
}
bool OperateSymbol(const char *c){
switch(*c){
case '+':
case '-':
case '*':
case '^':
case '(':
case '/':
return true;
default: return false;
}
}
template <class T>
class Queue
{
public:
virtual bool IsEmpty() const=0;
virtual bool IsFull() const=0;
virtual bool Front(T &x) const =0;
virtual bool EnQueue(T x) =0;
virtual bool DeQueue()=0;
virtual bool Clear() =0;
};
template <class T>
class SeqQueue:public Queue<T>
{
private:
int front, rear;
int maxSize;
T *q;
public:
SeqQueue(int mSize);
~SeqQueue(){delete []q;}//釋放內還
bool IsEmpty() const{return front==rear;}
bool IsFull() const {return (rear+1)% maxSize==front;}
bool Front(T &x) const;
bool EnQueue(T x);
bool DeQueue();
bool Clear() {front=rear=0; return true;}
void ListAll();
T IDfind(int i);
};
void InfixToPostfix(SeqQueue<string> &suffix0);
template <class T>
SeqQueue<T>::SeqQueue(int mSize){
maxSize=mSize;
q=new T[maxSize];
front=rear=0;
}
template <class T>
bool SeqQueue<T>::Front (T &x) const{
if (IsEmpty()){
cout<<"empty"<<endl; return false;//空隊列處理
}
x=q[(front+1)%maxSize];
return true;
}
template <class T>
bool SeqQueue<T>::EnQueue (T x){
if (IsFull()){//溢出處理
cout<<"隊滿"<<endl; return false;
}
q[(rear=(rear+1)%maxSize)]=x;
return true;
}
template <class T>
bool SeqQueue<T>::DeQueue (){
if(IsEmpty()){//空隊列處理
cout<<"隊列下溢"<<endl; return false;
}
front=(front+1)%maxSize;
return true;
}
template <class T>
void SeqQueue<T>::ListAll (){//輸出隊列里的所有元素
int temp;
int number=0;
temp=front;
if(front==rear) {cout<<"隊列無數據 !"<<endl;return;}
do{ cout<<q[temp+1]<<' ';
temp=(temp+1)%maxSize;
}while(rear!=temp+1);
}
template <class T>
T SeqQueue<T>::IDfind(int i){//根據在隊列里的序號找出相應元素
int number=front;
if(i==0) return q[front+1];
number=(number+1+i)%maxSize;
return q[number];
}
//將中綴表達式轉化為后綴表達式
template <class T>
class stack
{ public:
virtual bool IsEmpty() const=0;
virtual bool IsFull() const=0;
virtual bool Top(T &x) const=0;
virtual bool Push(T x)=0;
virtual bool Pop()=0;
virtual void Clear()=0;
};
template <class T>
class seqstack:public stack<T>
{
public:
seqstack(int mSize);
~seqstack(){delete []s;}
bool IsEmpty() const {return top==-1;}
bool IsFull() const {return top==maxTop;}
bool Top(T &x) const;//取出棧頂元素
bool Push(T x);//壓入棧
void Clear(){top=-1;}//清空棧
bool Pop();//彈出棧
private:
int top;//棧頂指針
int maxTop;//最大棧頂指針
T *s;
};
template <class T>
seqstack<T>::seqstack(int mSize)//初始化棧
{
maxTop=mSize-1;
s=new T[mSize];
top=-1;
}
template <class T>
bool seqstack<T>::Top(T &x) const
{
if(IsEmpty()){
cout<<"棧空"<<endl;return false;
}
x=s[top];return true;
}
template <class T>
bool seqstack<T>::Push(T x)
{
if(IsFull()){
cout<<"棧上溢"<<endl;return false;
}
s[++top]=x;return true;
}
template <class T>
bool seqstack<T>::Pop()
{
if(IsEmpty()){
cout<<"棧下溢"<<endl;return false;
}
top--;return true;
}
//定義計算器類
class Calculator
{
public:
Calculator(int maxSize):s(maxSize),suffix(maxSize) {};
void Run();//從隊列逐個讀入字符,做相應的運算,輸出結果
void Clear(){s.Clear();suffix.Clear();}
private:
SeqQueue<string> suffix;//存放轉換后得到的后綴表達式隊列對象
seqstack <double> s;//聲明存放操作數的棧對象
void PushOperand(double);//操作數進棧
bool GetOperands(double &,double &);//從棧中彈出2個操作數
bool DoOperator(const char *per);
};
void Calculator::PushOperand(double op)
{
s.Push(op);
}
bool Calculator::GetOperands(double &op1,double &op2)
{
if(!s.Top(op1)){
cerr<<"操作符多余"<<endl;return false;
}
s.Pop();
if(!s.Top(op2)){
cerr<<"操作符多余"<<endl;return false;
}
s.Pop(); return true;
}
bool Calculator::DoOperator(const char *oper)
{
bool result;
double oper1,oper2;
result=GetOperands(oper1,oper2);//從棧中彈出2個操作數
if(result){
switch(*oper)
//根據操作符做相應的運算,先出棧的操作數oper1
//放在操作符的右邊,后出棧的oper2放在左邊
{
case '+':s.Push(oper2+oper1);break;
case '-':s.Push(oper2-oper1);break;
case '*':s.Push(oper2*oper1);break;
case '/':if (fabs(oper1)<1e-6){//如果分母為0,則做出錯處理
cerr<<"Divide by 0!"<<endl;
Clear();return false;
}
else s.Push(oper2/oper1);break;
case '^':s.Push(pow(oper2,oper1));break;
}
return true;
}
else {Clear();return false;}
}
void Calculator::Run()
{
const char * c;double newop;
cout<<"請輸入運算式!"<<endl;
InfixToPostfix(suffix);//中綴轉換為后綴
int i=0;
while(suffix.IDfind(i)!="="){//從隊列中依次讀入一個字符,遇'#'結束
c=suffix.IDfind(i).c_str();
i++;
switch(*c){//從讀入的字符做如下處理
case '+':
case '-':
if(strlen(c)>1){
newop=atof(c);
PushOperand(newop);
}
else {if(DoOperator(c)==0) return;}
break;
case '*':
case '/':
case '^':if(DoOperator(c)==0) return;break;//是操作符則進行相應的計算
default://如不是操作符,則轉換為操作數
newop=atof(c);
PushOperand(newop);break;//操作數進棧
}
}
if(s.Top(newop)){
s.Pop();
if(s.IsEmpty ()==1){
cout<<"結果是:"<<newop<<endl;}//取到棧頂元素,并輸出結果
else cout<<"操作數多余"<<endl;
Clear();
}
}
void InfixToPostfix(SeqQueue<string> &suffix0){
seqstack<string> s(SIZE);
string ch, y;
s.Push("=");
while(cin>>ch,ch!="="){
if(IsNumber(ch.c_str())) suffix0.EnQueue (ch);//掃描到操作數直接入隊
else if(ch==")") //掃描到右括號時的處理
for(s.Top(y),s.Pop();y!="(";s.Top(y),s.Pop())
suffix0.EnQueue (y);
else if(OperateSymbol(ch.c_str())) {//掃描到其他操作符時的處理
for(s.Top(y),s.Pop();icp(ch.c_str())<=isp(y.c_str());s.Top(y),s.Pop()){
suffix0.EnQueue (y);}//則彈出的m棧頂操作符優先級高時入隊
s.Push(y);//當彈出的棧頂操作符的優先級低時, 將其重新壓回棧中
s.Push(ch);//然后掃描到的操作符進棧
}
else {
cout<<"你輸錯"<<ch<<endl;
s.Clear();
suffix0.Clear();
exit(1);
}
}
while(!s.IsEmpty()){
s.Top(y); s.Pop();
if(y!="=") suffix0.EnQueue (y);
}
suffix0.EnQueue ("=");
}
void main()
{char c;
cout<<" 歡迎使用本計算系統(笑^_^)"<<endl;
cout<<" 注意 1.=表示算術式結束標志符!!!"<<endl;
cout<<" 2.數字和符號之間用空格隔開"<<endl;
Calculator Cal(SIZE);
do{
Cal.Run();
cout<<"請輸入組合鍵Ctrl+Z,再按回車結束,按其他鍵繼續!!!"<<endl;
c=cin.get();
}while((c=cin.get())!=EOF);
cout<<"謝謝使用...."<<endl;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -