创建N个嵌套的for循环
Creating N nested for-loops
是否有办法创建for循环的形式
for(int i = 0; i < 9; ++i) {
for(int j = 0; j < 9; ++i) {
//...
for(int k = 0; k < 9; ++k) { //N-th loop
在编译时不知道N。理想情况下,我试图找出一种方法来循环通过数字向量的单独元素来创建每个可能的数字,如果一定数量的数字被不同的数字取代。
您可以使用递归来代替基本条件-
void doRecursion(int baseCondition){
if(baseCondition==0) return;
//place your code here
doRecursion(baseCondition-1);
}
现在您不需要在编译时提供baseCondition
值。可以在调用doRecursion()
方法时提供它。
这是一个很好的用于多索引的小类,可以通过基于范围的for循环进行迭代:
#include<array>
template<int dim>
struct multi_index_t
{
std::array<int, dim> size_array;
template<typename ... Args>
multi_index_t(Args&& ... args) : size_array(std::forward<Args>(args) ...) {}
struct iterator
{
struct sentinel_t {};
std::array<int, dim> index_array = {};
std::array<int, dim> const& size_array;
bool _end = false;
iterator(std::array<int, dim> const& size_array) : size_array(size_array) {}
auto& operator++()
{
for (int i = 0;i < dim;++i)
{
if (index_array[i] < size_array[i] - 1)
{
++index_array[i];
for (int j = 0;j < i;++j)
{
index_array[j] = 0;
}
return *this;
}
}
_end = true;
return *this;
}
auto& operator*()
{
return index_array;
}
bool operator!=(sentinel_t) const
{
return !_end;
}
};
auto begin() const
{
return iterator{ size_array };
}
auto end() const
{
return typename iterator::sentinel_t{};
}
};
template<typename ... index_t>
auto multi_index(index_t&& ... index)
{
static constexpr int size = sizeof ... (index_t);
auto ar = std::array<int, size>{std::forward<index_t>(index) ...};
return multi_index_t<size>(ar);
}
基本思想是使用一个数组来保存一些dim
索引,然后实现operator++
来适当地增加这些索引。
使用
for(auto m : multi_index(3,3,4))
{
// now m[i] holds index of i-th loop
// m[0] goes from 0 to 2
// m[1] goes from 0 to 2
// m[2] goes from 0 to 3
std::cout<<m[0]<<" "<<m[1]<<" "<<m[2]<<std::endl;
}
生活在Coliru
您可以使用递归函数:
void loop_function(/*params*/,int N){
for(int i=0;i<9;++i){
if(N>0) loop_function(/*new params*/,N-1);
}
这将递归调用loop_function N次,而每个函数将迭代调用loop_function
这样编程可能有点困难,但它应该做您想做的事情
您可以使用递归调用:
void runNextNestedFor(std::vector<int> counters, int index)
{
for(counters[index] = 0; counters[index] < 9; ++counters[index]) {
// DO
if(index!=N)
runNextNestedFor(counters, index+1);
}
}
第一次调用为:
std::vectors<int> counters(N);
runNextNestedFor(counters, 0);
我将根据给出的示例代码的表面值采取OP,并假设要求的是通过任意以10为基数的数字计数的解决方案。(我基于这个评论"理想情况下,我试图找出一种方法来循环通过数字向量的不同元素来创建每个可能的数字"。
这个解决方案有一个循环,通过一个以10为基数的数字向量计数,并将每个连续的值传递给辅助函数(doThingWithNumber)。出于测试的目的,我让这个助手简单地打印出数字。
#include <iostream>
using namespace std;
void doThingWithNumber(const int* digits, int numDigits)
{
int i;
for (i = numDigits-1; i>=0; i--)
cout << digits[i];
cout << endl;
}
void loopOverAllNumbers(int numDigits)
{
int* digits = new int [numDigits];
int i;
for (i = 0; i< numDigits; i++)
digits[i] = 0;
int maxDigit = 0;
while (maxDigit < numDigits) {
doThingWithNumber(digits, numDigits);
for (i = 0; i < numDigits; i++) {
digits[i]++;
if (digits[i] < 10)
break;
digits[i] = 0;
}
if (i > maxDigit)
maxDigit = i;
}
}
int main()
{
loopOverAllNumbers(3);
return 0;
}
我为自己写了一些c++ 11代码来实现n嵌套for循环。下面是可以用作单个.hpp导入的代码的主要部分(我将其命名为nestedLoop.hpp):
#ifndef NESTEDLOOP_HPP
#define NESTEDLOOP_HPP
#include <vector>
namespace nestedLoop{
class nestedLoop {
public:
//Variables
std::vector<int> maxes;
std::vector<int> idxes; //The last element is used for boundary control
int N=0;
int nestLevel=0;
nestedLoop();
nestedLoop(int,int);
nestedLoop(int,std::vector<int>);
void reset(int numberOfNests, int Max);
void reset(int numberOfNests, std::vector<int> theMaxes);
bool next();
void jumpNest(int theNest);
private:
void clear();
};
//Initialisations
nestedLoop::nestedLoop(){}
nestedLoop::nestedLoop(int numberOfNests, int Max) {
reset(numberOfNests, Max);
}
nestedLoop::nestedLoop(int numberOfNests, std::vector<int> theMaxes) {
reset(numberOfNests, theMaxes);
}
void nestedLoop::clear(){
maxes.clear();
idxes.clear();
N = 0;
nestLevel = 0;
}
//Reset the scene
void nestedLoop::reset(int numberOfNests, int Max){
std::vector<int> theMaxes;
for(int i =0; i < numberOfNests; i++) theMaxes.push_back(Max);
reset(numberOfNests, theMaxes);
}
void nestedLoop::reset(int numberOfNests, std::vector<int> theMaxes){
clear();
N = numberOfNests;
maxes=theMaxes;
idxes.push_back(-1);
for(int i=1; i<N; i++) idxes.push_back(theMaxes[i]-1);
}
bool nestedLoop::next(){
idxes[N-1]+=1;
for(int i=N-1; i>=0; i--){
if(idxes[i]>=maxes[i]) {
idxes[i] = 0;
if(i){ //actually, if i > 0 is needed
idxes[i-1] += 1;
}else{
return false;
}
}else{
nestLevel = i;
break;
}
}
return true;
}
void nestedLoop::jumpNest(int theNest){
for(int i = N-1; i>theNest; i--) {
idxes[i] = maxes[i]-1;
}
}
}
#endif // NESTEDLOOP_HPP
下面是一个期望输出的示例:
#include <iostream>
#include "stlvecs.hpp"
#include "nestedLoop.hpp"
int main(){
nestedLoop::nestedLoop looper;
std::vector<int> maxes = {2, 3, 2, 2};
looper.reset(4,maxes);
int i = 0;
while(looper.next()){
std::cout << "Indices: " << looper.idxes << ", Last nest incremented: " << looper.nestLevel << std::endl;
if(i == 5){
std::cout << "...Jump Second Nest (index 1)..." << std::endl;
looper.jumpNest(1);
}
i++;
}
}
/* Expected output
Indices: 4 0 0 0 0 , Last nest incremented: 0
Indices: 4 0 0 0 1 , Last nest incremented: 3
Indices: 4 0 0 1 0 , Last nest incremented: 2
Indices: 4 0 0 1 1 , Last nest incremented: 3
Indices: 4 0 1 0 0 , Last nest incremented: 1
Indices: 4 0 1 0 1 , Last nest incremented: 3
...Jump Second Nest (index 1)...
Indices: 4 0 2 0 0 , Last nest incremented: 1
Indices: 4 0 2 0 1 , Last nest incremented: 3
Indices: 4 0 2 1 0 , Last nest incremented: 2
Indices: 4 0 2 1 1 , Last nest incremented: 3
Indices: 4 1 0 0 0 , Last nest incremented: 0
Indices: 4 1 0 0 1 , Last nest incremented: 3
Indices: 4 1 0 1 0 , Last nest incremented: 2
Indices: 4 1 0 1 1 , Last nest incremented: 3
Indices: 4 1 1 0 0 , Last nest incremented: 1
Indices: 4 1 1 0 1 , Last nest incremented: 3
Indices: 4 1 1 1 0 , Last nest incremented: 2
Indices: 4 1 1 1 1 , Last nest incremented: 3
Indices: 4 1 2 0 0 , Last nest incremented: 1
Indices: 4 1 2 0 1 , Last nest incremented: 3
Indices: 4 1 2 1 0 , Last nest incremented: 2
Indices: 4 1 2 1 1 , Last nest incremented: 3
*/
我使用这个解决方案:
unsigned int dim = 3;
unsigned int top = 5;
std::vector<unsigned int> m(dim, 0);
for (unsigned int i = 0; i < pow(top,dim); i++)
{
// What you want to do comes here
// |
// |
// v
// -----------------------------------
for (unsigned int j = 0; j < dim; j++)
{
std::cout << m[j] << ",";
}
std::cout << std::endl;
// -----------------------------------
// Increment m
if (i == pow(top, dim) - 1) break;
unsigned int index_to_increment = dim - 1;
while(m[index_to_increment] == (top-1)) {
m[index_to_increment] = 0;
index_to_increment -= 1;
}
m[index_to_increment] += 1;
}
它当然可以优化和调整,但它工作得很好,你不需要向递归函数传递参数。使用一个单独的函数来增加多索引:
typedef std::vector<unsigned int> ivec;
void increment_multi_index(ivec &m, ivec const & upper_bounds)
{
unsigned int dim = m.size();
unsigned int i = dim - 1;
while(m[i] == upper_bounds[i] - 1 && i>0) {
m[i] = 0;
i -= 1;
}
m[i] += 1;
}
int main() {
unsigned int dim = 3;
unsigned int top = 5;
ivec m(dim, 0);
ivec t(dim, top);
for (unsigned int i = 0; i < pow(top,dim); i++)
{
// What you want to do comes here
// |
// |
// v
// -----------------------------------
for (unsigned int j = 0; j < dim; j++)
{
std::cout << m[j] << ",";
}
std::cout << std::endl;
// -----------------------------------
// Increment m
increment_multi_index(m, t);
}
}
相关文章:
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么我的for循环不能正确获取argv
- 在基于范围的for循环中使用结构化绑定声明
- 通过for循环使用用户输入填充列表
- 使用for循环检查数组中的重复项
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 正在使用for循环创建QScatterSerie
- Python中的for循环与C++有何不同
- 在更改for循环的第三部分后,未使用for循环结果
- 在 for 循环中查找问题时遇到困难
- 嵌套for循环C++的问题(初学者)
- 如何用for循环在c++中生成单词三角形
- 如何在for循环中包含两个索引值的测试条件
- 带有多个独立参数的C++For循环
- 为什么我的程序在for循环中k=0时返回垃圾值
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- C++-For循环未执行
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- C++ 无法在字符数组中使用 for 循环打印字母模式