Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编写C++;代数游戏24的版本 我试图编写一个C++程序,它像游戏24一样工作。对于那些不知道它是如何播放的人,基本上你可以通过四个代数运算符+,-,/,*,和括号找到4个数字总共24个的方法_C++ - Fatal编程技术网

编写C++;代数游戏24的版本 我试图编写一个C++程序,它像游戏24一样工作。对于那些不知道它是如何播放的人,基本上你可以通过四个代数运算符+,-,/,*,和括号找到4个数字总共24个的方法

编写C++;代数游戏24的版本 我试图编写一个C++程序,它像游戏24一样工作。对于那些不知道它是如何播放的人,基本上你可以通过四个代数运算符+,-,/,*,和括号找到4个数字总共24个的方法,c++,C++,例如,假设某人输入2,3,1,5 ((2+3)*5)-1=24 由于括号的位置数量有限,对函数进行编码以确定三个数字是否等于24是相对简单的,但我无法计算在输入四个变量时如何有效地进行编码 我现在有一些排列,但我仍然不能列举所有的情况,因为我不知道如何为操作相同的情况编码 此外,计算RPN的最简单方法是什么?我看到了很多这样的页面: 但是作为一个初学者,我不知道如何实现它 #include <iostream> #include <vector> #include &l

例如,假设某人输入2,3,1,5 ((2+3)*5)-1=24

由于括号的位置数量有限,对函数进行编码以确定三个数字是否等于24是相对简单的,但我无法计算在输入四个变量时如何有效地进行编码


我现在有一些排列,但我仍然不能列举所有的情况,因为我不知道如何为操作相同的情况编码

此外,计算RPN的最简单方法是什么?我看到了很多这样的页面: 但是作为一个初学者,我不知道如何实现它

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;





bool MakeSum(int num1, int num2, int num3, int num4)
{

  vector<int> vi;
  vi.push_back(num1);
  vi.push_back(num2);
  vi.push_back(num3);
  vi.push_back(num4);

  sort(vi.begin(),vi.end());


  char a1 = '+';
  char a2 = '-';
  char a3 = '*';
  char a4 = '/';
  vector<char> va;
  va.push_back(a1);
  va.push_back(a2);
  va.push_back(a3);
  va.push_back(a4);

  sort(va.begin(),va.end());
  while(next_permutation(vi.begin(),vi.end()))
    {

      while(next_permutation(va.begin(),va.end()))
    {

      cout<<vi[0]<<vi[1]<<vi[2]<<vi[3]<< va[0]<<va[1]<<va[2]<<endl;

      cout<<vi[0]<<vi[1]<<vi[2]<<va[0]<< vi[3]<<va[1]<<va[2]<<endl;

      cout<<vi[0]<<vi[1]<<vi[2]<<va[0]<< va[1]<<vi[3]<<va[2]<<endl;

      cout<<vi[0]<<vi[1]<<va[0]<<vi[2]<< vi[3]<<va[1]<<va[2]<<endl;

      cout<<vi[0]<<vi[1]<<va[0]<<vi[2]<< va[1]<<vi[3]<<va[2]<<endl; 


    }

    }

  return 0;

}

int main()
{

  MakeSum(5,7,2,1);
  return 0;
}
#包括
#包括
#包括
使用名称空间std;
bool MakeSum(int num1、int num2、int num3、int num4)
{
向量vi;
vi.推回(num1);
vi.推回(num2);
vi.推回(num3);
vi.推回(num4);
排序(vi.begin(),vi.end());
字符a1='+';
字符a2='-';
字符a3='*';
字符a4='/';
向量va;
va.推回(a1);
va.推回(a2);
va.推回(a3);
va.推回(a4);
排序(va.begin(),va.end());
while(下一个置换(vi.begin(),vi.end())
{
while(下一个置换(va.begin(),va.end())
{

cout我以前写过类似的东西。你需要一个递归求值器。当你点击“(“再次调用求值,否则与数字和运算符一起运行,直到点击”)”时,现在返回-+*/运算的结果,上面的求值实例

查找背包问题(这里有一个链接让你开始:),这个问题非常接近,只是稍微难一点(背包问题是NP完全问题!)

有一件事可能会使它比正常情况下更快。检查。使用这个,一次执行多个检查(您的“alg”函数),因此如果您有双核/四核cpu,您的程序应该更快

也就是说,如果如上所述,问题是NP完全的,那么它会更快,不一定快。

您可以使用生成可能的表达式,这将消除对偏执的需要

一个绝对简单的方法是生成所有可能的4位数字和3个运算符的字符串(不考虑RPN的有效性),假设它在RPN中,并尝试对其进行评估。您会遇到一些错误情况(如无效RPN字符串)。可能的总数(如果我计算正确的话)约为50000

我认为,更聪明的方法应该是将其降到7500左右(准确地说是64*24*5):生成数字排列(24种方式),生成3个运算符的三元组(4^3=64种方式),现在将运算符放在数字之间,使其成为有效的RPN(有5种方式,请参见Omnifarious的“答案”)

您应该能够在web上轻松找到置换生成器和RPN计算器

希望有帮助


PS:仅供参考:RPN只不过是对应表达式树的后序遍历,对于d个数字,数字是d!*4^(d-1)*选择(2(d-1),(d-1))/d。(最后一项是加泰罗尼亚数字)下面的解决方案是错误的。我们还需要考虑仅用XY2和XY4生成的数字,以及XX1和XY4。这种方法仍然可以工作,但是它会更复杂(甚至更不有效)。抱歉……/P>
假设我们有四个数字x_1,x_2,x_3,x_4

S = { all numbers we can make just using x_3, x_4 },
然后我们可以重写我们感兴趣的集合,我会调用它

T = { all numbers we can make using x_1, x_2, x_3, x_4 }
作为

因此,一种算法是生成S中所有可能的数字,然后依次使用S中的每个数字来生成T的一部分(这将相当容易地推广到n个数字,而不仅仅是4个)

下面是一个粗略的、未经测试的代码示例:

#include <set> // we can use std::set to store integers without duplication
#include <vector> // we might want duplication in the inputs

// the 2-number special case
std::set<int> all_combinations_from_pair(int a, int b)
{
  std::set results;

  // here we just use brute force
  results.insert(a+b);  // = b+a
  results.insert(a-b);
  results.insert(b-a);
  results.insert(a*b);  // = b*a
  // need to make sure it divides exactly
  if (a%b==0) results.insert(a/b);
  if (b%a==0) results.insert(b/a);

  return results;   
}

// the general case
std::set<int> all_combinations_from(std::vector<int> inputs)
{
  if (inputs.size() == 2) 
  {
    return all_combinations_from_pair(inputs[0], inputs[1]);
  }
  else
  {
    std::set<int> S = all_combinations_from_pair(inputs[0], inputs[1]);
    std::set<int> T;
    std::set<int> rest = S;
    rest.remove(rest.begin());
    rest.remove(rest.begin()); // gets rid of first two

    for (std::set<int>.iterator i = S.begin(); i < S.end(); i++)
    {
      std::set<int> new_inputs = S;
      new_inputs.insert(*i);
      std::set<int> new_outputs = all_combinations_from(new_inputs);

      for (std::set<int>.iterator j = new_outputs.begin(); j < new_outputs.end(); j++)
        T.insert(*j); // I'm sure you can do this with set_union()
    }

    return T;
  }
}
#include//我们可以使用std::set来存储整数,而不需要重复
#include//我们可能需要在输入中重复
//2号特例
std::设置所有来自\u对的\u组合(int a、int b)
{
设置结果;
//这里我们只是使用暴力
结果.插入(a+b);/=b+a
结果:插入(a-b);
结果:插入(b-a);
结果.插入(a*b);//=b*a
//需要确保它准确地分开
如果(a%b==0)结果。插入(a/b);
如果(b%a==0)结果。插入(b/a);
返回结果;
}
//一般情况
std::从(std::矢量输入)设置所有_组合
{
if(inputs.size()==2)
{
从_对返回所有_组合_(输入[0],输入[1]);
}
其他的
{
std::set S=来自_对的所有_组合(输入[0],输入[1]);
std::set T;
std::设置rest=S;
rest.remove(rest.begin());
rest.remove(rest.begin());//去掉前两个
对于(std::set.iterator i=S.begin();i因此,最简单的方法是排列所有可能的组合。这有点棘手,数字的顺序可能很重要,当然操作的顺序也很重要

一个观察结果是,您正在尝试生成具有特定属性的所有可能表达式树。一个属性是,该树将始终具有恰好4片叶子。这意味着该树也将始终具有正好3个内部节点。此类树只有3种可能的形状:

  A
 / \
 N  A
   / \      (and the mirror image)
  N   A
     / \
    N   N

  A
 / \
N   A
   / \
  A   N   (and the mirror image)
 / \
N   N

     A
   /` `\
  A     A
 / \   / \
N  N  N  N
在A的每个点中,您可以执行4个操作中的任意一个。在N的每个点中,您可以执行任意一个数字。但每个数字只能显示一个N

将其编码为蛮力搜索应该不会太难,我认为在您完成任务后
  A
 / \
 N  A
   / \      (and the mirror image)
  N   A
     / \
    N   N

  A
 / \
N   A
   / \
  A   N   (and the mirror image)
 / \
N   N

     A
   /` `\
  A     A
 / \   / \
N  N  N  N
N N N N A A A
N N N A N A A
N N N A A N A
N N A N N A A
N N A N A N A
6807900 <= equation of form ( 6 @ 8 ) @ ( 7 @ 9 )
100110 <= replace @'s with (-,-,/)
possibility is (6-8)-(7/9)