Calculator 2
新增:
计算类(拥有计算功能)
采用符号优先级计算方法
对符号不匹配的如 -2 ,自动补为 0-2
计算内核信息
输入 -a 可以显示等式与结果
输入 -p 可以显示计算逐步过程
传入 -a 参数 且 传入 -p 参数

传入 -a 参数 且 不传入 -p 参数

规定并非万无一失,但暂未发现有悖原意的bug。
如有发现bug,但求一知,万分感谢。
//
// main.cpp
// Calculator
//
// Created by admin on 16/2/25.
// Copyright © 2016年 YooRarely. All rights reserved.
//
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <cmath>
#include <sstream>
using namespace std;
class Scan{
private:
bool err; // 输入是否出错
public:
// 字符是否为运算符
bool isOper(char c){
if ( c == '+' || c == '-' || c == '*' || c == '/' ) return true;
return false;
}
// 字符是否为数字
bool isCount(char c){
if (c>='0' && c<='9') return true;
return false;
}
queue <string> ToStringQueue(string input){
err=false;
queue <string > a;
int sum_kuohao = 0;
// 当输入未出错时遍历输入字符串
for (int i = 0; i < input.size() && ! err; i ++){
string s;
// 如果为 运算符 或 括号
if ( isOper( input[i] ) || input[i] == '(' || input[i] == ')' ) {
s = input[i];
if (!a.empty()){
string k=a.back();
if (input[i] == '(' && ( isCount( k[0] ) || k[0] == ')' ) ) err = true;
if ( isOper( k[0] ) && input[i] != '(' && input[i] != '-' ) err = true;
}
if (input[i] == '(') sum_kuohao ++;
if (input[i] == ')') sum_kuohao --;
if ( sum_kuohao < 0 ) err = true;
}// 否则 如果为数字
else if ( isCount( input[i] ) ){
bool dian=false;
while ( ! err && i < input.size() ){
if ( isCount( input[i] ) || input[i] == '.') s=s+input[i];
if ( input[i] == '.' ) {
if ( dian ) err = true;
dian = true;
}
if ( isOper( input[i+1] ) || input[i+1] == '(' || input[i+1] == ')') break;
i++;
}
if (dian && s[ s.size() - 1 ] == '.') err = true;
if ( s.size() > 10 ) err = true;
}
// 入队
a.push(s);
s="";
}
if ( sum_kuohao ) err = true;
if ( ! err && ! a.empty() ){
string k = a.front();
if ( isOper( k[0] ) && k[0] != '-' ) err = true;
k = a.back();
if ( isOper( k[0] ) ) err = true;
}
if ( err ) {
while ( ! a.empty() ) a.pop();
a.push("Error Input !");
}
return a;
}
};
class Print{
public:
void PrintStringQueue(queue<string> a){
while ( ! a.empty() ) {
cout << a.front() << endl;
a.pop();
}
}
};
class Calculate{
private:
bool print;
int tried (stack <char> &oper,stack <int> &important,stack <double> &count, int k){
while ( ! important.empty() && k <= important.top()){
double amazing = count.top();
count.pop();
switch (oper.top()) {
case '+':
if (print) cout<<count.top()<<"+"<<amazing;
count.top() += amazing;
if (print) cout<<"="<<count.top()<<endl;
break;
case '-':
if (print) cout<<count.top()<<"-"<<amazing;
count.top() -= amazing;
if (print) cout<<"="<<count.top()<<endl;
break;
case '*':
if (print) cout<<count.top()<<"*"<<amazing;
count.top() *= amazing;
if (print) cout<<"="<<count.top()<<endl;
break;
case '/':
if (amazing == 0) { return -1;}
if (print) cout<<count.top()<<"/"<<amazing;
count.top() /= amazing;
if (print) cout<<"="<<count.top()<<endl;
break;
}
oper.pop();
important.pop();
}
return 0;
}
public:
// 字符是否为运算符
bool isOper(char c){
if ( c == '+' || c == '-' || c == '*' || c == '/' ) return true;
return false;
}
// 字符是否为数字
bool isCount(char c){
if (c>='0' && c<='9') return true;
return false;
}
double getAns(queue<string> a,bool p){
stack <char> oper;
stack <int> important;
stack <double> count;
int k=0;
print=p;
while ( ! a.empty() ){
if (a.front()[0] == '(') k += 2;
if (a.front()[0] == ')') k -= 2;
if (isOper( a.front()[0] )){
if ( oper.size() == count.size() ){
count.push(0);
important.push(10000);
}
else if ( a.front()[0] == '*' || a.front()[0] == '/'){
if ( tried(oper, important, count, k+1) == -1 ) return 0.000000;
important.push(k+1);
}
else{
if ( tried(oper, important, count, k) == -1 ) return 0.000000;
important.push(k);
}
oper.push( a.front()[0] );
}
if (isCount( a.front()[0] )){
count.push( atof( a.front().c_str() ) );
}
a.pop();
}
if ( ! oper.empty() )
if ( tried(oper, important, count, -1) == -1 ) return 0.000000;
return count.top();
}
};
int main(int argc, const char * argv[]) {
string input;
bool p,a;
double ans;
int i;
Scan scan;
Print print;
Calculate Calculate;
p=false;
a=false;
i=1;
// getline(cin,input);
if (argc<2) return 0;
input=argv[i];
while (1){
if (input=="-a") {
input=argv[++i];
a=true;
continue;
}
if (input=="-p"){
input=argv[++i];
p=true;
continue;
}
break;
}
// print.PrintStringQueue( scan.ToStringQueue(input) );
ans=Calculate.getAns( scan.ToStringQueue(input) , p);
if (a) cout<<input<<"=";
cout<<ans<<endl;
return 0;
}
Calculator 2的更多相关文章
- [LeetCode] Basic Calculator II 基本计算器之二
Implement a basic calculator to evaluate a simple expression string. The expression string contains ...
- [LeetCode] Basic Calculator 基本计算器
Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...
- Basic Calculator II
Implement a basic calculator to evaluate a simple expression string. The expression string contains ...
- Windows Universal 应用 – Tip Calculator
声明 以下内容取材于 Bob Tabor 的课程<Windows Phone 8.1 Development for Absolute Beginners>,链接地址为:http://ww ...
- Calculator(1.5)
Calculator(1.5) Github链接 ps.负数的处理未完成 解题过程中遇到的困难和解决 <stack>的使用: 认真研究了栈,基本上掌握了用法,与<queue>的 ...
- Calculator(1.0)
Calculator(1.0) Github链接 解题过程中遇到的困难 对于c++中类和对象的使用不够明确,看了c++的视频教程学会了用类和对象来写程序. 不会使用<queue>,在网上查 ...
- 数据结构与算法(1)支线任务2——Basic Calculator
题目:https://leetcode.com/problems/basic-calculator/ Implement a basic calculator to evaluate a simple ...
- calculator
#include <stdio.h> #include <stdlib.h> typedef enum { FALSE = , TRUE }BOOL; void calcula ...
- Basic Calculator
本博客介绍leetcode上的一道不难,但是比较经典的算法题. 题目如下: Implement a basic calculator to evaluate a simple expression s ...
- Matrix Calculator
表达式分析+矩阵+计算器+寄存器=矩阵计算器 怎么想起来搞这个呢.. //刚看龙书兴致勃勃要搞表达式分析 这个寄存器比较简陋,26字母+4缓存,//字母不分大小写 当然,不只能算矩阵,还能算数= = ...
随机推荐
- HTML-CSS的几种布局
第一种 两栏式布局 <body> <!-- 两栏式布局 --> <!-- 想要的效果是左边图片右边文字 拉伸盒子文字的高度宽度自动改变 --> <div c ...
- 大数据学习--day03(运算符、流程控制语句)
运算符.流程控制语句 自增自减容易出错的地方: 扩展的赋值运算符 a+=b 等同于 a = a+b; 扩展的赋值运算符 隐含了一个类型的强制转换 & && 有何区别 & ...
- spark启动原理总结
一般情况下,我们启动spark集群都是start-all.sh或者是先启动master(start-master.sh),然后在启动slave节点(start-slaves.sh),其实翻看start ...
- 决策树&随机森林
参考链接: https://www.bilibili.com/video/av26086646/?p=8 <统计学习方法> 一.决策树算法: 1.训练阶段(决策树学习),也就是说:怎么样构 ...
- python学习笔记~INI、REG文件读取函数(自动修复)
引入configparser,直接read整个INI文件,再调用get即可.但需要注意的是,如果INI文件本身不太规范,就会报各种错,而这又常常不可避免的.本文自定义函数通过try...except. ...
- 【8086汇编-Day7】关于多个段的程序的实验
实验一 实验二 实验三 实验四 实验五 实验六 总结 在集成环境下,内存从0770段开始按照段的先后顺序和内容多少分配,并且分配的都是16的倍数 关于实际占用的空间公式的话其实极容易想到(假设有N个字 ...
- BZOJ4300_绝世好题_KEY
题目传送门 刚开始是看到这道题目还以为是序列连续的. 当然了,序列可以不连续. 设f[i]表示到第i位时的序列的最长长度. 取cnt=Max f[j]+1,然后转移回去使f[j]=cnt. 这是为了让 ...
- 2212: [Poi2011]Tree Rotations
2212: [Poi2011]Tree Rotations https://www.lydsy.com/JudgeOnline/problem.php?id=2212 分析: 线段树合并. 首先对每个 ...
- 8、Java并发编程:同步容器
Java并发编程:同步容器 为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch). ...
- Java - 无乱码读写文件
Java读取数据流的时候,一定要指定数据流的编码方式,否则将使用本地环境中的默认字符集. BufferedReader reader = null; String laststr = "&q ...