| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
x
 
简单计算器的实现(实现整数的加减乘除)用了继承的方法,通过data和char的两个栈分别存放操作数和运算符来实现 
先不看逆波兰的计算,先实现简单的1+2 
 
- //counter.cpp
 
  
- #include <iostream>
 
 - #include<string.h>
 
 - #include<stdio.h>
 
 - #include "counter_char.h"
 
 - #include "counter_data.h"
 
 - using namespace std;
 
  
- void append_data(char*& rpn,int opnd)//将操作数接至RPN末尾
 
 - {
 
 -         int n = strlen(rpn);//RPN当前长度(以'\0'结尾,长度n+1)
 
 -         char buf[64];
 
 -         sprintf(buf,"%d \0",(int)opnd);//将一个格式化的字符串输出到一个目的字符串中
 
 -         //rpn = (char*)realloc(rpn,sizeof(char)*(n+strlen(buf)+1));//扩展空间
 
 -         strcat(rpn,buf);//把buf所指向的字符串追加到rpn的末尾,RPN加长
 
 - }
 
  
- void append_char(char*& rpn,char optr)//将运算符接至RPN末尾
 
 - {
 
 -         int n = strlen(rpn);////RPN当前长度(以'\0'结尾,长度n+1)
 
 - //        rpn = (char*)realloc(rpn,sizeof(char)*(n+3));//扩展空间
 
 -         sprintf(rpn+n,"%c ",optr);
 
 -         rpn[n+2] = '\0';//接入指定的运算符
 
 - }
 
  
- void readNumber(char*& p,Stack_data & stk)//将起始于p的子串解析为数值,并存入操作数栈
 
 - {
 
 -         stk.push((int)(*p - '0'));//当前数位对应的数值进栈
 
 -         while(isdigit(*(++p)))//只要后续还有紧邻的数字(即多位整数的情况),则
 
 -                 stk.push(stk.pop()*10+(*p - '0'));//弹出原操作数并追加新位数后,新数值重新入栈
 
 - }
 
  
- #define N_OPTR 5//运算符总数
 
 - typedef enum{ADD,SUB,MUL,DIV,EOE}Operator;//运算符集合
 
 - //加、减、乘、除、起始符与终止符
 
  
- const char pri[N_OPTR][N_OPTR]=//运算符优先等级[栈顶][当前]
 
 - {
 
 -         '>', '>', '<', '<', '>',
 
 -         '>', '>', '<', '<', '>',
 
 -         '>', '>', '>', '>', '>',
 
 -         '>', '>', '>', '>', '>',
 
 -         '<', '<', '<', '<', '='
 
 - };
 
  
- OperType optr2rank(char op)//由运算符转译出编号
 
 - {
 
 -         cout << "op:" << int(op) << endl;
 
 -         switch(op)
 
 -         {
 
 -         case '+':return ADD;//加
 
 -         case '-':return SUB;//减
 
 -         case '*':return MUL;//乘
 
 -         case '/':return DIV;//除
 
 -         case '\0':return EOE;//起始符与终止符
 
 -         default:printf("语法错误3\n");exit(-1);//未知运算符
 
 -         }
 
 - }
 
  
- char orderBetween(char op1,char op2)//比较两个运算符之间的优先级
 
 - {
 
 -         return pri[optr2rank(op1)][optr2rank(op2)];
 
 - }
 
  
- int calcu(int pOpnd1,char op,int pOpnd2)//op为操作符,pOpnd1和2为操作数
 
 - {
 
 -         int result;
 
 -         switch(op)
 
 -         {
 
 -                 case ADD:
 
 -                         result = pOpnd1 + pOpnd2;
 
 -                         break;
 
 -                 case SUB:
 
 -                         result = pOpnd1 - pOpnd2;
 
 -                         break;
 
 -                 case MUL:
 
 -                         result = pOpnd1 * pOpnd2;
 
 -                         break;
 
 -                 case DIV:
 
 -                         result = pOpnd1 / pOpnd2;
 
 -                         break;
 
 -                 default:printf("语法错误2\n");exit(-1);
 
 -         }
 
 -         return result;
 
 - }
 
  
- float evaluate(char* S,char* RPN)//对(已删除白空格的)表达式S求值,并转换为逆波兰式RPN
 
 - {//S为存放字符数组的指针
 
 -         Stack_data opnd;
 
 -         Stack_char optr;
 
 -         optr.push('\0');//尾哨兵'\0'也作为头哨兵首先入栈
 
 -         while(!optr.empty())//在运算符栈非空之前,逐个处理表达式中各字符
 
 -         {
 
 -                 if(isdigit(*S))//如果当前字符为操作符,则
 
 -                 {
 
 -                         cout << "这一轮while是if" << endl;
 
 -                         cout << "*S是:" << *S << endl;
 
 -                         readNumber(S,opnd);
 
 -                         append_data(RPN,opnd.top());//读入操作数,并将其接至RPN末尾→拼成逆波兰式
 
 -                 }
 
 -                 else//若当前字符为运算符,则
 
 -                 {
 
 -                         cout << "这一轮while是else" << endl;
 
 -                         cout << "*S是:" << *S << endl;
 
  
-                         cout << "orderBetween(optr.top(),*S):" << orderBetween(optr.top(),*S) << endl;
 
 -                         switch(orderBetween(optr.top(),*S))//视其与栈顶运算符之间优先级高低分别处理
 
 -                         {
 
 -                                 case'<'://栈顶运算符优先级更低时
 
 -                                         optr.push(*S);S++;//计算推迟,当前运算符进栈
 
 -                                         break;
 
 -                                 case'='://优先级相等(当前运算符为右括号或尾部哨兵'\0')时
 
 -                                         optr.pop();S++;//脱括号并接收下一个字符
 
 -                                         break;
 
 -                                 case'>'://栈顶运算符优先级更高时,可实施相应的计算,并将结果重新入栈
 
 -                                 {
 
 -                                         char op = optr.pop();append_char(RPN,op);//栈顶运算符出栈并续接至RPN末尾
 
 -                                         int pOpnd2 = opnd.pop(),pOpnd1 = opnd.pop();//取出后、前操作数
 
 -                                         opnd.push(calcu(pOpnd1,optr2rank(op),pOpnd2));
 
 -                                         break;
 
 -                                 }
 
 -                                 default:printf("语法错误1\n");exit(-1);//逢语法错误,不做处理直接退出
 
 -                         }
 
 -                 }
 
 -         }
 
 -         return opnd.pop();//弹出并返回最后的计算结果
 
 - }
 
  
- int main()
 
 - {
 
  
-         char expression[20];
 
 -         char RPN[10];
 
 -         cout << "请输入要计算的式子:";
 
 -         gets(expression);
 
 -         expression[4] = '\0';
 
 -         cout << "计算结果为:" << evaluate(expression,RPN) << endl;
 
 -         cout << "逆波兰表达式为:" << *RPN << endl;
 
 -         
 
 -         return 0;
 
 - }
 
  复制代码 
- //vector_char.cpp
 
  
- #include "vector_char.h"
 
 - #include <iostream>
 
  
- using namespace std;
 
  
- Vector_char::Vector_char()
 
 - {
 
 -         _size = 4;
 
 -         _capacity = 4;
 
 -         elem = new OperType[_capacity];//建立容量为_size的数组
 
 - }
 
  
- void Vector_char::expand()//空间不足时扩容
 
 - {
 
 -         if(_size < _capacity)//尚未满员时,不必扩容
 
 -                 return;        
 
 -         OperType * oldElem = elem;
 
 -         elem = new OperType[_capacity <<= 1];//容量加倍
 
 -         for(int i= 0;i < _size;i++)
 
 -                 elem[i] = oldElem[i];//复制原向量内容
 
 -         delete []oldElem;//释放原空间
 
 -         cout << "该向量扩容后容量为:" << _capacity << endl;
 
 - //        print();
 
 - }
 
  
- void Vector_char::shrink()//缩容
 
 - {
 
 -         if(_size << 2 > _capacity)//以25%为界
 
 -         {
 
 -                 cout << "不需要缩容" << endl;
 
 -                 return;
 
 -         }
 
 -         cout << "缩容后:";
 
 - //        print();
 
 -         OperType * oldElem = elem;
 
 -         elem = new OperType[_capacity >>= 1];//容量减半
 
 -         for(int i= 0;i < _size;i++)
 
 -                 elem[i] = oldElem[i];//复制原向量内容
 
 -         cout << "缩容后有" << _size << "个单位" << endl;
 
 -         delete [] oldElem;//释放原空间
 
  
- }
 
  
- Rank Vector_char::insert(Rank r,OperType optr)//插入
 
 - {
 
 - //        expand();//如果有必要,扩容
 
 -         for(int i = _size;i>r;i--)
 
 -                 elem[i] = elem[i-1];//自后向前,后继元素顺次后移一个单位
 
 -         elem[r]=optr;
 
 -         _size++;//置入新元素并更新容量
 
 - //        cout << "插入e后:";
 
 - //        print();
 
 -         return r;//返回秩
 
 - }
 
  
