C++ 简化C++;For循环

C++ 简化C++;For循环,c++,arrays,for-loop,cartesian-product,C++,Arrays,For Loop,Cartesian Product,目前,我有以下代码: for(int i = 0; i < 4; i++){ cout << rowNo[i] << endl; } for(int i = 0; i < 4; i++){ for(int j = 0; j < 4; j++){ cout << rowNo[i] << '.'; cout << rowNo[j] << endl; }

目前,我有以下代码:

for(int i = 0; i < 4; i++){
    cout << rowNo[i] << endl;
}

for(int i = 0; i < 4; i++){
    for(int j = 0; j < 4; j++){
        cout << rowNo[i] << '.';
        cout << rowNo[j] << endl;
    }
}

for(int i = 0; i < 4; i++){
    for(int j = 0; j < 4; j++){
        for(int k = 0; k < 4; k++){
            cout << rowNo[i] << '.';
            cout << rowNo[j] << '.';
            cout << rowNo[k] << endl;
        }
    }
}

for(int i = 0; i < 4; i++){
    for(int j = 0; j < 4; j++){
        for(int k = 0; k < 4; k++){
            for(int l = 0; l < 4; l++){
                cout << rowNo[i] << '.';
                cout << rowNo[j] << '.';
                cout << rowNo[k] << '.';
                cout << rowNo[l] << endl;
            }
        }
    }
}
for(int i=0;i<4;i++){

cout我想到的第一个解决方案是在每个循环中放入缓冲区,最后打印所有缓冲区。 我认为还有其他一些巧妙的方法

for(int i = 0; i < 4; i++){
        put in buffer1 rowNo[i]
        for(int j = 0; j < 4; j++){
            put in buffer2 rowNo[i],rowNo[j]
            for(int k = 0; k < 4; k++){
                 put in buffer3 rowNo[i],rowNo[j],rowNo[k]
                for(int l = 0; l < 4; l++){
                    put in buffer4 rowNo[i],rowNo[j],rowNo[k],rowNo[l],endl.
                }
            }
        }
    }
     print(buffer1);
     print(buffer2);
     print(buffer3);
     print(buffer4);
for(int i=0;i<4;i++){
放入缓冲区1行编号[i]
对于(int j=0;j<4;j++){
放入缓冲区2罗诺[i],罗诺[j]
对于(int k=0;k<4;k++){
放入缓冲区3-罗诺[i],罗诺[j],罗诺[k]
对于(int l=0;l<4;l++){
放入缓冲区4 rowNo[i]、rowNo[j]、rowNo[k]、rowNo[l]、endl。
}
}
}
}
打印(1);
打印(2);
打印(3);
打印(4);

以下是我想到的最简单的代码。但必须有一种更直接的方法来实现这一点

它基本上引入了一个“ghost”索引-1,对应于数字中的一个空位置。循环条件中的三元运算符用于避免重复

int main()
{
    int N = 4;
    int rowNo[4] = {1, 2, 3, 4};

    for (int i = -1; i < N; i++)
        for (int j = (i > -1 ? 0 : -1); j < N; j++)
            for (int k = (j > -1 ? 0 : -1); k < N; k++)
                for (int l = (k > -1 ? 0 : -1); l < N; l++)
                {
                    if (i > -1) std::cout << rowNo[i] << '.';
                    if (j > -1) std::cout << rowNo[j] << '.';
                    if (k > -1) std::cout << rowNo[k] << '.';
                    if (l > -1) std::cout << rowNo[l];
                    std::cout << std::endl;
                }
}
intmain()
{
int N=4;
int rowNo[4]={1,2,3,4};
for(int i=-1;i-1?0:-1);j-1?0:-1);k-1?0:-1);l-1)std::cout您正在寻找

bool增量(std::vector&v,std::size\u t maxSize)
{
对于(自动it=v.rbegin();it!=v.rend();++it){
++*它;
如果(*it!=maxSize){
返回true;
}
*它=0;
}
返回false;
}
然后你可以做:

void print_cartesian_product(const std::vector<int>&v, int n)
{
    std::vector<std::size_t> indexes(n);

    do {
        print(v, indexes);
    } while (increment(indexes, v.size()));

}
void print\u笛卡尔积(const std::vector&v,int n)
{
std::向量索引(n);
做{
打印(v,索引);
}而(增量(索引,v.size());
}

实际上,您正在尝试打印一个用数字{1,2,3,4}编码在base4中的数字。要实现它,您只需要定义一个递增1的函数。我提出了一个通用的解决方案,即打印的数字量和基数。 和其他人一样,我用数字表示“空数字”
,我用零表示,这非常方便

完整的源代码:

#include <iostream>
#include <vector>

bool increment_basep(std::vector<int>& number, int p)
{ 
    int i = 0; 
    while(i < number.size() && number[i] == p)
    { 
       number[i] = 1;
       ++i;
    }
    if(i >= number.size())
        return false;

    ++number[i];
    return true;
}

void print_vect(std::vector<int>& number)
{
   for(int i = number.size() -1 ; i >= 0; --i)
   {
       if(number[i] != 0)
          std::cout << number[i];
   }
   std::cout << std::endl;
}

int main() {
    int n = 4;
    int p = 4;
    std::vector<int> num4(n);
    std::fill(num4.begin(), num4.end(), 0);

    while(increment_basep(num4, p))
    {
        print_vect(num4);
    }
    return 0;
}
#包括
#包括
布尔增量(标准::向量和数字,整数)
{ 
int i=0;
而(i=number.size())
返回false;
++编号[i];
返回true;
}
无效打印向量(标准::向量和编号)
{
对于(int i=number.size()-1;i>=0;--i)
{
如果(数字[i]!=0)

std::能否打印{1,2,3,4}幂集中每个集合的每个置换?hum 4444的可能副本实际上是有效的。因此,您只需要字母表{1,2,3,4}中的每个可能的数字是的,基本上,虽然输出的格式化方式并不是一个真正的问题。因此,要输出例如:1,2,3,4,1.1,1.2,1.3,1.4…我会将其作为打印数组的值,这些值由所有N位基数4的数字索引。我可能会在空闲时间编写一些代码,但您可能自己也可以:)还指定根据你的要求,你可以生成代码,然后构建它。你要做的是制作一个写n次的程序,然后构建它。如果你想尝试这种方法,请告诉我。很好!它不会打印少于n个元素的组合,但是,用这种方法可以吗?唯一的一件事,我认为OP希望而是在main中:
for(inti=0;i<3;++i){print_cartesian_乘积({4,8,42},i);})
谢谢,经过几次调整后,这个功能现在运行得很好:)@user2506322好像你没有查看我的帖子。@UmNyobe对此表示抱歉,我没有刷新我的页面。你现在:)这几乎不是OP代码的改进。它还使用了4个嵌套循环,所以它同样快(或慢),但它更难阅读和理解。此外,我不确定他是否希望避免重复。而且你没有抓住关于大小N的要点。你的方法,就像他的方法一样,要求为每个额外的项目添加代码。对于4个元素,你需要编写4个循环。OP希望代码能够在不接触其余代码的情况下为任何值N工作。比k you,这是预期的。但是,如果用户在开始时输入N,是否可以创建一个动态的for循环量?在这种情况下,N的最大值为8。@FabioTurati恐怕打印一组k元素的所有组合的复杂性将始终为O(N^k),不管我们如何编写代码:)而OP在其原始代码中没有打印两次相同的组合,因此我的代码也必须打印两次相同的组合。@对不起,我没有正确地表达自己。我的意思是你的算法比OP的算法更难理解,不能满足他的要求,使其对任何N都有效,也不能提供任何其他好处。速度只是一个我通常期望从不同算法中获得的好处的例子;我并不是说在这种特定情况下它可以实现。所以在我看来,采用这种解决方案是没有意义的。没错,这是一种优雅的方法,而且时间更短;但在我看来,这两种方法都无法弥补避免了可读性的丧失。
#include <iostream>
#include <vector>

bool increment_basep(std::vector<int>& number, int p)
{ 
    int i = 0; 
    while(i < number.size() && number[i] == p)
    { 
       number[i] = 1;
       ++i;
    }
    if(i >= number.size())
        return false;

    ++number[i];
    return true;
}

void print_vect(std::vector<int>& number)
{
   for(int i = number.size() -1 ; i >= 0; --i)
   {
       if(number[i] != 0)
          std::cout << number[i];
   }
   std::cout << std::endl;
}

int main() {
    int n = 4;
    int p = 4;
    std::vector<int> num4(n);
    std::fill(num4.begin(), num4.end(), 0);

    while(increment_basep(num4, p))
    {
        print_vect(num4);
    }
    return 0;
}