Given a string of numbers and operators, return all possible results
from computing all the different possible ways to group numbers and
operators. The valid operators are +, - and *.Example 1
Input: “2-1-1”.
((2-1)-1) = 0
(2-(1-1)) = 2Output: [0, 2]
Example 2
Input: “2*3-4*5”
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10Output: [-34, -14, -10, -10, 10]
大意:
给定一个数字和操作符的字符串,返回所有运算顺序的结果。
思路:
分治。
分:递归地将一个字符串分成 左操作数,操作符,右操作数,直到这个字符串只剩一个操作数。
治:返回对左操作数序列与右操作数序列的笛卡儿积应用对应操作符产生的序列。
实现:
/*糟糕的实现QAQ*/
#define M 10003
#define OP(op,a,b) (op=='+'?a+b:op=='-'?a-b:a*b)
class Solution {
public:
vector<int> nums, ops;
void calc(int op, int a, int b, int right, vector<int>&rst){
vector<int> l,r;
if(op - a < 2) l.push_back(op-a?OP(ops[op-1],nums[a],nums[a+1]):nums[a]);
else{
vector<int> tp;
for(int i = a;i<op;i++){
tp.clear();
calc(i,a,i+1,op,tp);
for(int i = 0;i<tp.size();i++)
l.push_back(tp[i]);
}
}
if(right - b < 2) r.push_back(right - b?OP(ops[op+1],nums[b],nums[b+1]):nums[b]);
else{
vector<int> tp;
for(int i = b;i<right;i++){
tp.clear();
calc(i,b,i+1,right,tp);
for(int i = 0;i<tp.size();i++)
r.push_back(tp[i]);
}
}
for(int i = 0;i<l.size();i++)
for(int j = 0;j<r.size();j++)
rst.push_back(OP(ops[op],l[i],r[j]));
}
vector<int> diffWaysToCompute(string input) {
vector<int> rst;
int a;
for(int i = a = 0;input[i];i++){
if(input[i] == '+' || input[i] == '-' || input[i] == '*'){
ops.push_back(input[i]);
nums.push_back(a);
a = 0;
}
else a=a*10+input[i]-'0';
}
nums.push_back(a);
for(int i = 0;i<ops.size();i++)
calc(i,0,i+1,nums.size()-1,rst);
if(!rst.size()) rst.push_back(nums[0]);
return rst;
}
};