簡體   English   中英

如何在C ++中更有效地僅生成這么多排列?

[英]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()));

}

關於此代碼,我有兩個主要問題:

  1. 在上面,即使對於僅關心max_perm_size大小的排列的情況,我仍然會生成整個“ 0123456789”排列。 在將它們存儲到我的std::unordered_set之前,我只是對它們進行了修剪。 有沒有辦法更好地做到這一點,從而更快?
  2. 在最壞的情況下, 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());
    }
}
  1. 您可以先獲取數字字符串的子字符串。 然后,您的循環將僅處理max_perm_size的排列。

  2. 您可以創建一個按需生成排列的類,而不是預先生成並存儲它們。 根據您的應用程序,您甚至不必存儲它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM