这个 "number square" 问题是如何用取模运算符解决的?

How is this "number square" problem done with a modulus operator?

我在做一些练习时遇到了一个非常熟悉的问题,但我一直无法使用预期的方法——接受 (int min, int max) 参数的模数 % 运算符来解决这个问题作为开始和结束限制。

调用numberSquare(1, 5)打印如下:

12345
23451
34512
45123
51234

虽然我知道这不是正确的方法,但我实际上是通过创建一个手动跟踪器来让它工作的:

private static void numberSquare(int min, int max)
{   
    int difference = max - min;
    // outside loop
    for(int row = min; row <= max; row++)
    {
        // inside loop
        for(int col = row; col <= row + difference; col++)
        {   
            // is in bounds
            if(col <= max)
                System.out.print(col);
            // not in bounds
            else
                System.out.print(col - difference - 1);
        } // next line
        System.out.println();
    }
}

我使用运算符的其他方法的内部循环如下所示:

// is in bounds
if(col <= max)
    System.out.print(col);
// not in bounds
else
    System.out.print(col % max + min);

这给了我一个输出:

|12345|                  |12345|
|23452|                  |23451|
|34523|    instead of    |34512|
|45234|                  |45123|
|52345|                  |51234|

我真的很想知道如何使用模数 % 运算符来做到这一点,并且会喜欢任何 help/suggestions.

编辑以获取更多信息

我有另一个版本可以工作,但这个版本也没有 % 运算符...

private static void numberSquare(int min, int max)
{
    // track outside rows
    for(int row = min ; row <= max; row++)
    {
       // track inside columns and the print value
       for(int col = min, value = row; 
               col <= max; col++, value++)
       {
           // reset if the value is too high
           value = (value > max) ? min : value;
           System.out.print(value);
       } 
       // next line
       System.out.println();
    } 
}

假设您的 整数 abcd,其中每个字母都是一个数字。您可以通过首先分离 bcda

来进行左循环移位
bcd = abcd % 1000
a = abcd / 1000 (integer division)

然后,构造bcda

的左循环移位
bcda = bcd * 10 + a

在 Java 中,这就是我的实现方式

void numSquare(int min, int max) {
    int number = 0;
    int div = 1;
    // construct the integer, e.g., 12345, and the corresponding power of tens
    for (int i = max; i >= min; --i) {
        number += i * div;
        div *= 10;
    }
    div /= 10;
    
    // left cyclic shifting the integer and printing
    int nShifts = max - min + 1;
    for (int i = 0; i < nShifts; ++i) {
        System.out.println(number);
        number = (number % div) * 10 + (number / div);
    }
}

如果要打印 digit-by-digit 并且必须使用 %,技巧是将列减去 min 以将范围移动到 [0, max-min],使用 %达到最大值后复发,然后re-addmin恢复正常范围,像这样

void numSquare(int min, int max) {
    int len = max - min + 1;
    for (int row = min; row <= max; row++) {
        for (int col = row; col < row + len; col++) {
            System.out.print((col - min) % len + min);
        }
        System.out.println(); // break line when we do a new row
    }
}

如果可能的话,我建议不要使用这种方法,因为它会多次调用 System.out.print,随着时间的推移会累积起来。

您可以将值计算为 (row + col - 2) % max + 1