简体   繁体   English

javascript:将for循环创建为for循环

[英]javascript : create for loops into for loops

I had to solve the following problem: 我必须解决以下问题:

问题

9 values, from 1 to 9 (0 and 10 not accepted) and all numbers need to be different . 9个值,从1到9(不接受0和10),并且所有数字都必须不同

To solve the probem, I made those horrible for loops inside for loops. 为了解决这个问题,我在for循环中将for循环变成了可怕的循环。
(I added 2 more conditions to check if i had one of the solutions) (我添加了2个条件来检查是否有其中一种解决方案)
It is working, but I was wondering how to create those for loops inside for loops in a better way? 它正在工作,但是我想知道如何以更好的方式在for循环内创建这些for循环?

Also, each number can't be equal to another. 另外,每个数字不能等于另一个。 How can you accomplish this another way than I did? 您如何能以不同于我的方式完成此任务? (Again, 2 first conditions can be deleted) (同样,可以删除2个第一个条件)

Here is code: 这是代码:

var a = 1, b = 1, c = 1, d = 1, e = 1, f = 1, g = 1, h = 1, i = 1;

var x = 0;

var result = [];

function calc(){

  x = a + 13 * b / c + d + 12 * e - f - 11 + g * h / i - 10;

  if(x == 66){
     result.push([a, b , c , d , e, f, g, h, i] );
  }
}

for(a = 1; a < 10; a++){
    calc();
    for(b = 1; b < 10; b++){
        calc();
        for(c = 1; c < 10; c++){
            calc();
            for(d = 1; d < 10; d++){
                calc();
                for(e = 1; e < 10; e++){
                    calc();
                    for(f = 1; f < 10; f++){
                        calc();
                        for(g = 1; g < 10; g++){
                            calc();
                            for(h = 1; h < 10; h++){
                                calc();
                                for(i = 1; i < 10; i++){
                                    calc();
                                }
                            }
                        }
                    }
                }
            }
        }
    }

}

console.log(result);

var result2 = result.filter(function(el){

    return el[0] == 5 && el[1] == 9 && el[0] != el[1] &&  el[0] != el[2] && el[0] != el[3] && el[0] != el[4] &&   el[0] != el[5] &&   el[0] != el[6] &&   el[0] != el[7] &&   el[0] != el[8] && el[1] != el[0] && el[1] != el[2] && el[1] != el[3] && el[1] != el[4] &&   el[1] != el[5] &&   el[1] != el[6] &&   el[1] != el[7] && el[1] != el[8] &&  el[2] != el[0] && el[2] != el[1] && el[2] != el[3] && el[2] != el[4] && el[2] != el[5] && el[2] != el[6] &&  el[2] != el[7] && el[2] != el[8] && el[3] != el[0] && el[3] != el[1] && el[3] != el[2] && el[3] != el[4] && el[3] != el[5] && el[3] != el[6] && el[3] != el[7] &&  el[3] != el[8] &&  el[4] != el[0] && el[4] != el[1] && el[4] != el[2] && el[4] != el[3] && el[4] != el[5] && el[4] != el[6] && el[4] != el[7] && el[4] != el[8] && el[5] != el[0] && el[5] != el[1] && el[5] != el[2] && el[5] != el[3] && el[5] != el[4] && el[5] != el[6] && el[5] != el[7] && el[5] != el[8] && el[6] != el[1] && el[6] != el[2] && el[6] != el[3] && el[6] != el[4] && el[6] != el[5] && el[6] != el[7] && el[6] != el[8] && el[7] != el[0] && el[7] != el[1] && [7] != el[2] && el[7] != el[3] && el[7] != el[4] && el[7] != el[5] && el[7] != el[6] && el[7] != el[8] && el[8] != el[0] && el[8] != el[1] && el[8] != el[2] && el[8] != el[3] && el[8] != el[4] && el[8] != el[5] && el[8] != el[6] && el[8] != el[7];

});

console.log(result2);

for starters you can make N x nested for loops like this 对于初学者,您可以像这样将N x嵌套for循环

You can handle your problem as a 9 digit number generation 您可以通过9位数字生成来解决您的问题

As your digits are not repeating you can discard many iterations. 由于数字不重复,因此您可以放弃许多迭代。 If encoded in the above manner (like nested for) you will came up with something like this: 如果以上述方式编码(如嵌套),您将想到以下内容:

Generalized Permutation (without repetitions) in C++: C ++中的广义置换(无重复):

