编写一个给出一串数字和目标值的函数,打印在数字之间放置+'和*的位置,使它们与目标值完全组合。请注意,可能有多个答案,无论您打印哪一个都无关紧要。
示例:
"1231231234",11353 -> "12*3+1+23*123*4"
"3456237490",1185 -> "3*4*56+2+3*7+490"
"3456237490",9191 -> "no solution"
答案 0 :(得分:8)
如果您有一个N位数值,则+或*运算符有N-1个可能的插槽。如此蛮力,有3 ^(N-1)种可能性。测试所有这些都是低效的。
BUT
您的示例全部为10位数。 3 ^ 9 = 19683,所以蛮力很精细!无需任何爱好者。
因此,您需要做的就是遍历所有19683个案例,每次为该案例构建一个字符串,并评估表达式。评估表达式是一项简单的任务。迭代是直截了当的(只需使用递增值,你可以通过(i%3)读取第一个槽的状态,这给你“无操作符”“+”或“*”,第二个槽的状态是(i / 3)%3,第三个时隙的状态是(i / 9)%3,依此类推。)
即使使用原始解析代码,CPU也很快。
蛮力选项在大约20位后开始变得难看,你必须切换到更聪明。
答案 1 :(得分:2)
如果这是针对游戏程序员的位置,请不要使用蛮力方法。我这样做但几年前失败了。后来从内部的人那里听到,动态编程方法就是获得这份工作的人。
答案 2 :(得分:1)
这可以通过回溯或动态编程来解决。
答案 3 :(得分:1)
“聪明的”方法(使用动态编程)基本上是这样的:
对于原始字符串的每个子字符串,找出它可以创建的所有可能值。 (例如,在你的第一个例子中,“12”可以变为1 + 2 = 3或1 * 2 = 2)
可能有很多不同的组合,但其中很多都是重复的。 (另外,您应该忽略所有大于目标的组合。)
因此,当您添加“+”或“*”时,您可以将其视为组合字符串的两个子字符串。 (并且因为你有每个子字符串的可能值,你可以看看是否可以这样组合)
可以类似地生成这些值:尝试以所有可能的方式分割子字符串,并在子字符串的每一半中组合不同的值。
然后,“状态”的总数类似于| S | ^ 2 * target - 对于您的示例情况,它比蛮力方法更糟。但是如果你有一个长度为1000的字符串和5000的目标,那么问题就可以通过动态编程来解决。
答案 4 :(得分:1)
Google Code Jam去年有一个问题的扩展版本(在Round 1C中),称为Ugly Numbers。您可以访问该链接,并在扩展为大量数字时,针对该问题的某些方法单击“竞赛分析”。