我正在尝试解决一个问题,我需要在数字之间插入数学运算(在这种情况下为+/-)或合并它们以获得请求的数字。
例如:123456789 => 123+4-5+6-7+8-9 = 120
我的概念基本上是在数组中生成不同的操作代码组合,并计算表达式,直到它等于某个数字。
问题是我想不出使用递归生成数学运算的所有可能组合的方法。
以下是代码:
#include <iostream>
#include <algorithm>
using namespace std;
enum {noop,opplus,opminus};//opcodes: 0,1,2
int applyOp(int opcode,int x, int y);
int calculate(int *digits,int *opcodes, int length);
void nextCombination();
int main()
{
int digits[9] = {1,2,3,4,5,6,7,8,9};
int wantedNumber = 100;
int length = sizeof(digits)/sizeof(digits[0]);
int opcodes[length-1];//math symbols
fill_n(opcodes,length-1,0);//init
while(calculate(digits,opcodes,length) != wantedNumber)
{
//recursive combination function here
}
return 0;
}
int applyOp(int opcode,int x, int y)
{
int result = x;
switch(opcode)
{
case noop://merge 2 digits together
result = x*10 + y;
break;
case opminus:
result -= y;
break;
case opplus:
default:
result += y;
break;
}
return result;
}
int calculate(int *digits,int *opcodes, int length)
{
int result = digits[0];
for(int i = 0;i < length-1; ++i)//elem count
{
result = applyOp(opcodes[i],result,digits[i+1]);//left to right, no priority
}
return result;
}
答案 0 :(得分:1)
关键是回溯。每个级别的递归句柄 一位数;另外,你会想要停止递归 一个你已经完成了。
最简单的方法是定义一个Solver
类
跟踪全局信息,如生成的字符串
到目前为止和运行总计,并做出递归函数
成员。基本上是这样的:
class Solver
{
std::string const input;
int const target;
std::string solution;
int total;
bool isSolved;
void doSolve( std::string::const_iterator pos );
public:
Solver( std::string const& input, int target )
: input( input )
, target( target )
{
}
std::string solve()
{
total = 0;
isSolved = false;
doSolve( input.begin() );
return isSolved
? solution
: "no solution found";
}
};
在doSolve
中,您必须首先检查您是否已完成
(pos == input.end()
):如果是,请设置isSolved = total == target
并立即返回;否则,尝试三种可能性,
(total = 10 * total + toDigit(*pos)
,total += toDigit(*pos)
,
和total -= toDigit(*pos)
),每次保存原件
total
和solution
,添加必要的文字
solution
,并使用递增的doSolve
调用pos
。
从递归调用返回时,如果! isSolved
,则恢复
以前的total
和solution
值,然后尝试下一个
可能性。只要看到isSolved
或全部,就会立即返回
三种可能性已经解决。