算术表达式解析(第二版) 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: ...
随机推荐
- Android热修复AndFix
热修复主要用来修复代码.修复bug.添加独立的功能,他的原理主要是操作PathClassLoader.DexClassLoader. PathClassLoader是类加载器,DexClassLoad ...
- linux系统的学习
通过<鸟哥的linux私房菜>的学习,自己得到的收获! 关机与重启 shutdown -k now "message" 用以发送所有信息,并不是真的关机.还可以登录新的 ...
- jQuery中 pageX,clientX,offsetX,layerX的区别
一.PageX和clientXPageX和clientX ,这个两个比较容易搞混,PageX:鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化.可以理解为:相对#(0.0 ...
- 【转】JavaWeb MVC
-------------------------------------------------------------------------------------------------- 1 ...
- 浏览器内核控制Meta标签说明文档
浏览器内核控制Meta标签说明文档 原文链接 背景介绍 由于众所周知的情况,国内的主流浏览器都是双核浏览器:基于Webkit内核用于常用网站的高速浏览.基于IE的内核用于兼容网银.旧版网站.以360的 ...
- BASH_SUBSHELL 变量不生效的情况
BASH_SUBSHELL 实现于 Bash 3.0,我一直想不到它在实际编码中有什么用,后来在 Bash 的 Change Log 里找到一句话,才知道它是作调试用的: New variables ...
- 【转载】使用Pandas进行数据匹配
使用Pandas进行数据匹配 本文转载自:蓝鲸的网站分析笔记 原文链接:使用Pandas进行数据匹配 目录 merge()介绍 inner模式匹配 lefg模式匹配 right模式匹配 outer模式 ...
- JavaScript操作JSON的方法总结,JSON字符串转换为JSON对象
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...
- 如何让自己的app尽量不被系统杀死
1. 在Service中重写下面的方法,这个方法有三个返回值, START_STICKY是service被kill掉后自动重写创建 @Override public int onStartComman ...
- Java 计算数学表达式(字符串解析求值工具)
Java字符串转换成算术表达式计算并输出结果,通过这个工具可以直接对字符串形式的算术表达式进行运算,并且使用非常简单. 这个工具中包含两个类 Calculator 和 ArithHelper Calc ...