如何避免在C ++中出现这种for循环混乱?

坚硬的

我需要对从1到的所有可能的数字集进行编程,N获取任意数量m的整数而无需置换。

由于我不知道如何更好地解释它,因此这里有一些示例:

为了 m = 2

vector<vector<int>> box;    
int N = 5;

for(int i = 1; i <= N; i++) {
    for(int j = N; j >= i; j--) {
        vector<int> dummy;
        dummy.push_back(i);
        dummy.push_back(j);
        box.push_back(dummy);
    }
}

为了 m = 3

vector<vector<int>> box;    
int N = 5;  

for(int i = 1; i <= N; i++) {
    for(int j = N; j >= i; j--) {
        for(int k = N; k >= j; k--) {
            vector<int> dummy;
            dummy.push_back(i);
            dummy.push_back(j);
            dummy.push_back(k);
            box.push_back(dummy);
        }
    }
}

这工作得很好,结果就是我所需要的。但是就像已经提到的那样,它m可以是任意的,我也不会为实现此目的而烦恼m = 37Nm在程序运行时已知值,但变化。m = 37与实现一行37个循环情况相比,必须有一种更好的方法来实现此目的有人能帮我吗?我很无知:\

编辑:为了更好地解释我在寻找什么,这里有更多示例。

假设N = 5m = 41223这对我来说是一个可行的解决方案,124不是因为它太短了。假设我已经找到1223了一个不需要的解决方案21232213或者这个数字的任何其他排列。

edit2:或者,如果您更喜欢一种视觉上的(数学上的)问题表述,则可以。

考虑m尺寸。有了m2,您剩下一个N大小矩阵。我正在寻找此矩阵(包括对角线)的上(或下)三角形。让我们转到m = 3,矩阵变成一个3维立方体(或者,如果您愿意,则为Tensor),现在我正在寻找包括对角平面的上(或下)四面体。对于大于3的尺寸,我正在寻找超立方体(包括超对角平面)的超四面体。

bames53

http://howardhinnant.github.io/combinations.html

以下通用算法允许客户一次访问长度为N,r个项目的序列的每种组合或排列。

用法示例:

std::vector<std::vector<int>> box;  

std::vector<int> v(N);
std::iota(begin(v), end(v), 1);

for_each_combination(begin(v), begin(v) + M, end(v), [](auto b, auto e) {
    box.emplace_back(b, e);
    return false;
});

上面的代码仅以插入每个组合box为例,但是您实际上可能不想这样做:假设这box只是一个中介,而您的实际工作然后在其他地方使用它,则可以避免使用中介,而只是做您直接需要在函子体内进行的任何工作。

这是使用提供的链接中的代码完整的可行示例


由于您想要的是具有重复的组合,而不仅仅是组合。这是在之上实现此示例for_each_combination()

template<typename Func>
void for_each_combination_with_repetition(int categories, int slots, Func func) {
    std::vector<int> v(slots + categories - 1);
    std::iota(begin(v), end(v), 1);

    std::vector<int> indices;
    for_each_combination(begin(v), begin(v) + slots, end(v), [&](auto b, auto e) {
        indices.clear();
        int last = 0;
        int current_element = 0;

        for(;b != e; ++last) {
            if (*b == last+1) {
                indices.push_back(current_element);
                ++b;
            } else {
                ++current_element;
            }
        }
        func(begin(indices), end(indices));
        return false;
    });
}

维基百科有关组合的文章很好地说明了这种方法的作用:正在获取数字[0,N + M-1)的所有组合(无重复),然后在结果中寻找“缺口”。间隙表示从一个元素的重复到另一个元素的重复的过渡。

您传递给此算法的函子将获得一个范围,该范围包含索引的集合,该集合包含要合并的元素。例如,如果您要从{x,y}的集合中获取所有三个元素的集合,则结果是{{x,x,x},{x,x,y},{x,y, y},{y,y,y}},此算法通过将索引范围返回到(有序)集合{x,y}中来表示:{{0,0,0},{0,0,1} ,{0,1,1},{1,1,1}}。

因此,通常使用此向量,您可以拥有一个向量或包含您的元素的东西,并将此算法产生的范围用作该容器的索引。但是,在您的情况下,由于元素只是从1到N的数字,因此可以通过在每个索引上加一个直接使用索引:

for_each_combination_with_repetition(N, M, [&](auto b, auto e) {
    for(; b != e; ++b) {
        int index = *b;
        std::cout << index + 1 << " ";
    }
    std::cout << '\n';
});

完整的例子


一种替代实现可以返回表示每个类别的计数的向量。例如,较早的{{x,x,x},{x,x,y},{x,y,y},{y,y,y}}结果可以表示为:{{3,0} {2 ,1},{1,2},{0,3}}。修改实现以产生此表示形式的方法如下所示:

