在C中的运行时生成嵌套循环 [英] Generating Nested Loops at Run Time in C

查看:47
本文介绍了在C中的运行时生成嵌套循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道使用递归方法,但是它仅适用于开头和结尾语句与下面的代码相同的循环

I know using recursions way but it works just for loops which beginning and ending statements are same like code below

for (int i=1 ; i<5;i++){
    for (int j=0; j<5;j++){
       for (int m= 0;m<5;m++) {
           // N time
       }
    }
}

但是我的问题不同.我不知道N级别以及编译时的开始和结束语句.我将在运行时向用户学习.

But my problem is different. I do not know N level and beginning and ending statements at compile time. I will learn them from user at Run Time.

赞:

for (int i=1 ; i<5;i++){
        for (int j=5; j<18;j++){
           for (int m= 4;m<5;m++) {
               // N time
           }
        }
    }

所以我的问题是:有没有办法在编译时不知道N的情况下为循环创建嵌套的N级?

So my question is : Is there a way to create nested N level for loop without knowing N at compile time?

推荐答案

您可以通过构造一些数据来充当迭代器并将其视为要迭代的单个对象来完成此操作.该数据将为您要迭代的每个维度包含一个单独的计数器,并且将通过自身在每个维度上进行迭代的函数对其进行初始化,测试和递增.这是一个使用简单数组作为计数器的示例.

You can do this by constructing some data to act as an iterator and treating it as a single thing that is iterated. That data will contain a separate counter for each dimension you wish to iterate, and it will be initialized, tested, and incremented by functions that themselves iterate over each dimension. Here is an example using a simple array for the counters.

#include <string.h>


//  Initialize counters to their start values.
static void InitializeCounters(long N, long *Counters, const long *Starts)
{
    memcpy(Counters, Starts, N * sizeof *Counters);
}


//  Return 1 if there are more values to iterate, 0 otherwise.
static int MoreToIterate(long N, long *Counters, const long *Ends)
{
    return Counters[0] < Ends[0];
}


//  Increment the counters, lexicographic (dictionary/odometer) style.
static void IncrementCounters(long N, long *Counters, const long *Starts,
    const long *Ends)
{
    /*  Increment each dimension (except the first will be special).  If it
        rolls over its end, reset it to its start and go on the next dimension.
        If it does not roll over, stop there.
    */
    for (long i = N-1; 0 < i; --i)
        if (++Counters[i] < Ends[i])
            return;
        else
            Counters[i] = Starts[i];

    /*  For dimension zero, do not reset it, so MoreToIterate can see it
        finished.
    */
    ++Counters[0];
}


#include <stdio.h>
#include <stdlib.h>


static void _Noreturn Usage(char *argv[])
{
    fprintf(stderr, "Usage: %s <N>\n", argv[0]);
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
    if (argc != 2)
        Usage(argv);

    char *end;
    long N = strtol(argv[1], &end, 0);
    if (*end != '\0')
        Usage(argv);

    if (N < 0)
        Usage(argv);

    long *Counters = malloc(N * sizeof *Counters);
    long *Starts   = malloc(N * sizeof *Starts);
    long *Ends     = malloc(N * sizeof *Ends);
    if (!Counters || !Starts || !Ends)
    {
        fprintf(stderr, "Error, unable to allocate memory.\n");
        exit(EXIT_FAILURE);
    }

    //  Initialize start and end values as desired.
    for (long i = 0; i < N; ++i)
    {
        Starts[i] = 0;
        Ends[i]   = i+1;
    }

    for (   InitializeCounters(N, Counters, Starts);
            MoreToIterate(N, Counters, Ends);
            IncrementCounters(N, Counters, Starts, Ends))
    {
        for (long i = 0; i < N; ++i)
            printf("%ld ", Counters[i]);
        printf("\n");
    }

    free(Ends);
    free(Starts);
    free(Counters);
}

使用参数"3"执行时的示例输出为:

Sample output when executed with argument "3" is:


0 0 0 
0 0 1 
0 0 2 
0 1 0 
0 1 1 
0 1 2 

这篇关于在C中的运行时生成嵌套循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