[英]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.