简单计算器的实现

时间:2022-12-29 14:48:40

计算器

问题描述: 输入一个简单四则运算表达式字符串,计算该表达式的值 


注: 
1、表达式只含 +, -, *, /, (, ), 四则运算符 
2、表达式数值只包含整数(0-9),每个操作数可以是多位,且不会出现0作为除数的情况 
3、要考虑加减乘除按通常四则运算规定的计算优先级 
4、除法用整数除法,即仅保留除法运算结果的整数部分。比如80/3=26。输入表达式保证无0作为除数情况发生 
5、输入字符串一定是符合题意合法的表达式,其中只包括数字字符和四则运算符字符,除此之外不含其它任何字符,不会出现计算溢出情况


要求实现函数:  
int calculate(int len,char *expStr) 


【输入】 int len: 字符串长度; char *expStr: 表达式字符串; 
【输出】 无 
【返回】 计算结果  
• 示例  
1) 输入:char *expStr = “-3*(-200)-(-3*(-5-2*10)/(4+3-17)*9)” 

      函数返回:663
2) 输入:char *expStr = “8/3*3”

      函数返回:6



#include "stdafx.h"
#include<vector>
#include<deque>
#include<iostream>
using namespace std;


char*vec2char(vector<char>vec, char*str)
{
char*s = str;
vector<char>::iterator it;
it = vec.begin();
while (it != vec.end())
*(s++) = *(it++);
*s = '\0';
return str;
}

//计算不带括号的表达式的值
int calculate_without_bracket(vector<char>&substr)
{
vector<char>::iterator it, it1, it2, iter;
char*str = new char[100];
it = substr.begin();
while (it != substr.end())
{
deque<int>bb;
deque<int>::iterator p;
int aa;
//因为每次去括号时,都会对多个“-”
//号进行合并,这里不会出现多于两个“-”相连的情况
if (*substr.begin() == '-')
{
if (*(substr.begin() + 1) == '-')
{
substr.erase(substr.begin(), substr.begin() + 2);
it = substr.begin();
}
}
if (*it == '*' || *it == '/')
{
bool flag1 = false;
bool flag2 = false;
int f1 = 0, f2 = 0;
it1 = it - 1;

int gg = 0;
while (*it1 - '0' >= 0 && *it1 - '0' <= 9 && it1 - substr.begin() >= 0)
{
gg++;
bb.push_front(*it1 - '0');
if (it1 == substr.begin())
break;
it1--;
}
if (it1 != substr.begin())
{
if (*it1 == '-')
{
if (*(it1 - 1) == '-')
if (it1 - 1 == substr.begin())
{
substr.erase(substr.begin(), substr.begin() + 2);
it = substr.begin() + gg;
it1 = substr.begin();
}
else
{
it1 = it1 - 2;
substr.erase(it1 + 1, it1 + 3);
substr.insert(it1 + 1, '+');
it1 = it1 + 2;
it = it1 + gg;
}
else if (*(it1 - 1) == '+')//这一次的乘除运算之前不可能出现别的“*”或“/”
{
it1 = it1 - 2;
substr.erase(it1 + 1, it1 + 3);
substr.insert(it1 + 1, '-');
it1 = it1 + 2;
it = it1 + gg;
}
else
it1++;
}

}
else if (it1 == substr.begin() && *it1 == '-')
it1++;
it2 = it + 1;
if (*it2 == '-')
{
flag1 = true;
it2++;
}
p = bb.begin();
while (p != bb.end())
{
f1 = *p + 10 * f1;
++p;
}
while (it2 != substr.end() && *it2 - '0' >= 0 && *it2 - '0' <= 9)
{
f2 = 10 * f2 + (*it2 - '0');
it2++;
}
if (*it == '*')
aa = f1*f2;
else
aa = f1 / f2;
if (flag1)
aa = -aa;
char*ss = new char[100];
_itoa(aa, ss, 10);
if (it1 == substr.begin())
{
int c = 0;
substr.erase(it1, it2);
while (*ss != '\0')
{
substr.insert(substr.begin() + c, *ss);
++ss;
++c;
}
it = substr.begin();
}
else
{
int c = 0;
iter = it1 - 1;
substr.erase(it1, it2);
while (*ss != '\0')
{
substr.insert(iter + 1 + c, *ss);
++ss;
++c;
}
//substr.insert(iter + 1, aa+'0');
it = iter + 1;
}
}
else
{

it++;
}
//if (substr.size() == 1)
// return (*substr.begin() - '0');
}
it = substr.begin();
while (it != substr.end())
{

deque<int>bb;
deque<int>::iterator p;
int aa;
if (*substr.begin() == '-')
{
if (*(substr.begin() + 1) == '-')
{
substr.erase(substr.begin(), substr.begin() + 2);

}
else
{
bool flag2 = false;
int f1 = 0, f2 = 0;
it1 = substr.begin() + 1;

while (*it1 - '0' >= 0 && *it1 - '0' <= 9)
{
bb.push_back(*it1 - '0');
it1++;
if (it1 == substr.end())
{
char*src = new char[100];
return atoi(vec2char(substr, src));
}
}

p = bb.begin();
while (p != bb.end())
{
f1 = *p + 10 * f1;
++p;
}
it = it1;
it2 = it + 1;
if (*it2 == '-')//因为每次去括号时,都会对多个“-”
//号进行合并,这里不会出现多于两个“-”相连的情况
{
it2++;
flag2 = true;
}
while (it2 != substr.end() && *it2 - '0' >= 0 && *it2 - '0' <= 9)
{
f2 = 10 * f2 + (*it2 - '0');
it2++;
}
if (*it == '+')
if (flag2)
aa = -f1 - f2;
else
aa = -f1 + f2;
else
if (flag2)
aa = -f1 + f2;
else
aa = -f1 - f2;
char*ss = new char[100];
_itoa(aa, ss, 10);
int c = 0;
substr.erase(substr.begin(), it2);
while (*ss != '\0')
{
substr.insert(substr.begin() + c, *ss);
++ss;
++c;
}
//substr.insert(substr.begin(), aa + '0');
it = substr.begin();

}
}
else if
//因为每次都是从左到右一次只计算两个数,除了第一个符号是“-”外,另一种
//情况下第一个操作数一定是正数,只需考虑第二个操作数的符号
(*it == '+' || *it == '-')
{
bool flag1 = false;
int f1 = 0, f2 = 0;
it1 = it - 1;
it2 = it + 1;
if (*it2 == '-')
{
flag1 = true;
it2++;
}
while (*it1 - '0' >= 0 && *it1 - '0' <= 9 && it1 - substr.begin() >= 0)
{
bb.push_front(*it1 - '0');
if (it1 == substr.begin())
break;
it1--;
}
if (it1 != substr.begin())
it1++;
p = bb.begin();
while (p != bb.end())
{
f1 = *p + 10 * f1;
++p;
}
while (it2 != substr.end() && *it2 - '0' >= 0 && *it2 - '0' <= 9)
{
f2 = 10 * f2 + (*it2 - '0');
it2++;
}
if (*it == '+')
if (flag1)
aa = f1 - f2;
else
aa = f1 + f2;
else
if (flag1)
aa = f1 + f2;
else
aa = f1 - f2;
char*ss = new char[100];
_itoa(aa, ss, 10);
if (it1 == substr.begin())
{
int c = 0;
substr.erase(it1, it2);
while (*ss != '\0')
{
substr.insert(substr.begin() + c, *ss);
++ss;
++c;
}
//substr.insert(substr.begin(), aa + '0');
it = substr.begin();
}
else
{
//iter = it - 2;
//substr.erase(it - 1, it + 2);
//substr.insert(iter + 1, aa + '0');
//it = iter + 1;
int c = 0;
iter = it1 - 1;
substr.erase(it1, it2);
while (*ss != '\0')
{
substr.insert(iter + 1 + c, *ss);
++ss;
++c;
}
it = iter + 1;
}

}
else
{
it++;
}
}

return atoi(vec2char(substr, str));
}





