使用算术运算查找具有给定数字的目标数字

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 + *,不带括号。

要遍历每个可能的表达式,您只需排列数字,然后分散在运算符中。但是,您必须遵守两条规则:

在任何时候(从左到右阅读),您传递的运算符必须少于值 整个表达式的值必须恰好比运算符多一个

当然,您可以为前缀符号调整这些规则。

最简单的实现方式可能是一个递归函数,它尝试绘制一个值(无需替换)并将其推送到堆栈,并且还尝试(分别)从堆栈中弹出顶部的两个值,绘制一个随机操作(带替换),将该运算符应用于弹出的值并推送到堆栈顶部。函数递归,直到值池为空并且堆栈上只有一个值。

请注意,您当然会有很多冗余 - 我们完全忽略这些操作的任何关联/交换属性,您可能会缓存一组从值的子集产生的中间值,但这是完全不同的主题。

【讨论】:

以上是关于使用算术运算查找具有给定数字的目标数字的主要内容,如果未能解决你的问题,请参考以下文章

2017.031.数字电路与系统-算术逻辑单元

算术运算测试与猜数字游戏

算术运算的Rust泛型[重复]

如何将金额类型更改为数字类型以在javascript中执行算术运算

python-算术运算符复合赋值运算符

使用任意定义的字符在基本N数字系统上进行算术运算