Dapatkan indeks array 2D dari 1D

Jadi, saya mencoba mengulangi semua elemen dalam array 2D menggunakan satu loop.

Di sinilah saya berada:

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 + " ";
        }
    }
}

Saya telah mengomentari rentang indeks untuk setiap baris yang harus dihasilkan oleh program di atas, tetapi tidak karena logikanya salah. Ada saran?

Sunting: Kondisi perulangan harus tetap sama.


person Community    schedule 13.07.2014    source sumber
comment
Apa gunanya menggunakan angka ajaib (57) dan syaratnya harus tetap sama? Keterbacaan dan pemeliharaan buruk... Apa yang terjadi jika jumlah elemen BUKAN 57? Harapkan pengecualian!?   -  person laune    schedule 13.07.2014
comment
Saya menjelaskan alasannya dalam komentar di salah satu jawaban. 57 bukan angka ajaib, melainkan jumlah total elemen dalam array. i digunakan sebagai indeks untuk array lain yang tidak relevan di sini.   -  person    schedule 13.07.2014
comment
@laune Sunting: Apa yang terjadi jika jumlah elemen BUKAN 57? Harapkan pengecualian!? Pertama, Anda perlu sedikit bersantai. Jumlah elemen dihitung lebih awal, jadi tidak ada kemungkinan tidak menjadi 57. Saya menghapus detail yang tidak relevan dari contoh.   -  person    schedule 13.07.2014
comment
Saya hanya terkejut dengan desakan OP untuk mempertahankan kondisi loop yang tidak wajar, dengan final (totalLen) disetel ke nilai yang dihitung sebelumnya, yaitu sebelum waktu kompilasi.   -  person laune    schedule 14.07.2014
comment
Mengapa Anda berasumsi ini sebelum waktu kompilasi? Sebelumnya seperti sebelumnya digunakan dalam metode ini. Saya menulis satu lingkaran untuk menghitungnya dan kemudian menyimpannya -- run-time. Saya tidak perlu mengacaukan pertanyaan dengan memasukkan loop itu. Saya hanya heran dengan fiksasi Anda terhadap kondisi tersebut.   -  person    schedule 15.07.2014
comment
Saya heran dengan desakan kondisi loop ini karena saya tidak melihat perlunya maupun keuntungannya.   -  person laune    schedule 15.07.2014


Jawaban (3)


Coba solusi ini, ini menggunakan satu loop while dan kondisi loop yang sama dari pertanyaan (seperti yang diminta):

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

Alternatifnya, jika Anda lebih suka menggunakan perulangan 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 = "";
    }
}

Cuplikan mana pun akan menghasilkan keluaran berikut di konsol:

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
person Óscar López    schedule 13.07.2014

Anda harus dapat melakukannya dengan dua variabel row dan col, di mana col bertambah di header perulangan, dan row bertambah secara kondisional di badan perulangan:

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

Kondisi loop tidak boleh berbeda. Maaf, saya lupa menyebutkannya.

Anda juga dapat menambahkan i dan berhenti ketika Anda mencapai 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;
    }
}

Namun, ini lebih rapuh, karena Anda mendapatkan ketergantungan pada totalLen yang dihitung dengan benar.

person Sergey Kalinichenko    schedule 13.07.2014
comment
Kedua solusi mencetak keluaran yang salah, kode OP bermaksud menghasilkan nilai col untuk setiap baris, lihat jawaban saya. - person Óscar López; 13.07.2014

Oke, saya mencoba menjaga kondisi loop Anda apa adanya... tapi saya tidak menggunakan setiap parameter. Bagaimanapun, ini harusnya berhasil:

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;
        }
    }
}

pada dasarnya hampir sama dengan yang dilakukan @dasblinkenlight – hanya saja saya memperkenalkan kondisi break ketika variabel row mencapai panjang array key. Anda juga dapat menguji if(i==totalLen) tetapi secara pribadi menurut saya lebih dapat diandalkan untuk memeriksa panjang array.

person GameDroids    schedule 13.07.2014
comment
@ user2570380, Anda benar, saya memperbaikinya. Maaf - person GameDroids; 14.07.2014