- int Vector_char::remove(Rank r)//删除秩为r的元素
 
 - {
 
 -         int e = elem[r];//备份被删除的元素
 
 -         remove(r,r+1);//调用区间删除算法,等效于对区间[r,r+1)的删除
 
 -         return e;//返回被删除元素
 
 - }
 
  
- void Vector_char::remove(Rank lo,Rank hi)//删除区间[lo,hi]
 
 - {
 
 -         while(hi < _size)
 
 -                 elem[lo++] = elem[hi++];//[hi,_size)顺次前移hi-lo个单元
 
 -         _size = lo;//更新规模,丢弃尾部[lo,_size = hi)区间
 
 - //        cout << "删除后:";
 
 - //        print();
 
 -         shrink();//若有必要,缩容
 
 -         
 
 - //        return hi - lo;//返回被删除元素的数目
 
 - }
 
  
- void Vector_char::print()
 
 - {
 
 -         for(int i =0;i<_size;i++)
 
 -                 cout << elem[i] << "\t";
 
 -         cout << endl;
 
 - }
 
  
- OperType * Vector_char::back(int r)//返回elem指针
 
 - {
 
 -         return elem+r;
 
 - }
 
  
- bool Vector_char::empty()//判断栈内是否为空
 
 - {
 
 -         int elem_length = sizeof(elem)/sizeof(*elem);
 
 -         if (elem_length == 0)
 
 -                 return true;
 
 -         else
 
 -                 return false;
 
 - }
 
  复制代码 
- //vector_data.cpp
 
  
- #include "vector_data.h"
 
 - #include <iostream>
 
  
- using namespace std;
 
  
- Vector_data::Vector_data()
 
 - {
 
 -         _capacity = 4;
 
 -         elem = new DataType[_capacity];//建立容量为_capacity的数组
 
 -         _size = 4;
 
 - }
 
  
- void Vector_data::expand()//空间不足时扩容
 
 - {
 
 -         if(_size < _capacity)//尚未满员时,不必扩容
 
 -                 return;        
 
 -         DataType * oldElem = elem;
 
 -         elem = new DataType[_capacity <<= 1];//容量加倍
 
 -         for(int i= 0;i < _size;i++)
 
 -                 elem[i] = oldElem[i];//复制原向量内容
 
 -         delete []oldElem;//释放原空间
 
 - //        cout << "该向量扩容后容量为:" << _capacity << endl;
 
 - //        print();
 
 - }
 
  
- void Vector_data::shrink()//缩容
 
 - {
 
 -         if(_size << 2 > _capacity)//以25%为界
 
 -         {
 
 -                 cout << "不需要缩容" << endl;
 
 -                 return;
 
 -         }
 
 - //        cout << "缩容后:";
 
 - //        print();
 
 -         DataType * oldElem = elem;
 
 -         elem = new DataType[_capacity >>= 1];//容量减半
 
 -         for(int i= 0;i < _size;i++)
 
 -                 elem[i] = oldElem[i];//复制原向量内容
 
 - //        cout << "缩容后有" << _size << "个单位" << endl;
 
 -         delete [] oldElem;//释放原空间
 
 - }
 
  
- Rank Vector_data::insert(Rank r,DataType opnd)//插入
 
 - {
 
 - //        expand();//如果有必要,扩容
 
 -         for(int i = _size;i>r;i--)
 
 -                 elem[i] = elem[i-1];//自后向前,后继元素顺次后移一个单位
 
 -         elem[r]=opnd;
 
 -         _size++;//置入新元素并更新容量
 
 - //        cout << "插入e后:";
 
 -         return r;//返回秩
 
 - }
 
  
- int Vector_data::remove(Rank r)//删除秩为r的元素
 
 - {
 
 -         int e = elem[r];//备份被删除的元素
 
 -         remove(r,r+1);//调用区间删除算法,等效于对区间[r,r+1)的删除
 
 -         return e;//返回被删除元素
 
 - }
 
  
- void Vector_data::remove(Rank lo,Rank hi)//删除区间[lo,hi]
 
 - {
 
 -         while(hi < _size)
 
 -                 elem[lo++] = elem[hi++];//[hi,_size)顺次前移hi-lo个单元
 
 -         _size = lo;//更新规模,丢弃尾部[lo,_size = hi)区间
 
 - //        cout << "删除后:";
 
 - //        cout << "_size是:" << _size << endl;
 
 -         shrink();//若有必要,缩容
 
 -         
 
 - //        return hi - lo;//返回被删除元素的数目
 
 - }
 
  
