算术表达式解析(第二版) 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: ...
随机推荐
- Python Day8
Socket Socket是网络编程的一个抽象概念.通常我们用一个Socket表示"打开了一个网络链接",而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型 ...
- mysql优化记录
老板反应项目的反应越来越慢,叫优化一下,顺便学习总结一下mysql优化. 不同引擎的优化,myisam读的效果好,写的效率差,使用场景 非事务型应用只读类应用空间类应用 Innodb的特性,innod ...
- Canvas实例
<!doctype html> <html> <head> <meta charset="utf-8" /> <title&g ...
- 2015.4.19 为什么footer下a的索引值那么大
1.问题demo:为什么footer下a的索引值那么大,index不是查找兄弟级别的元素么?而且还限定了范围在footer下的a的情况下. 解决方法:alert( $("#footer a& ...
- HTC学习笔记
添加一个属性的setter, getter 建立一个页面 <html> <head> <title>TODO supply a title</title> ...
- 大熊君大话NodeJS之------基于Connect中间件的小应用(Bigbear记事本应用之第一篇)
一,开篇分析 大家好哦,大熊君又来了,昨天因为有点个人的事没有写博客,今天又出来了一篇,这篇主要是写一个记事本的小应用,前面的文章, 我也介绍过“Connect”中间件的使用以及“Mongodb”的用 ...
- codevs2800 送外卖
题目描述 Description 有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上.n个不同的客户分别在1~n个编号的城市中.送外卖的从0号城市出发,然后n个城市都要走一 ...
- JavaScript -- 小试牛刀
//var a = parseInt(window.prompt("请输入一个数字!","")); //switch(a) { // case 1 : // c ...
- word201612012
I/O (input/output) port / 输入/输出端口 IAS, Internet Authentication Service / Internet 验证服务 ICMP, Interne ...
- .NET LINQ 转换数据类型
转换数据类型 转换方法更改输入对象的类型. LINQ 查询中的转换运算可用于各种应用程序.下面是一些示例: Enumerable.AsEnumerable<TSource&g ...