//去括号,每次找到第一对连续匹配的括号,然后用calculate_without_bracket函数
//计算括号里的表达式的值,计算后的结果插入原表达式,返回true。
//如果原表达式没有括号,返回false
bool erase_bracket(vector<char>&str)
{
int size = str.size();
bool flag = false;
int k = 0;
int m, n;
vector<char>::iterator it, it1, it2;
it = str.begin();
while (k < size)
{
if (str[k] == '(')
{
m = k;
k++;
while (str[k] != '('&&str[k] != ')')
k++;
if (str[k] == ')')
{
n = k;
flag = true;
break;
}
else if (str[k] == '(')
{
k--;
}

}
else
{
k++;
}
}
if (flag)
{
vector<char>sub;
for (int i = m+1; i < n ; i++)
sub.push_back(str[i]);
calculate_without_bracket(sub);
it = it + m - 1;
for (int i = 0; i < n + 1 - m;i++)
str.erase(it + 1, (it + 2 ));
int k = 0;
int len = sub.size();
while (k < len)
{
str.insert(it + k + 1, sub[k]);
k++;
}
}

return flag;
}



/*vector<char>char2vec(vector<char>&vec, char*str)
{
while (*str != '\0')
{
vec.push_back(*str);
++str;
}
return vec;
}*/


//整体表达式计算函数,每次调用erase_bracket函数先计算括号里的值
//直到消除所有的括号,最后调用calculate_without_bracket计算剩下的无括号表达式的值
int calculate(int len, char *expStr)
{
vector<char>str;
for (int i = 0; i < len; i++)
str.push_back(expStr[i]);
bool flag = true;

while (flag)
{
flag = erase_bracket(str);
}

return calculate_without_bracket(str);

}




int _tmain(int argc, _TCHAR* argv[])
{
/*vector<int>aa;
vector<int>::iterator it,ite;
for (int i = 0; i < 5; i++)
aa.push_back(i);
it = aa.begin()+3;
ite = it -2;
aa.erase(it-1,it+1);
aa.insert(ite+1, 9);*/


vector<char>vec;
//char2vec(vec, "2+10-30-2*9/4+3-7*9");
//cout << calculate_without_bracket(vec) << endl;
//int len=strlen("2+(5-14-2)*9/(4+3-17)*9");
int len = strlen("-3*(-200)-(-3*(-5-2*10)/(4+3-17)*9)");
cout << calculate(len, "-3*(-200)-(-3*(-5-2*10)/(4+3-17)*9)");

system("pause");
return 0;
}