使用算术运算查找具有给定数字的目标数字
Posted
技术标签:
【中文标题】使用算术运算查找具有给定数字的目标数字【英文标题】:Finding target number with given numbers using arithmetic operations 【发布时间】:2021-09-14 21:22:55 【问题描述】:我用 C++ 编写了一个程序,它尝试使用算术运算获得具有给定数字的目标值。大多数时候,有几种解决方案。找到其中之一就足够了。例如,目标号码是:410
,给定号码是:2,3,5,20,44,50
我的程序应该找到如下解决方案:(2*5)*(44-3)
但是,我的程序仅在最左边的表达式中添加括号。我的程序只能找到类似以下的解决方案:(((((2+3)+5)*44)+20)-50)
因此,有时我的程序虽然有解决方案却找不到解决方案。我应该如何改变我的算法?
这是我的代码:
#include <iostream>
#include <string>
using namespace std;
int TargetNumber = 302;
int Numbers[6];
bool isNumberUsed[6] = 0,0,0,0,0,0 ;
int calculate(int x, char operation, int y)
if (operation == '+')
return (x + y);
if (operation == '-')
return (x - y);
if (operation == '*')
return (x * y);
if (operation == '/' && y != 0 && x%y == 0)
return (x / y);
bool isSolutionFound = 0, isOperationUsed = 0;
std::string answer = "";
int result;
void searchSolution(int TargetNumber, std::string term, int value)
if (TargetNumber == value)
isSolutionFound = 1;
answer = term;
return;
for (int a = 0; a < 6; a++)
for (int b = 0; b < 4; b++)
isOperationUsed = 0;
if (isNumberUsed[a] == 1)
isNumberUsed[a] = 0;
if (b == 0)
result = calculate(value, '+', Numbers[a]);
isOperationUsed = 1;
if (b == 1)
result = calculate(value, '-', Numbers[a]);
isOperationUsed = 1;
if (b == 2)
result = calculate(value, '*', Numbers[a]);
isOperationUsed = 1;
if (b == 3 && (value % Numbers[a] == 0) && Numbers[a] != 0)
result = calculate(value, '/', Numbers[a]);
isOperationUsed = 1;
if (isOperationUsed == 1 && isSolutionFound == 0)
if (b == 0)
searchSolution(TargetNumber, "(" + term + "+" + std::to_string(Numbers[a]) + ")", result);
if (b == 1)
searchSolution(TargetNumber, "(" + term + "-" + std::to_string(Numbers[a]) + ")", result);
if (b == 2)
searchSolution(TargetNumber, "(" + term + "*" + std::to_string(Numbers[a]) + ")", result);
if (b == 3)
searchSolution(TargetNumber, "(" + term + "/" + std::to_string(Numbers[a]) + ")", result);
isNumberUsed[a] = 1;
int main()
TargetNumber = 302;
string inputstring = "2 3 7 10 25 50";
int ConvertToInt = 0, ArrayIndex = 0;
for (int a = 0; a < inputstring.length(); a++) // Taking values from string & changing to int
if (inputstring[a] != ' ')
if (ConvertToInt == 0)
ConvertToInt = inputstring[a] - '0';
else
ConvertToInt = ConvertToInt * 10 + inputstring[a] - '0';
if (inputstring[a] == ' ')
Numbers[ArrayIndex] = ConvertToInt;
ConvertToInt = 0;
ArrayIndex++;
Numbers[ArrayIndex] = ConvertToInt; // For the last number in the string
for (int i = 0; i < 6; i++)
isNumberUsed[i] = 0;
searchSolution(TargetNumber, std::to_string(Numbers[i]), Numbers[i]);
isNumberUsed[i] = 1;
if (answer == "")
answer = "No Solution";
cout << answer<<"\n";
【问题讨论】:
获取数字列表并创建每个长度的排列列表。然后在一个循环中,通过替换运算符的每个组合来从每个表达式中生成每个表达式。用括号将这些表达式括起来。然后递归地执行此操作,直到找到解决方案。所以 2,3,5,20,44,50 会产生很多带括号的表达式,包括你需要的两个:(2*5)
和 (44-3)
但是因为你是递归地做它,下一个级别将是一个包含带括号的表达式 - 包括您要查找的表达式:((2*5)*(44-3))
【参考方案1】:
解决此问题的最简单方法是避免使用中缀表示法,在这种情况下需要显式括号,而使用前缀或后缀表示法。例如,考虑表达式2 * (3 + 4)
。我们可以用后缀表示法将其重写为2 3 4 + *
,不带括号。
要遍历每个可能的表达式,您只需排列数字,然后分散在运算符中。但是,您必须遵守两条规则:
在任何时候(从左到右阅读),您传递的运算符必须少于值 整个表达式的值必须恰好比运算符多一个当然,您可以为前缀符号调整这些规则。
最简单的实现方式可能是一个递归函数,它尝试绘制一个值(无需替换)并将其推送到堆栈,并且还尝试(分别)从堆栈中弹出顶部的两个值,绘制一个随机操作(带替换),将该运算符应用于弹出的值并推送到堆栈顶部。函数递归,直到值池为空并且堆栈上只有一个值。
请注意,您当然会有很多冗余 - 我们完全忽略这些操作的任何关联/交换属性,您可能会缓存一组从值的子集产生的中间值,但这是完全不同的主题。
【讨论】:
以上是关于使用算术运算查找具有给定数字的目标数字的主要内容,如果未能解决你的问题,请参考以下文章