从一维数组中获取二维数组的索引

4

我正在尝试使用一个循环遍历二维数组中的所有元素。

这是我的代码:

public class Test {
    private static final String[][] key = {
        {"`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "Backspace"}, // 0 - 13
        {"Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\"},      // 0 - 13
        {"Caps", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter"},       // 0 - 12
        {"Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "\u2191"},          // 0 - 11
        {" ", "<", "\u2193", ">"}                                                       // 0 - 3
    };

    public static void main(String[] args) {
        final int totalLen = 57;
        String str = "";

        for (int i = 0, row = 0, col = 0; i < totalLen; ++i, ++col) {

            if (row < key.length && i % key[row].length >= key[row].length - 1) {
                ++row;
                col = 0;
                System.out.println(str);
                str = "";
            }

            if (row < key.length)
                str += col + " ";
        }
    }
}

我已经为上述程序中每行注释了索引范围,但由于逻辑错误,它并没有输出。有什么建议吗?
编辑:循环条件必须保持不变。

使用“魔数”(57)和坚持“条件必须保持不变”的目的是什么?可读性差,可维护性差...如果元素数量不是57会发生什么?期望异常吗? - laune
我在一个答案的注释中解释了原因。 57 不是魔数,而是数组中元素的总数。 “i” 用作另一个与此无关的数组的索引。 - user2570380
首先你需要冷静一点。元素数量已经在之前计算过了,所以不可能不是57个。我从示例中删除了无关的细节。 - user2570380
我对 OP 坚持维持一个不自然的循环条件感到惊讶,最终 (totalLen) 被设置为一个在编译时之前计算出来的值。 - laune
你为什么假设它是在编译时之前?“更早”指的是在此方法中使用之前。我编写了一个循环来计数,然后存储它 - 运行时。我不需要通过包含该循环来混淆问题。我只是对你对条件的固执感到惊讶。 - user2570380
我对这个循环条件的坚持感到惊讶,因为我既看不到它的必要性,也看不到它的优势。 - laune
3个回答

2

您应该能够使用两个变量rowcol来完成,其中col在循环头中递增,而row在循环体中有条件地递增:

for (int row =0, col = 0 ; row != key.length ; col++) {
    System.out.println(row + " " + col);
    if (col == key[row].length-1) {
        row++;
        col = 0;
    }
}

循环条件不能改变。抱歉,我忘了提醒。

您也可以添加i并在达到totalLen时停止:

for (int row =0, col = 0, i = 0 ; i != totalLen ; col++, i++) {
    System.out.println(row + " " + col);
    if (col == key[row].length-1) {
        row++;
        col = 0;
    }
}

然而,这种方法更加脆弱,因为你需要依赖于正确计算出 totalLen 的值。

两个解决方案都打印出了错误的输出,OP的代码意图是为每一行生成“col”值,请参考我的答案。 - Óscar López

0

尝试这个解决方案,它使用单个while循环和与问题相同的循环条件(如所请求):

String str = "";
int row = 0, col = 0;
int i = 0, totalLen = 57;

while (i < totalLen) {
    if (col < key[row].length) {
        str += col++ + " ";
        i++;
    } else {
        System.out.println(str);
        str = "";
        row++;
        col = 0;
    }
}
System.out.println(str); // prints the last line

或者,如果您更喜欢使用 for 循环:

String str = "";
int totalLen = 57;

for (int i = 0, row = 0, col = 0; i < totalLen; i++) {
    str += col++ + " ";
    if (col == key[row].length) {
        row++;
        col = 0;
        System.out.println(str);
        str = "";
    }
}

无论哪个代码片段,都会在控制台上产生以下输出:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 
0 1 2 3 4 5 6 7 8 9 10 11 12 
0 1 2 3 4 5 6 7 8 9 10 11 
0 1 2 3

0

好的,我尝试保持您的循环条件不变...但我并没有使用每个参数。无论如何,它应该可以工作:

for (int i = 0, row = 0, col = 0; i < totalLen; ++i, ++col) {
    System.out.println("row " + row + ", col " + col);
    // what ever you want to do with your loop, do it here
    // before altering the row and col parameters

    if (col == key[row].length-1) {
        col = -1;   // if end of the row, set col to -1, it will be incremented in the next loop
        row++;
        if(row==key.length){
            break;
        }
    }
}

基本上它和@dasblinkenlight所做的几乎相同-只是当row变量达到key数组的长度时,我引入了一个break条件。您也可以测试if(i==totalLen),但个人觉得检查数组长度更可靠。


@user2570380,你是对的,我已经纠正了。抱歉。 - GameDroids

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接