-
-
由于代码的注释过于详细,就不对代码再进行解释了 (如有疑问可以在评论内询问)
-
支持带空格的式子,以及带各种诡异字符的式子。。(会自动忽略)
-
增添了之前 写的四则运算中 的没有涉及的判错。。
-
之前 写的四则运算 把 处理 字符串 和 运算 冗杂在一起 降低了 运算过程的可读性 修改起来也相当麻烦,于是重写
-
虽然 只有获取字符串队列的功能 但是稍作修改就能将此运用于之前的运算中去
//
// main.cpp
// Calculator
//
// Created by admin on 16/2/25.
// Copyright © 2016年 YooRarely. All rights reserved.
//
#include <iostream>
#include <queue>
#include <string>
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){
// 初始化变量 a 为 返回值
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 ++; // 左括号 数量+1
if (input[i] == ')') sum_kuohao --; // 右括号 数量-1
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;
// 如果这个数超过10位 错误
if ( s.size() > 10 ) err = true;
}
// 入队
a.push(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;
}
// 如果存在错误 把 a 队列清空 报告错误
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();
}
}
};
int main(int argc, const char * argv[]) {
string input;
getline(cin,input);
Scan scan;
Print print;
print.PrintStringQueue( scan.ToStringQueue(input) );
return 0;
}
-
原来是拿着之前写的进行修改
-
分成两个存储运算符和数字的队列
-
除了增加判断小数以外其他都弄好了。。
-
但是感觉用起来麻烦且不好扩展,于是就拍掉重做。。
-
hpp 文件
//
// scan.hpp
// text
//
// Created by admin on 16/2/25.
// Copyright © 2016年 YooRarely. All rights reserved.
//
#ifndef scan_hpp
#define scan_hpp
#include <stdio.h>
#include <string>
#include <iostream>
#include <queue>
using namespace std;
class scan{
private:
deque <int> important;
deque <char> oper;
deque <int> count;
queue <string> str;
int k;
bool err;
public :
void ToStringQueue(string input);
void print(){
if (isErr()){
std::cout << "input is error!" << std::endl;
return;
}
int f = 1,j = 0;
for (int i = 0; i < oper.size(); i++){
while ( important[i] != f ){
std::cout << count[j++] << std::endl;
f++;
};
std::cout << oper[i] << std::endl;
f++;
}
if (j < count.size()) std::cout << count[j++] << std::endl;
}
bool isErr() { return err; }
};
#endif /* scan_hpp */
//
// scan.cpp
// text
//
// Created by admin on 16/2/25.
// Copyright © 2016年 YooRarely. All rights reserved.
//
#include "scan.hpp"
void scan:: ToStringQueue(string input){
err=false;
while ( ! oper.empty() ) oper.pop_back();
while ( ! count.empty() ) count.pop_back();
while ( ! important.empty() ) important.pop_back();
k = 0;
int count = 0;
int biubiubiu = -1;
for (int i = 0; i < input.length() && ! err; i ++){
switch (input[i]) {
case '(':
if (biubiubiu == 0) err = true; oper.push_back('('); important.push_back( ++ k); count = 0; biubiubiu = 1;
break;
case ')':
if (biubiubiu > 2) err = true; oper.push_back(')'); important.push_back( ++ k); count = 0; biubiubiu = 2;
break;
case '+':
if (biubiubiu > 2 || biubiubiu == 1) err = true; oper.push_back('+'); important.push_back( ++ k); count = 0; biubiubiu = 3;
break;
case '-':
if (biubiubiu > 2) err = true; oper.push_back('-'); important.push_back( ++ k); count = 0; biubiubiu = 4;
break;
case '*':
if (biubiubiu > 2 || biubiubiu == 1) err = true; oper.push_back('*'); important.push_back( ++ k); count = 0; biubiubiu = 5;
break;
case '/':
if (biubiubiu > 2 || biubiubiu == 1) err = true; oper.push_back('/'); important.push_back( ++ k); count = 0; biubiubiu = 6;
break;
default:
break;
}
if (input[i] >= '0' && input[i] <= '9') {
if (!this->count.empty() && ! biubiubiu) this->count.pop_back(),k --;
biubiubiu = 0;
if (1L + count * 10 + input[i] - 48 > 9999999999L) err = true;
count = count * 10 + input[i] - 48;
k ++;
this->count.push_back(count);
}
}
if ( k == important.back() && oper.back() != ')') err = true;
int check=0;
for (int i = 0 ; i < oper.size(); i ++){
if (oper[i] == '(') check++;
if (oper[i] == ')') check--;
if (check < 0) err = true;
}
if (check > 0) err = true;
}