算术表达式解析(第二版) C++11版
//一个简单的计算器代码,主要用来练习C++11新标准的编程技术和stl应用
1 #include<iostream>
#include<stack>
#include<map>
#include<set>
#include<functional>
#include<string>
using namespace std; typedef function<float(float,float)> optionFun;
stack<float> snumber;
stack<string> soption;
map<string,optionFun> optFunMap;
map<string,int> optWeightMap; #define DECLARE_OPT(opts,preority) \
optWeightMap[#opts] = int(preority);\
optFunMap[#opts] = bind([](float a, float b){return a opts b;}, placeholders::_1, placeholders::_2); void init_option()
{
DECLARE_OPT(+,);
DECLARE_OPT(-,);
DECLARE_OPT(*,);
DECLARE_OPT(/,);
} bool isoption(string op)
{
auto it = optWeightMap.find(op);
return it!=optWeightMap.end();
}
float recognize_float(const char* pstr, int& width)
{
char value[]={};
int dotcount = ;
for(int i=;pstr[i]!='\0';i++)
{
int x = pstr[i];
if(isdigit(x)||(x=='.'&&dotcount==))
{
value[i] = x;
dotcount++;
}
else
{
width = i;
break;
}
}
return atof(value);
} //offset from '(' to ')'
int check_match(const char* str)
{
int offset = ;
bool match = false;
while(str[offset]!='\0')
{
if(str[offset++]==')')
{
match = true;
break;
}
}
return match?offset:-;
} void handle_stack()
{
while(!soption.empty())
{
string opt = soption.top();
if(opt=="(")
{
soption.pop();
break;
}
auto it = optFunMap.find(opt);
if(it != optFunMap.end())
{
auto fun = it->second;
float a= snumber.top();
snumber.pop();
float b = snumber.top();
snumber.pop();
snumber.push(fun(b,a));
soption.pop();
}
}
}
float calc(const char* str)
{
if(str==nullptr)
{
cout<<"invalid express"<<endl;
return ;
} if(*str=='+'||*str=='-')
{
snumber.push();
}
while(*str!='\0')
{
if(isdigit(*str))
{
int len;
snumber.push(recognize_float(str,len));
str+=len;
continue;
}
if(*str=='(')
{
int len = check_match(str);
if(len==-)
{
cout<<"sync error : the express less a ')'"<<endl;
return;
}
soption.push("(");
calc(str+);
str += len;
continue;
}
if(*str==')')
{
handle_stack();
return ;
}
string ops(,*str);
if(isoption(ops))
{
if(!soption.empty())
{
if(optWeightMap[ops]<optWeightMap[soption.top()])
{
handle_stack();
}
}
soption.push(ops);
str++;
continue;
}
cout<<"invalid express"<<endl;
return ;
}
handle_stack();
return snumber.top();
}
int main()
{
init_option();
string str;
while(str!="exit")
{
cout<<"> ";
cin>>str;
if("exit"==str)break;
cout<<calc(str.c_str())<<endl;
}
return ;
}
这个计算器去年也写了一个,这次代码少了将近一半,说明还是有进步的……下次再少一点就好了,因为现在看上去还是有一些不和谐的东西,比如float类型的限制、括号处理分在了两个函数里面等。
算术表达式解析(第二版) C++11版的更多相关文章
- [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)
Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...
- [Java]算术表达式求值之一(中序表达式转后序表达式方案)
第二版请见:https://www.cnblogs.com/xiandedanteng/p/11451359.html 入口类,这个类的主要用途是粗筛用户输入的算术表达式: package com.h ...
- [Java]将算术表达式(中序表达式Infix)转成后续表达式Postfix
Inlet类: package com.hy; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...
- [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)
Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...
- K:双栈法求算术表达式的值
相关介绍: 该算法用于求得一个字符串形式的表达式的结果.例如,计算1+1+(3-1)*3-(21-20)/2所得的表达式的值,该算法利用了两个栈来计算表达式的值,为此,称为双栈法,其实现简单且易于理 ...
- [Java]算术表达式组建二叉树,再由二叉树得到算式的后序和中序表达式
Entry类: package com.hy; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...
- 关于aggregation 语法和表达式大全(最新3.4版)
用mongodb四年多了,从1.8版用到目前的3.4版,功能越来越强大,而且它的每一次升级带给我的都是惊喜,最近发现他的aggregation(管道)技术越来越丰富了,基本上将它提供的所有功能都集成了 ...
- 【翻译】《深入解析windows操作系统第6版下册》第10章:内存管理
[翻译]<深入解析windows操作系统第6版下册>第10章:内存管理(第一部分) [翻译]<深入解析windows操作系统第6版下册>第10章:内存管理(第二部分) [翻译] ...
- 用java实现编译器-算术表达式及其语法解析器的实现
大家在参考本节时,请先阅读以下博文,进行预热: http://blog.csdn.net/tyler_download/article/details/50708807 本节代码下载地址: http: ...
随机推荐
- Alpha阶段第二次Scrum Meeting
情况简述 Alpha阶段第一次Scrum Meeting 敏捷开发起始时间 2016/10/21 00:00 敏捷开发终止时间 2016/10/22 00:00 会议基本内容摘要 汇报了已经完成的任务 ...
- K米点歌APP评测
K米APP评测 产品简介 K米点歌是一款免费的社交K歌手机应用,其手机点歌功能主要在KTV.夜总会,酒吧等K歌场所中使用,当前提供iPhone版本及安卓版本下载使用.——百度百科 评测版本 K米点歌4 ...
- ztree.js的使用整理
/** 配置:知识点管理 */ var setting = { view: { showIcon: false, addDiyDom: addPrevDom, addHoverDom: addHove ...
- opencv学习
判断是否正确读入的方法: if( argc != 2 || !(src=imread(argv[1], 1)).data ) return -1; --- if( src.empty() ) { re ...
- elasticsearch curl operation
Elastic Search API Index.简单的介绍了使用Elastic Search 如何建立索引. ElasticSearch-API-Index 索引创建API允许初始化一个索引.Ela ...
- Google Map API V3开发(4)
Google Map API V3开发(1) Google Map API V3开发(2) Google Map API V3开发(3) Google Map API V3开发(4) Google M ...
- OpenGL Common Mistakes
https://www.opengl.org/wiki/Common_Mistakes Do not use constructors/destructors to initialize/destro ...
- yield和send的执行循序彻底搞清
yield: 对于yield方法和Generator的send同时使用时的执行顺序一直搞不清,今天看到这篇 理解PHP中的Generator 加上测试,终于搞清了. 总结一下上文中的结论: Gener ...
- [NHibernate]Nullables
系列文章 [Nhibernate]体系结构 [NHibernate]ISessionFactory配置 [NHibernate]持久化类(Persistent Classes) [NHibernate ...
- Servlet监听器
一.servlet的8个监听器 场景 监听者接口 事件类型 你想知道一个web应用上下文中是否增加.删除或替换了一个属性 javax.servlet.ServletContextAttributeLi ...