Imagine you are representing numbers with an array of digits. For example, 682 would be [6,8,2].
如果你想从0到999人计算,你可以写:
for (int n[0] = 0; n[0] <= 9; ++n[0])
for (int n[1] = 0; n[1] <= 9; ++n[1])
for (int n[2] = 0; n[2] <= 9; ++n[2])
// Do something with three digit number n here
但是,当你想计算到99999人时,你需要额外住宿。
相反,如果把最后一位数推到前面的数位数,你则采用增加1位数的程序:如果把最后一位数推到前面的数位数,则增加该数。 当第一位数位数人流出时,你们的休息就已完成。 这涉及数位数。
你们需要一种类似的程序,以“增加1”替代 your变。
添加最后的“数字”,即<代码>a[g]。 如果超支(即超过2g-1
>),则转入下一个最重要的“数字”(a[g-1]
)和重复。 与数字相比,稍加复杂的是,随着价值流逝而回到阵列后,你需要将溢出的数位数重新打入新的基值(取决于左边的数值)。
下面的C#代码既执行方法,也印刷了通往青少年的阵列。
static void Print(int[] a, int n, ref int count)
{
++count;
Console.Write("{0} ", count);
for (int i = 0; i <= n; ++i)
{
Console.Write("{0} ", a[i]);
}
Console.WriteLine();
}
private static void InitialiseRight(int[] a, int startIndex, int g)
{
for (int i = startIndex; i <= g; ++i)
a[i] = a[i - 1] + 1;
}
static void Main(string[] args)
{
const int g = 5;
// Old method
int count = 0;
int[] a = new int[g + 1];
a[0] = 1;
for (a[1] = a[0] + 1; a[1] <= 2; ++a[1])
for (a[2] = a[1] + 1; a[2] <= 3; ++a[2])
for (a[3] = a[2] + 1; a[3] <= 5; ++a[3])
for (a[4] = a[3] + 1; a[4] <= 7; ++a[4])
for (a[5] = a[4] + 1; a[5] <= 9; ++a[5])
Print(a, g, ref count);
Console.WriteLine();
count = 0;
// New method
// Initialise array
a[0] = 1;
InitialiseRight(a, 1, g);
int index = g;
// Loop until all "digits" have overflowed
while (index != 0)
{
// Do processing here
Print(a, g, ref count);
// "Add one" to array
index = g;
bool carry = true;
while ((index > 0) && carry)
{
carry = false;
++a[index];
if (a[index] > 2 * index - 1)
{
--index;
carry = true;
}
}
// Re-initialise digits that overflowed.
if (index != g)
InitialiseRight(a, index + 1, g);
}
}