【问题标题】:Print all arrangements in c++在 C++ 中打印所有排列
【发布时间】:2018-04-20 06:11:26
【问题描述】:

我想列出所有安排,以下是我的示例代码:

const unsigned char item1[] = {'b'};
const unsigned char item2[] = { 'A', 'C' ,'D'};
const unsigned char item3[] = {'1','2'};

int _tmain(int argc, _TCHAR* argv[])
{
    for (int i = 0; i < sizeof(item1) / sizeof(unsigned char); i++){
        for (int j = 0; j < sizeof(item2) / sizeof(unsigned char); j++){
            for (int k = 0; k < sizeof(item3) / sizeof(unsigned char); k++){
                printf("%c%c%c\n",item1[i],item2[j],item3[k]);
            }
        }
    }
    return 0;
}

这将打印所有排列,但我担心如果数组项是从item1item99,代码很难维护。是否有更好的解决方案来打印所有安排?谢谢!

【问题讨论】:

  • 我说得不好,但你要找的可能是一个向量的向量,用递归函数处理。
  • 您可以使用#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))减少数组长度计算
  • @Hamed 我不确定您所说的“几个循环”是什么意思。我理解“几个循环”==“很少循环”。 OP 'item1' 到 'item99' 似乎他们在谈论要由 100 个循环处理的 100 个项目,这在更改为向量向量时仍然适用。我可能误解了你的意思。随意详细说明。
  • @Hamed,他需要显示所有组合,对于 n=100,它是 1000000 个组合,对于三个数组,它是三个 lop 语句
  • 如果您想为每个数组和 100 个不同的数组执行此操作,请准备好等待。如果平均循环持续时间为 1ns,则总时间约为 400 亿年。大约是宇宙存在时间的 4 倍......

标签: c++ permutation


【解决方案1】:

您可以将“迭代器”存储在向量中,然后您可以执行以下操作:

bool increase(const std::vector<std::string>& v, std::vector<std::size_t>& it)
{
    for (std::size_t i = 0, size = it.size(); i != size; ++i) {
        const std::size_t index = size - 1 - i;
        ++it[index];
        if (it[index] == v[index].size()) {
            it[index] = 0;
        } else {
            return true;
        }
    }
    return false;
}

void do_job(const std::vector<std::string>& v, std::vector<std::size_t>& it)
{
    for (std::size_t i = 0, size = v.size(); i != size; ++i) {
        std::cout << v[i][it[i]];
    }
    std::cout << std::endl;
}

void iterate(const std::vector<std::string>& v)
{
    std::vector<std::size_t> it(v.size(), 0);

    do {
        do_job(v, it);
    } while (increase(v, it));
}

Demo

【讨论】:

    【解决方案2】:

    实现此目的的一个好方法是将问题视为整数基转换问题。因此,组合的总数是所有数组大小的乘积。输出字符串 n 足以确定应在字符串中打印的数组索引。 由于您已将其标记为 C++ 问题,因此我将使用 2-D 向量,因为这使生活变得更加简单:

    int _tmain(int argc, _TCHAR* argv[])
    {
        // Initialize the vector
        vector<vector<char>> v( 3 );
    
        v[0].push_back( 'b' );
        v[1].push_back( 'A' );
        v[1].push_back( 'C' );
        v[1].push_back( 'D' );
        v[2].push_back( '1' );
        v[2].push_back( '2' );
    
        // This is a convenience vector of sizes of each 1-D vector
        vector<size_t> sizes( v.size() );
    
        // Get the total number of combinations and individual vector
        // sizes
        size_t total = 1;
        for( size_t i = 0; i < v.size(); ++i )
        {
            sizes[i] = v[i].size();
            total *= sizes[i];
        }
    
        size_t done = 0;
    
        // Loop till all the combinations are printed
        while( done != total )
        {
            // Remainder, which is the index of the element
            // in the 1-D vector that is to be printed
            size_t r = 0;
            // Quotient to be used for the next remainder
            size_t q = done;
            // Combination to be printed
            string s = "";
    
            // Loop over the 1-D vectors, picking the correct
            // character from each
            for( size_t i = 0; i < v.size(); ++i )
            {
                r = q % sizes[v.size() - 1 - i];
                q = static_cast<size_t>( floor( q/sizes[v.size() - 1 - i] ) );
                s = v[v.size() - 1 - i][r] + s;
            }
    
            cout<<s<<"\n";
    
            done++;
        }
        return 0;
    }
    

    【讨论】:

    • _tmain() 是特定于操作系统的。它不是标准的 C++。
    • 没关系,从不影响逻辑的意义上说。我只是使用了OP的设置。
    • @TuRoland :我在 linux 中尝试过,它确实有效。它是在什么时候崩溃的?
    • @TuRoland:对不起。代码略有不同。我复制粘贴了一个旧版本。现在编辑了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 2018-03-07
    • 1970-01-01
    相关资源
    最近更新 更多