【问题标题】:Recursive for-loop for Mastermind algorithm in C++C++中Mastermind算法的递归for循环
【发布时间】:2020-06-30 10:23:48
【问题描述】:

我想为 Mastermind 算法创建一个数字池 (https://www.swtestacademy.com/algorithms-mastermind/)。池应包含大小为 n 的 Mastermind 代码的所有可能组合。例如,当 n = 4 时,池应如下所示:

[0000][0001][0002] ....[5555]

n = 5

[00000] .... [55555]

其中每个数字代表主谋解决方案中的一种颜色。因此,例如 [3101] 将是红色、蓝色、白色、蓝色。

我做了一个函数来创建一个 n = 4 的池:

vector<string> createPool4()
{
    vector<string> pool;

    for (int i = 0; i < colours; i++)
        for (int j = 0; j < colours; j++)
            for (int k = 0; k < colours; k++)
                for (int l = 0; l < colours; l++)
                    pool.push_back(to_string(i) + to_string(j) + to_string(k) + to_string(l));

    return pool;
}

我当时尝试的是将此函数转换为某种递归嵌套的 for 循环,但是,请自行寻找:

vector<string> fillPool(int n, vector<string> pool, const string& s) {

    if (n == 0) {
        pool.push_back(s);
        s.clear();
        return pool;

    }

    for (int i = 0; i < n; i++) {
        s += to_string(i);
        pool = fillPool(n-1,pool,s);
    }
}

此代码不起作用,它应该只显示我要去的方向。

总而言之,我需要一个可以采用维度 n 的函数,然后创建一个可能的代码列表。到目前为止,我一直在使用字符串向量,但我很高兴听到其他可能性。

也许有人可以帮我解决这个问题,因为我知道在某个地方,有一个非常好的解决方案。

谢谢!

【问题讨论】:

  • 您使用池作为输入并用结果覆盖它......如果这没有以一种很酷的方式进行优化,那么您有很多池副本。也许有一个参考池来修改会更好。
  • 我看不出将s 设为常量引用的意义。您正在修改字符串(通过添加另一个字符),因此它不是 const 引用。我认为你应该重视它。

标签: c++ eclipse algorithm for-loop recursion


【解决方案1】:

这可以通过组合和排列来解决。

这个想法是:

  1. 为给定的nnumberOfColours 创建所有可能的组合。
  2. 为每个组合创建所有不同的排列,将其附加到组合中,然后删除所有重复项。

这个question 对如何进行组合有一些很好的答案。将 Rosetta 代码中的 solutionsolution 分别放在一起进行组合和排列,可以这样解决问题:

#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

using namespace std;

void permutation(string str, vector<string> *result) {
  auto strCopy = str;
  std::sort(str.begin(), str.end());
  do {
    result->push_back(str);
  } while (std::next_permutation(str.begin(), str.end()));

  // To avoid duplication 
  result->erase(std::remove(result->begin(), result->end(), strCopy), result->end());
}

void combination(int n, int numberOfColours, vector<string> *result) {
  vector<string> colours;
  for (int i = 0; i < numberOfColours; i++)
    colours.push_back(to_string(i));
  auto s = colours.size() - 1;
  vector<int> v(n + 1, 0);
  while (true) {
    for (int i = 0; i < n; ++i) {
      if (v[i] > s) {
        v[i + 1] += 1;
        for (int k = i; k >= 0; --k) {
          v[k] = v[i + 1];
        }
      }
    }

    if (v[n] > 0)
      break;
    string str{};
    for (size_t i = 0; i < n; ++i)
      str.append(colours[v[i]]);
    result->push_back(str);
    v[0] += 1;
  }
}

void createPoolN(int n, int numberOfColours, vector<string> *pool) {
  combination(n, numberOfColours, pool);
  auto perms = make_unique<vector<string>>();
  for (const auto &p : *pool) {
    permutation(p, perms.get());
  }
  pool->insert(pool->end(), perms->begin(), perms->end());
  sort(pool->begin(), pool->end());
}

int main() {
  int n = 5;
  int numberOfColours = 10;
  auto pool = make_unique<vector<string>>();
  createPoolN(n, numberOfColours, pool.get());
  for (const auto &p : *pool)
    cout << "[" << p << "]\n";
  return 0;
}

输出:

[00000]
[00001]
[00002]
...
[99997]
[99998]
[99999]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-06
    • 2014-09-17
    • 2012-10-24
    • 2016-07-18
    • 2016-10-12
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    相关资源
    最近更新 更多