//一个简单的计算器代码,主要用来练习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版的更多相关文章

  1. [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)

    Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...

  2. [Java]算术表达式求值之一(中序表达式转后序表达式方案)

    第二版请见:https://www.cnblogs.com/xiandedanteng/p/11451359.html 入口类,这个类的主要用途是粗筛用户输入的算术表达式: package com.h ...

  3. [Java]将算术表达式(中序表达式Infix)转成后续表达式Postfix

    Inlet类: package com.hy; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...

  4. [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)

    Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...

  5. K:双栈法求算术表达式的值

    相关介绍:  该算法用于求得一个字符串形式的表达式的结果.例如,计算1+1+(3-1)*3-(21-20)/2所得的表达式的值,该算法利用了两个栈来计算表达式的值,为此,称为双栈法,其实现简单且易于理 ...

  6. [Java]算术表达式组建二叉树,再由二叉树得到算式的后序和中序表达式

    Entry类: package com.hy; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...

  7. 关于aggregation 语法和表达式大全(最新3.4版)

    用mongodb四年多了,从1.8版用到目前的3.4版,功能越来越强大,而且它的每一次升级带给我的都是惊喜,最近发现他的aggregation(管道)技术越来越丰富了,基本上将它提供的所有功能都集成了 ...

  8. 【翻译】《深入解析windows操作系统第6版下册》第10章:内存管理

    [翻译]<深入解析windows操作系统第6版下册>第10章:内存管理(第一部分) [翻译]<深入解析windows操作系统第6版下册>第10章:内存管理(第二部分) [翻译] ...

  9. 用java实现编译器-算术表达式及其语法解析器的实现

    大家在参考本节时,请先阅读以下博文,进行预热: http://blog.csdn.net/tyler_download/article/details/50708807 本节代码下载地址: http: ...

随机推荐

  1. pthread_cond_signal惊群现象

    1.如下代码所示: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include < ...

  2. Perplexity Vs Cross-entropy

    Evaluating a Language Model: Perplexity We have a serial of \(m\) sentences: \[s_1,s_2,\cdots,s_m\] ...

  3. Elasticsearch集群状态脚本及grafana监控面板导出的json文件

    脚本文件: #!/usr/bin/env python import datetime import time import urllib import json import urllib2 imp ...

  4. 面试题目——《CC150》链表

    面试题2.1:编写代码,移除未排序链表中的重复结点 进阶:如果不得使用临时缓冲区,该怎么解决? package cc150; import java.util.HashMap; import java ...

  5. UITableViewCell的重用机制

    UITabelView一般会显示大量数据,如果有多少条数据就新建多少个cell,那么对于内存来说是种极大的负担,这样自然是不合理的,所以才会有重用机制 比如一个家庭办酒席,一共有13桌,每桌20个菜, ...

  6. tyvj1113 魔族密码

    描述     风之子刚走进他的考场,就……    花花:当当当当~~偶是魅力女皇——花花!!^^(华丽出场,礼炮,鲜花)    风之子:我呕……(杀死人的眼神)快说题目!否则……-_-###    花 ...

  7. HTTP请求报文格式

    HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的.HTTP有两类报文:请求报文和响应报文. 请求报文 一个HTTP请求报文由请求行(request line ...

  8. URL转义

    在处理一些url的时候常常会出现一些让人意想不到的情况,比如:当图片的链接中有空格的时候, this.src='http://img.cits-sh.com/UploadImgs/beihaidao2 ...

  9. 基于浏览器的HTML5地理定位

    基于浏览器的HTML5地理定位 地理位置(Geolocation)是 HTML5 的重要特性之一,提供了确定用户位置的功能,借助这个特性能够开发基于位置信息的应用.今天这篇文章向大家介绍一下 HTML ...

  10. java 深入技术四(Set)

    1)Set接口 set接口的父接口-Collection set接口的重要子类-HashSet set接口的重要子类 -TreeSet set 接口的特别子类-LinkedHashSet 2)Hash ...