【问题标题】:How should I go about generating every possible map<char, char> combination from map<char, vector<char> >?我应该如何从 map<char, vector<char> > 生成每个可能的 map<char, char> 组合?
【发布时间】:2010-03-09 23:56:41
【问题描述】:

我希望获取map&lt;char, vector&lt;char&gt; &gt; 并从中生成每个可能的map&lt;char, char&gt;

我知道这可能会使用大量内存并需要一些时间。

每个map&lt;char, char&gt; 需要包含每个字母 a-z,并映射到唯一的 a-z 字符。 IE。 ak bj cp dy 电动汽车 调频 嘎 血红蛋白 红外 jq kn 李 MX 数控 哦 pz qs rl sd 你 uw VF 工作组 厘米 于 zt

到目前为止,这是我为自己得出的结论:

为了将可能组合的荒谬数量减少到较低的数量,如果 vector&lt;char&gt; 包含超过 5 个元素,我将简单地将其替换为包含来自我的“主”/“原始”的单个字符的 vector&lt;char&gt; 'map&lt;char, char&gt;.

并非所有字符都会出现在地图中的所有vector&lt;char&gt;s 上。需要找到这些字符并将其放入一些“其他”向量中。

这还应该包含一个字符是多个字符键的唯一可能字符的字符(即我正在使用的示例中的 mw - 我不确定如何处理)。

此“其他”向量应用于不可能具有唯一 a-z 字符或多个字符具有相同的单个可能字符的情况。

这是我目前所拥有的一个例子。

我将采取map&lt;char, vector&lt;char&gt; &gt;,如:

a: gjkpqvxz
b: gjkpqvxz
c: gjkpqvxyz
d: mw
e: gjkpqvxz
女:nr
g: 在
h: cf
我:他的
j: gjkpqvxz
k: r
l: h
米:gjkpqvxz
n: gjkpquvxyz
o: 是
p: gjkpqvxz
问:是
r: dl
s: l
t: e
你:dgkpuvy
v: cf
w: bcf
x: dguy
y: f
z:在

这是我的起始地图。在切出超过 5 个的大字符向量并用最佳猜测替换它们之后。如果是大小为 1 的 vector&lt;char&gt;,则该字符映射只有一个组合,并且该字符不能用于任何其他映射,因为它会使其不唯一。我已将其修剪为:

a: k
b: j
c: p
d: mw
e: v
f: n
g: 在
h: c
我:是
j: q
k: r
l: h
米:x
n: 家伙
o: 是
p: z
问:是
r: d
s: l
t: e
你:dguy
v: c
w: 公元前
x: dguy
y: f
z:在

“others”向量包含“o”(我认为重要的是要注意,我认为这应该包含上面示例中的 mw 等情况。因为 d 是唯一可以使用 mw 的地方,但显然与需要每个字母只能使用一次,只能使用其中一个,而另一个则丢失在某个地方。我不知道如何编写一个通用案例以将这些添加到其他向量。)

我正在寻找帮助和指针,以像这样和这种格式从map&lt;char, vector&lt;char&gt; &gt;s 生成所有可能的map&lt;char, char&gt;。它们将用作函数调用中的参数。我不确定从哪里开始写一些一般意义上的东西。我可能会用大量的 for 循环来处理它.

对不起,如果这太像文字墙,或者看起来过于具体或写得不好/问得不好。

感谢所有帮助。

【问题讨论】:

  • 您能告诉我们您要解决的问题吗?
  • 我的第一个念头是“凯撒密码”……
  • 我正在尝试破解替代密码。

标签: c++ vector map permutation combinations


【解决方案1】:

我想我希望我不需要它们同时存在。然后我可以:

1) 通过将第一个可能的元素分配给每个字母来创建第一个映射:

for (char c = 'a'; c <= 'z'; ++c) {  // yes, I assume ASCII
   new_map[c] = old_map[c][0];
}
int indexes[26] = {0};

2)通过修改现有地图,依次创建剩余地图,重复:

++indexes[0];
if (indexes[0] < old_map['a'].size()) {
    new_map['a'] = old_map['a'][indexes[0]];
} else {
    indexes[0] = 0;
    new_map['a'] = old_map['a'][0];
    // "carry the 1" by applying the same increment process to indexes[1]
}
do_something_with(new_map);

do_something_with 可以每次从地图中重新构造“其他”向量,或者每次更改角色时都可以更新它。替换:

    new_map['a'] = something;

与:

    char removed = new_map['a'];
    --counts[removed];
    if (counts[removed] == 0) others.add(removed);
    ++counts[something];
    if (counts[something] == 1) others.remove(something);
    new_map['a'] = something;

在您精简的示例中,只有大约 6000 种可能性,它们应该会飞过。事实上,如果你确实同时需要它们,你可以在每一步都复制之前的地图,而且不会完全等到下一个冰河时代。

顺便说一句,您是否认为一张地图对于仅 26 个可能的键来说有点过分了,每个键都需要出现在每个地图中?使用和复制向量或数组会便宜得多。

【讨论】:

  • 这看起来像我要找的。谢谢。我在理解这一点时遇到了一些麻烦,但我怀疑那是因为已经快凌晨 1 点了。我猜第二部分需要处于某种循环中?早上我会好好看看。如果我仍然不能完全理解发生了什么,可以打扰你吗?再次感谢。
  • 是的,第二部分在循环中。如果您尝试将 1 带入索引 [25] 之外,则应该打破循环。实际上你最好定义一个函数increment_position(int),它递归地调用自己来携带1。只是我也在格林威治标准时间,我不相信我可以在没有测试或睡着的情况下输入所有内容。您至少可以进行一项优化:与其从索引 0 开始,然后到 1,2 等,而是列出向量大于 1 的所有索引,并且只在这些索引处递增。
  • 我仍然无法理解您所指的“携带 1”,我应该使用该循环并知道何时停止。
  • 把它想象成课堂加法,只是每个“数字”(即数组中的索引)不是以 10 为底,而是在不同的底下,由相应向量的大小给出。因此,如果您尝试增加 index[0] 但它已超过限制,则将其设置为 0 并改为增加 index[1]。如果超过限制,您也将其设置为 0 并增加下一个。如果你一直到最后将事物设置为 0 并用完“数字”,这意味着你回到了最初开始的地图(每个字符的第一个选项),所以你已经完成了。跨度>
  • 在我弄清楚这一点之前还有一个问题,或者放弃并满足于不尝试所有可能的组合。这个项目真的占用了我不成比例的时间。我猜我的循环实现中存在一些主要的逻辑缺陷,因为程序在运行时退出。 while(true){ ++indexes[i]; for (char ch = 'a'; ch &lt;= 'z'; ++ch) { if (indexes[i] &lt; a[ch].size()) { compmapguess[ch] = a[ch][indexes[i]]; } else { indexes[i] = 0; // cout&lt;&lt; "Shouldnt get here that often" &lt;&lt; endl; compmapguess[ch] = a[ch][i]; i++;} if (i&gt;25){ break;} 呃,格式化很抱歉。
【解决方案2】:

我知道这可能会使用大量内存并需要一些时间。

是的,组合的数量大约是 403,291,461,000,000,000,000,000,000 :-)

【讨论】:

  • 真的有那么多吗?字符数量如此减少,其中 16 个字符只有 1 个字符,2 个字符中的几个,并且只有几个字符以上?
  • 正如 Steve Jessop 在下面指出的那样,它接近 6000,这是我的预期。
猜你喜欢
  • 1970-01-01
  • 2012-02-16
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
相关资源
最近更新 更多