题目
思路
思路决定成败,心态可以说一度很崩了。
第一种思路:
复杂标记的数组。不要考虑
第二种思路:
符号栈+数栈。栈便于符号的紧前比较,及时运算。分开两个栈的原因是数据类型的不同。
第三种思路:
数栈,而符号灵活处理。节省了栈的空间以及栈上的操作时间。
思路三归纳总结
这里的数字没什么规律可言,而符号却是突破口。
- “+” 和 “-”,可以节约成紧后数的正负号,而不代表本意的运算符。
- . “ * ” 和 “ / ” ,进行及时运算。
用到的一些操作
- stoi(string to int)用法:int temp=stoi(str);
- stack的push\pop\top\empty\size
Deficiency
运算快,逻辑清晰的代码往往很少很精。
现在冗长的原因有思路不够开阔,用法不够简短。
这些的根源,应该还是做题少吧…
leetcode目前来看像是补充课内不足的一个手段,要珍惜机会认真对待!
代码
- 两个栈,不要写成这样
class Solution
{
public:
int calculate(string s)
{
stack<char> sym;
stack<int> opr;
sym.push('#');
for (int i = 0; i < s.length(); i++)
{
char ch = s[i];
switch (ch)
{
case ' ':
break;
case '+':
case '-':
{
char topnow = sym.top();
while (topnow == '*' || topnow == '/' || topnow == '+' || topnow == '-')
{
sym.pop();
int a2 = opr.top();
opr.pop();
int a1 = opr.top();
opr.pop();
switch (topnow)
{
case '+':
opr.push(a1 + a2);
break;
case '-':
opr.push(a1 - a2);
break;
case '*':
opr.push(a1 * a2);
break;
case '/':
opr.push(a1 / a2);
break;
}
topnow = sym.top();
}
sym.push(ch);
break;
}
case '*':
case '/':
{
if (sym.top() == '*')
{
sym.pop();
int a2 = opr.top();
opr.pop();
int a1 = opr.top();
opr.pop();
opr.push(a1 * a2);
sym.push(ch);
}
else if (sym.top() == '/')
{
sym.pop();
int a2 = opr.top();
opr.pop();
int a1 = opr.top();
opr.pop();
opr.push(floor(a1 / a2));
sym.push(ch);
}
else
sym.push(ch);
break;
}
default:
{
string num = "";
while (ch >= '0' && ch <= '9')
{
num += ch;
i++; //越界
ch = s[i];
}
i--;
stringstream ss;
ss << num;
int temp = 0;
ss >> temp;
opr.push(temp);
break;
}
}
}
while (sym.top() != '#')
{
char topnow2 = sym.top();
sym.pop();
int a2 = opr.top();
opr.pop();
int a1 = opr.top();
opr.pop();
switch (topnow2)
{
case '+':
opr.push(a1 + a2);
break;
case '-':
opr.push(a1 - a2);
break;
case '*':
opr.push(a1 * a2);
break;
case '/':
opr.push(a1 / a2);
break;
}
}
return opr.top();
}
};
- 一个栈
class Solution
{
public:
int calculate(string s){
stack<int> num;
int index = 0;
if( !s.empty())
{
while( (index = s.find(' ',index)) != string::npos)
{
s.erase(index,1);
}
}
for(int i=0;i<s.length();i++)
{
char ch=s[i];
string opr="";
if(ch>='0'&&ch<='9'){
while(ch>='0'&&ch<='9')
{
opr+=ch;i++;ch=s[i];
}
i--;
num.push(stoi(opr));
}
else if(ch==' '||ch=='+')
continue;
else if(ch=='-')
{
i++;ch=s[i];opr+='-';
while(ch>='0'&&ch<='9')
{
opr+=ch;i++;ch=s[i];
}
i--;
num.push(stoi(opr));
}
else if(ch=='*'||ch=='/')
{
char chk=ch;i++;ch=s[i];
while(ch>='0'&&ch<='9')
{
opr+=ch;i++;ch=s[i];
}
i--;
int temp=stoi(opr);
if(chk=='*'){
int k=temp*num.top();
num.pop();
num.push(k);
}
else if(chk=='/'){
int k=num.top()/temp;
num.pop();
num.push(k);
}
}
}
int sum=0;
while(!num.empty()){
sum+=num.top();
num.pop();
}
return sum;
}
};
彩蛋?
StefanPochmann老兄的日常骚操作,只求最短不求最快。
- 事实上也不需要栈,顺序处理即可
- 加减号左边的加到sum里面
- 乘除法让下一个数与存的数做运算
need a tool ! 快速、简短取数
istringstream
将不同类型数据自动拆分
int test(string s){
istringstream ss('+'+s);
int i=0;
char p='';
while(ss>>p)
{
ss>>i;
cout<<p<<" "<<i<<" "<<endl;
}
}
+ 1
* 2
- 3
/ 4
+ 5
* 6
- 7
* 8
+ 9
/ 10