我想创建一个嵌套循环,其中嵌套深度由数组上的大小决定。例如,我有一个整数数组

我想检查所有的元组

哪里

。有没有一种方法可以简单地用c# (或任何其他语言)来做到这一点?
我唯一简单的想法是将这些数字相乘,然后执行一个for循环,直到那个数字,但不幸的是,乘积达到了int的极限。同样,在这种情况下,我没有办法在每个级别上添加额外的条件。
下面是一个小示例和产品方法:
int[] a = new int[]{2, 3, 2}; //we have an array like this. In the description above it is a_1, a_2, a_3
void f(int[] i) //I have a function that works on an array input
{...}
bool check(int[] i) //I have a checker function, with an array parameter too
{...}
//And I would like to perform this function on all these arrays
//f({0, 0, 0})
//f({0, 0, 1})
//010
//011
//020
//021
//100
//101
//110
//111
//120
//f({1, 2, 1})
//But if let's say check({1, 0}) is false then don't perform the f function on {1, 0, 0} and {1, 0, 1}
//A simple implementation if we know the size of the array a is the following
for(int i1=0;i1<a[0];i1++)
{
if(!check({i1}))
continue;
for(int i2=0;i2<a[1];i2++)
{
if(!check({i1, i2}))
continue;
for(int i3=0;i3<a[2];i3++)
{
if(!check({i1, i2, i3}))
continue;
f({i1, i2, i3});
}
}
}
//But this obviously fails as we have no idea apriori of the size of the array a
//An alternative I have is the following:
int prod = 1;
foreach(int x in a)
{
prod *= x;
}
for(int c=0;c<prod;c++)
{
int d=c;
int[] i = new int[a.Length];
for(int l=0;l<a.Length;l++)
{
i[l]=d%(a[l]);
d /= a[l];
}
f(i);
}
//But the problem with this implementation is that in my case prod is larger than the int limit. Also this loops through all the incorrect cases too, where the check function can highly reduce the number of cases to calculate.发布于 2020-11-29 10:03:07
我已经设法解决了这个问题。这个想法是,将i值增加1真的很容易,我们可以检查条件,我们不会超过a值,也不会轻易违反check函数。下面是一个可以工作的代码
int[] a = ...;
void f(int[] i){...}
bool check(int[] i){...}
int n = a.Length;
int[] i = new int[n];
while (true) //keep increasing the coordinates of i, while we can
{
for (int l = 0; l < n; l++)
{
int[] il = copyFirst(i, l);
while(!check(il)) //check for all first few coordinates if it is correct, skip if incorrect.
//There is a way to improve this even further, as we don't have to check the first few
// coords if it was correct before, so should only care about the recently changed section
{
i = increase(a, i, l);
if (i == null)
{
return;
}
else
{
il = copyFirst(i, l);
}
}
}
f(i);
i = increase(a, i, n-1);
if (i == null) return;
}
int[] copyFirst(int[] i, int l) //this is just a small helper function to copy the first few elements of i, to use in the check
{
int[] ret = new int[l];
for (int k = 0; k < l; k++)
{
ret[k] = i[k];
}
return ret;
}
int[] increase(int[] a, int[] i, int l) //this results in the increased vector and in null if we've reached the end
{
for (int k = l; k >= 0; k--)
{
i[k] = i[k] + 1;
if (i[k] >= a[k])
{
i[k] = 0;
}
else
{
return i;
}
}
return null;
}https://stackoverflow.com/questions/65055699
复制相似问题