[英]How to generate only so many permutations more efficiently in C++?
我正在尝试解决一个问题,我觉得自己已经很接近了,但是它仍然有点慢,因为我生成了很多排列。
我需要“ 0123456789”的排列。 我知道有(10)! 排列很多。 我使用std::unordered_set
是因为我不在乎它们的存储顺序,而且看起来比使用常规std::set
更快
这是我写的一些核心内容: max_perm_size
是我在特定情况下关心的排列字符串的大小。
void getPermutations(unordered_set<string> &permutations, int &max_perm_size)
{
string digits = "0123456789";
do{
permutations.insert(digits.substr(0, max_perm_size));
} while (next_permutation(digits.begin(), digits.end()));
}
关于此代码,我有两个主要问题:
max_perm_size
大小的排列的情况,我仍然会生成整个“ 0123456789”排列。 在将它们存储到我的std::unordered_set
之前,我只是对它们进行了修剪。 有没有办法更好地做到这一点,从而更快? max_pem_size = 10
,对于我而言,是否有一种更有效的方式来生成和存储所有这些排列? 据我所知,您的结果是从0到某个限制的数字(没有重复的数字)。 既然您说您不关心数字的顺序,那么如果我们只坚持升序,那可能是最简单的。 在这种情况下,我们可以生成如下结果:
#include <iostream>
int main() {
for (int i=0; i<10; i++)
for (int j=i+1; j<10; j++)
for (int k=j+1; k<10; k++)
std::cout << i << j << k << "\t";
}
结果:
012 013 014 015 016 017 018 019 023 024 025 026 027
028 029 034 035 036 037 038 039 045 046 047 048 049
056 057 058 059 067 068 069 078 079 089 123 124 125
126 127 128 129 134 135 136 137 138 139 145 146 147
148 149 156 157 158 159 167 168 169 178 179 189 234
235 236 237 238 239 245 246 247 248 249 256 257 258
259 267 268 269 278 279 289 345 346 347 348 349 356
357 358 359 367 368 369 378 379 389 456 457 458 459
467 468 469 478 479 489 567 568 569 578 579 589 678
679 689 789
如果您的限制不是数字位数,则可以将这些数字放到一个实际的int中进行比较(然后脱离循环)。
这是针对您的情况而不是通用的解决方案,但是对于数字排列的情况,您可以执行以下操作:
void getPermutations(unordered_set<string> &permutations, int max_perm_size)
{
if (max_perm_size < 1) return;
uint64_t stopat = 1;
for (int i = 1; i < max_perm_size; ++i) {
stopat *= 10;
}
for (uint64_t dig = 0; dig < stopat; ++dig) {
std::ostringstream ss;
ss << std::setw(max_perm_size) << std::setfill('0') << dig;
permutations.insert(ss.str());
}
}
您可以先获取数字字符串的子字符串。 然后,您的循环将仅处理max_perm_size的排列。
您可以创建一个按需生成排列的类,而不是预先生成并存储它们。 根据您的应用程序,您甚至不必存储它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.