template<typename Func>
void for_each_combination_with_repetition(int categories, int slots, Func func) {
    std::vector<int> v(slots + categories - 1);
    std::iota(begin(v), end(v), 1);

    std::vector<int> repetitions(categories);
    for_each_combination(begin(v), begin(v) + slots, end(v), [&](auto b, auto e) {
        std::fill(begin(repetitions), end(repetitions), 0);

        int last = 0;
        int current_element = 0;

        for(;b != e; ++last) {
            if (*b == last+1) {
                ++repetitions[current_element];
                ++b;
            } else {
                ++current_element;
            }
        }
        func(begin(repetitions), end(repetitions));
        return false;
    });
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何避免在R中出现循环?

来自分类Dev

如何避免在R中出现循环?

来自分类Dev

如何避免在纯CSS中出现这种重叠?

来自分类Dev

如何避免PR中出现混乱的git commit

来自分类Dev

如何避免BuildPath中出现循环(特定项目设置)

来自分类Dev

我如何避免在班级图中出现循环关系

来自分类Dev

如何避免在Scala中出现for循环的编译器警告?

来自分类Dev

如何避免嵌套的foreach循环php中出现重复项

来自分类Dev

避免R中出现for循环的建议

来自分类Dev

NumPy:如何避免这种循环?

来自分类Dev

您如何处理getopt中出现的参数混乱?

来自分类Dev

如何避免网址中出现“ / Home”

来自分类Dev

如何避免RabbitMQ中出现重复消息?

来自分类Dev

如何避免checkListBox中出现重复项

来自分类Dev

如何避免在RRDTool图表中出现空格?

来自分类Dev

如何避免联接查询中出现多行?

来自分类Dev

R:在此函数中如何避免R中出现2个“ for”循环

来自分类Dev

如何在vue.js中避免v-for循环的输出中出现重复值

来自分类Dev

如何避免 RDS 实例和安全组的模块中出现循环错误

来自分类Dev

循环时避免在Python中出现索引错误

来自分类Dev

有没有办法避免在OS X的Terminal中出现这种严重的提示效果?

来自分类Dev

在这种情况下,避免混乱循环的最佳方法是什么?

来自分类Dev

如何避免/检查C ++中这种非常险恶的错误源

来自分类Dev

如何避免这种缩小?

来自分类Dev

如何避免这种重叠?

来自分类Dev

如何避免这种缩小?

来自分类Dev

打字稿。如何避免在foreach循环中出现此错误:“算术运算的左侧必须为'any','number'或枚举类型”?

来自分类Dev

打字稿。如何避免在foreach循环中出现此错误:“算术运算的左侧必须为'any','number'或枚举类型”?

来自分类Dev

如何避免字符串中出现单引号

Related 相关文章

  1. 1

    如何避免在R中出现循环?

  2. 2

    如何避免在R中出现循环?

  3. 3

    如何避免在纯CSS中出现这种重叠?

  4. 4

    如何避免PR中出现混乱的git commit

  5. 5

    如何避免BuildPath中出现循环(特定项目设置)

  6. 6

    我如何避免在班级图中出现循环关系

  7. 7

    如何避免在Scala中出现for循环的编译器警告?

  8. 8

    如何避免嵌套的foreach循环php中出现重复项

  9. 9

    避免R中出现for循环的建议

  10. 10

    NumPy:如何避免这种循环?

  11. 11

    您如何处理getopt中出现的参数混乱?

  12. 12

    如何避免网址中出现“ / Home”

  13. 13

    如何避免RabbitMQ中出现重复消息?

  14. 14

    如何避免checkListBox中出现重复项

  15. 15

    如何避免在RRDTool图表中出现空格?

  16. 16

    如何避免联接查询中出现多行?

  17. 17

    R:在此函数中如何避免R中出现2个“ for”循环

  18. 18

    如何在vue.js中避免v-for循环的输出中出现重复值

  19. 19

    如何避免 RDS 实例和安全组的模块中出现循环错误

  20. 20

    循环时避免在Python中出现索引错误

  21. 21

    有没有办法避免在OS X的Terminal中出现这种严重的提示效果?

  22. 22

    在这种情况下,避免混乱循环的最佳方法是什么?

  23. 23

    如何避免/检查C ++中这种非常险恶的错误源

  24. 24

    如何避免这种缩小?

  25. 25

    如何避免这种重叠?

  26. 26

    如何避免这种缩小?

  27. 27

    打字稿。如何避免在foreach循环中出现此错误:“算术运算的左侧必须为'any','number'或枚举类型”?

  28. 28

    打字稿。如何避免在foreach循环中出现此错误:“算术运算的左侧必须为'any','number'或枚举类型”?

  29. 29

    如何避免字符串中出现单引号

热门标签

归档