1.计算器
实现一个计算器,可以计算+、-、*、/ 四则运算,允许表达式中有括号,且“-”可以作为一元运算符出现。
例:(-1-1)*2+ 3 *(4/2)
主函数为calculate函数,输入为表达式,返回值是运算结果。
class Solution {
//$,+,-,*,/,(
char table[6][6]={
{'<','<','<','<','<','<'},
{'>','<','<','<','<','>'},
{'>','<','<','<','<','>'},
{'>','>','>','<','<','>'},
{'>','>','>','<','<','>'},
{'>','<','<','<','<','<'}
};
int optovalue(char s){
switch(s){
case '+':return 1;
case '-':return 2;
case '*':return 3;
case '/':return 4;
case '(':return 5;
default: return 0;
}
}
public:
int calculate(string s) {
stack<string> nums;//存数字
stack<string> op;//存运算符
op.push("$");
char last='$';
for(int i=0;i<s.size();i++){
if(s[i]-'0'>=0&&s[i]-'0'<=9){
string temp;
temp+=s[i];
while(i+1<s.size()&&s[i+1]-'0'>=0&&s[i+1]-'0'<=9){
i++;
temp+=s[i];
}
nums.push(temp);
}
else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'){
if(last=='('||last=='$'){
nums.push("0");
}
string temp=op.top();
while(table[optovalue(s[i])][optovalue(temp[0])]!='>'){
nums.push(temp);
op.pop();
temp=op.top();
}
op.push(string(1,s[i]));
}
else if(s[i]=='('){
op.push(string(1,s[i]));
}
else if(s[i]==')'){
string temp=op.top();
while(temp!="("){
nums.push(temp);
op.pop();
temp=op.top();
}
op.pop();
}
last=s[i];
}
while(op.top()!="$"){
string temp=op.top();
nums.push(temp);
op.pop();
temp=op.top();
}
stack<string> res;
while(!nums.empty()){
// cout<<nums.top()<<" ";
res.push(nums.top());
nums.pop();
}
if(res.size()==1)
return stoi(res.top());
while(1){
if(res.top()!="+"&&res.top()!="-"&&res.top()!="*"&&res.top()!="/"){
nums.push(res.top());
res.pop();
}
else{
string temp=res.top();
res.pop();
int a=stoi(nums.top());
nums.pop();
int b=stoi(nums.top());
nums.pop();
int c;
switch(temp[0]){
case '+':c=b+a;break;
case '-':c=b-a;break;
case '*':c=b*a;break;
case '/':c=b/a;break;
default:break;
}
res.push(to_string(c));
if(res.size()==1)
break;
}
}
return stoi(res.top());
}
};
2.猜算式
看下面的算式: □□ x □□ = □□ x □□□ 它表示:两个两位数相乘等于一个两位数乘以一个三位数。
如果没有限定条件,这样的例子很多。 但目前的限定是:这9个方块,表示1~9的9个数字,不包含0。 该算式中1至9的每个数字出现且只出现一次!
比如:
46 x 79 = 23 x 158
54 x 69 = 27 x 138
54 x 93 = 27 x 186 ……
请编程,输出所有可能的情况!
注意:左边的两个乘数交换算同一方案,不要重复输出!
回溯
#include <bits/stdc++.h>
using namespace std;
vector<string> ans;
bool check(int a, int b, int c, int d) {
if (a * b == c * d)
return true;
return false;
}
void dfs(vector<int> A,int step) {
if (step == A.size()) {
int a = A[0] * 10 + A[1], b = A[2] * 10 + A[3];
int c = A[4] * 10 + A[5], d = A[6] * 100 + A[7] * 10 + A[8];
if (a > b)
swap(a, b);
if (check(a, b, c, d)) {
string s = to_string(a) + 'x' + to_string(b) + '=' + to_string(c) + "x" + to_string(d);
if(find(ans.begin(),ans.end(),s)==ans.end())
ans.push_back(s);
}
}
else {
for (int i = step; i < A.size(); i++) {
swap(A[i], A[step]);
dfs(A, step + 1);
swap(A[i], A[step]);
}
}
}
int main() {
vector<int> A = { 1,2,3,4,5,6,7,8,9 };
dfs(A, 0);
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << endl;
return 0;
}
回溯backtracking函数套路:
path为路径,list为可选列表
list ans;
void backtracking(path, list){
if(满足条件){
list.add(path);
return;
}
for(选择:list){
path.add(选择);
backtracking(path,list);
path.erase(选择);
}
}