There's no simple way, but you could implement an iterator-like type that generates the Cartesian product over n given ranges:enum { MAX = 8};typedef struct Combinator Combinator;struct Combinator { size_t index; // running index of generated numbers size_t n; // number of dimensions int data[MAX]; // current combination int start[MAX]; // lower and ... int end[MAX]; // .. exclusive upper limits};/* * Adds a dimensin with valid range [start, end) to the combinator */void combo_add(Combinator *c, int start, int end){ if (c->n < MAX && start < end) { c->data[c->n] = start; c->start[c->n] = start; c->end[c->n] = end; c->n++; }}/* * Reset the combinator to the lower limits */void combo_reset(Combinator *c){ c->index = 0; memcpy(c->data, c->start, sizeof(c->start));}/* * Get the next comnination in c->data. Returns 1 if there * is a next combination, 0 otherwise. */int combo_next(Combinator *c){ size_t i = 0; if (c->index++ == 0) return 1; do { c->data[i]++; if(c->data[i] < c->end[i]) return 1; c->data[i] = c->start[i]; i++; } while (i < c->n); return 0;}这实现了一个类似里程表的计数器:它增加了第一个计数器.如果溢出,它将重置并递增下一个计数器,并根据需要移至下一个计数器.如果最后一个计数器溢出,组合的生成将停止.(第一个组合的索引有些混乱,因此您可以从 while 循环的循环条件中控制所有内容.可能有一种更优雅的解决方法.)This implements an odometer-like counter: It increments the first counter. If it overflows, it resets it and increments the next counter, moving to te next counter as needed. If the last counter overflows, the generation of combinations stops. (There's a bit of a kludge with the index for the first combination so that you can control everything from the loop condition of a while loop. There's probably a more elegant way to solve this.)像这样使用组合器:Combinator combo = {0}; // Must initialize with zerocombo_add(&combo, 0, 3);combo_add(&combo, 10, 12);combo_add(&combo, 4, 7);while (combo_next(&combo)) { printf("%4zu: [%d, %d, %d]\n", combo.index, combo.data[0], combo.data[1], combo.data[2]);} 此组合器只能使用一次:创建它,设置范围,然后用尽所有组合.This combiinator is designed to use only once: Create it, set up the ranges, then exhaust the combinations.如果您中断,那么组合器将保持其状态,以便在中断时继续调用 combo_next .您可以通过调用 combo_reset 重新开始.(这有点像从文件中读取:使用它们的通常方法是读取所有内容,但是您可以倒退.)If you break out of the loop, the combinator retains its state, so that further call to combo_next continue where you broke off. You can start afresh by calling combo_reset. (This is a bit like reading from a file: The usual way to use them is to read everything, but you can rewind.) 这篇关于多维循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-26 23:35