- void Vector_data::print()
 
 - {
 
 -         for(int i =0;i<_size;i++)
 
 -                 cout << elem[i] << "\t";
 
 -         cout << endl;
 
 - }
 
  
- DataType * Vector_data::back(int r)
 
 - {
 
 -         return elem+r;
 
 - }
 
 
  复制代码 
- //counter_char.h
 
  
- #ifndef _COUNTER_CHAR_H_
 
 - #define _COUNTER_CHAR_H_
 
  
- #include<iostream>
 
 - #include "vector_char.h"//以向量为基类,派生出栈模板类
 
  
- using namespace std;
 
  
- class Stack_char:public Vector_char{//将向量的 首/末端 作为 栈底/顶
 
 - public:
 
 -         void push(OperType optr){insert(size(),optr);}//入栈,常引用作参数
 
 -         OperType pop(){return remove(size()-1);}//出栈,删除末元素  将末元素改为其前驱
 
 -         OperType & top(){return *(back(size())-1);}//取顶 ,引用作为返回值
 
 - };
 
 - #endif
 
  复制代码 
- //counter_data.h
 
  
- #ifndef _COUNTER_DATA_H_
 
 - #define _COUNTER_DATA_H_
 
  
- #include<iostream>
 
 - #include "vector_data.h"//以向量为基类,派生出栈模板类
 
  
- using namespace std;
 
  
- class Stack_data:public Vector_data{//将向量的 首/末端 作为 栈底/顶
 
 - public:
 
 -         void push(DataType opnd){insert(size(),opnd);}//入栈,常引用作参数
 
 -         DataType pop(){return remove(size()-1);}//出栈,删除末元素  将末元素改为其前驱
 
 -         DataType & top(){return *(back(size())-1);}//取顶 ,引用作为返回值
 
 - };
 
  
- #endif
 
  复制代码 
- //vector_char.h
 
  
- //存放操作符
 
  
- //存放数字
 
 - //存放字符
 
 - #ifndef _VECTOR_CHAR_H_
 
 - #define _VECTOR_CHAR_H_
 
  
- #include<iostream>
 
 - using namespace std;
 
  
- typedef int Rank;
 
 - typedef char OperType;
 
  
- class Vector_char
 
 - {
 
 - private:
 
 -         char *p;//p指向数组elem,用于释放数组
 
 -         OperType *elem;
 
 -         int _capacity;//_capacity是数组容量
 
 -         
 
 - public:
 
 -         Rank _size;//_size是实际规模
 
 -         Rank size()const{return _size;}//规模
 
 -         void expand();//空间不足时扩容
 
 -         void shrink();//缩容
 
 -         Rank insert(Rank r,OperType optr);//插入
 
 -         int remove(Rank r);//删除秩为r的元素
 
 -         void remove(Rank lo,Rank hi);//删除区间[lo,hi]
 
 -         void print();
 
 -         OperType * back(int r);//返回elem指针
 
 -         bool empty();
 
 -         
 
 -         //构造函数
 
 -         Vector_char();
 
 - };
 
  
- #endif
 
  复制代码 
- //counter_data.h
 
  
- //存放数字
 
 - #ifndef _VECTOR_DATA_H_
 
 - #define _VECTOR_DATA_H_
 
  
- #include<iostream>
 
 - using namespace std;
 
  
- typedef int Rank;
 
 - typedef int DataType;
 
  
- class Vector_data
 
 - {
 
 - private:
 
 -         int *p;//p指向数组elem,用于释放数组
 
 -         DataType *elem;
 
 -         int _capacity;//_capacity是数组容量
 
 -         
 
 - public:
 
 -         Rank _size;//_size是实际规模
 
 -         Rank size()const{return _size;}//规模
 
 -         void expand();//空间不足时扩容
 
 -         void shrink();//缩容
 
 -         Rank insert(Rank r,DataType opnd);//插入
 
 -         int remove(Rank r);//删除秩为r的元素
 
 -         void remove(Rank lo,Rank hi);//删除区间[lo,hi]
 
 -         void print();
 
 -         DataType * back(int r);//返回elem指针
 
 -         
 
 -         //构造函数
 
 -         Vector_data();
 
 - };
 
  
- #endif
 
  复制代码 |   
 
 
 
 |