//---------------------------------------------------------------------------
//--- permutation class ver 0.00 --------------------------------------------
//---------------------------------------------------------------------------
#ifndef _permutation_h
#define _permutation_h
/*---------------------------------------------------------------------------
    // usage:
    permutation per;
    per.alloc(N);

    per.first();
    for (;;)
        {
        ... here per.i[0..N-1] contains actual permutation
        ... N! permutations
        if (!per.next()) break;
        }
//-------------------------------------------------------------------------*/
class permutation
    {
public:
    int  *i;    // i[N] permutation
    BYTE *a;    // a[N] item not used yet ?
    int   N;    // items
    int  ix;    // actual permutation layer
    permutation()   { N=0; i=NULL; a=NULL; ix=0; }
    permutation(permutation& b) { *this=b; }
    ~permutation()  { free(); }
    permutation* operator = (const permutation *b) { *this=*b; return this; }
    permutation* operator = (const permutation &b) { alloc(b.N); for (int j=0;j<N;j++) { i[j]=b.i[j]; a[j]=b.a[j]; } ix=b.ix; return this; }

    void alloc(int _N)
        {
        free();
        i=new  int[_N];
        if (i==NULL) return;
        a=new BYTE[_N];
        if (a==NULL) { free(); return; }
        N=_N;
        }
    void free ()
        {
        N=0; ix=0;
        if (i!=NULL) delete i; i=NULL;
        if (a!=NULL) delete a; a=NULL;
        }
    void first()                                        // init permutation
        {
        for (ix=0;ix<N;ix++)
            {
            i[ix]=ix;
            a[ix]=0;
            } ix--;
        }
    bool next()                                         // next permutation return if it is not last
        {
        int *ii=&i[ix];
        for (;;)
            {
            if (*ii>=0) a[*ii]=1;
            for ((*ii)++;*ii<N;(*ii)++) if (a[*ii]) { a[*ii]=0; break; }
            if (*ii>=N)
                {
                if (ix==  0) return false;
                *ii=-1; ix--; ii=&i[ix];
                }
            else{
                if (ix==N-1) return true;
                ix++; ii=&i[ix];
                }
            }
        }
    };
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

The important stuff is in first() and next() members, each permutation is stored in the i[] array as index so set N=9 and your output numbers will be (per.i[0]+1),(per.i[1]+1),...,(per.i[9]+1) 重要的是在first()next()成员中,每个排列都作为索引存储在i[]数组中,因此设置N=9 ,您的输出数将是(per.i[0]+1),(per.i[1]+1),...,(per.i[9]+1)

it works in following manner: 它以以下方式工作:

  1. first() initialize permutation to state i[9]=(0,1,2,...8) and a[9]=(0,0,0,...0) first()将置换初始化为状态i[9]=(0,1,2,...8)a[9]=(0,0,0,...0)

    I will write this for simplicity like this: i=012345678,a=000000000 where 为了简化起见,我将这样编写: i=012345678,a=000000000其中

    • ix points to last digit ix指向最后一位数字
    • i is the actual permutation i是实际的排列
    • a flags if digit is unused(1) or used(0) (to avoid O(N^N) operation) a标志,指示数字是否未使用(1)或已使用(0)(以避免O(N^N)操作)
  2. next() increment to next valid permutation next()递增到下一个有效排列

    Increase the last digit to next unused value. 将最后一位增加到下一个未使用的值。 If no unused value set it as unused and increment previous digit. 如果没有未使用的值,则将其设置为未使用并递增前一位。 The same goes for overflow. 溢出也是如此。 The first iteration will be like this: 第一次迭代将如下所示:

     i=012345678,a=000000000 // starting iteration i=01234567? a=000000001 // unset (no unused values) i=01234568? a=000000010 // increment 8th digit i=012345687 a=000000000 // set the last digit result 

    next iteration: 下一次迭代:

     i=012345687 a=000000000 // starting iteration i=01234568? a=000000010 // unset (no unused values) i=0123456?? a=000000011 // unset (8->9 overflow) i=0123457?? a=000000101 // increment 7th digit i=01234576? a=000000001 // after overflow digit set to lowest free value i=012345768 a=000000000 // after overflow digit set to lowest free value 

    I hope it is clear enough. 我希望它足够清楚。

Of coarse if you use recursion instead of iteration the code will look much nicer but in most languages will run also slower due to stack/heap trashing 如果使用递归而不是迭代的话,代码看起来会好很多,但是在大多数语言中,由于堆栈/堆的乱码,其运行速度也会变慢

As @NikolaDimitroff pointed out this is in C++ instead of javascript so: 正如@NikolaDimitroff指出的那样,这是C ++而不是javascript,因此:

  • ignore new,delete and class members other then first(),next() 忽略除first(),next() new,deleteclass成员
  • set N=9; 设置N=9; and arrays i,a can be static like: int i[9]; BYTE a[9]; 和数组i,a可以是静态的,例如: int i[9]; BYTE a[9]; int i[9]; BYTE a[9];

Here the solution O(N!) for the task in C++: 这是C ++中任务的解决方案O(N!)

int a,b,c,d,e,f,g,h,i;
permutation per;
per.alloc(9);
per.first();
for (;;)
    {
    if ((per.i[0]+1)
        +(13*(per.i[1]+1)/(per.i[2]+1))+(per.i[3]+1)
        +(12*(per.i[4]+1))
        -(per.i[5]+1)-11
        +((per.i[6]+1)*(per.i[7]+1)/(per.i[8]+1))-10
        ==66)
        {
        a=per.i[0]+'1';
        b=per.i[1]+'1';
        c=per.i[2]+'1';
        d=per.i[3]+'1';
        e=per.i[4]+'1';
        f=per.i[5]+'1';
        g=per.i[6]+'1';
        h=per.i[7]+'1';
        i=per.i[8]+'1';
        // here a,b,c,d,e,f,g,h,i holds the solution
        break;
        }
    if (!per.next()) break;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM