3

マトリックスから特定の方向、たとえば右下のすべての対角線を抽出しようとしています。

次のマトリックスの場合:

A   B   C   D
E   F   G   H
I   L   M   N

期待される結果は

[ [A F M], [B G N], [C H], [D], [E L], [I] ]

一般的なアプローチを歓迎します。

私が使用している言語はJavaです。

ありがとう!

編集

String[] grid = {"SUGAR", 
                 "GLASS", 
                 "MOUSE"};

for( int k = 0; k < grid.length; k++ )
{   
    StringBuffer buffer = new StringBuffer( );

    for( int i = 0; i < grid.length
                && i+k < grid[0].length( ); i++ )
    {
        buffer.append( grid[i].charAt(i+k) );
    }

    trie.addWord( buffer.toString() );
}

トライに追加された出力ワードは

[ "SLU" "UAS" "GSE" ]

トライに格納されている予想される文字列(順序は関係ありません)

[ "SLU" "UAS" "GSE" "GO" "M" "AS" "R"]
4

4 に答える 4

2

データが表形式の場合は、マトリックスを最初の列までスキャンしてから、最初の行を横切って左に移動することができます。

final String[M][N] mtx = { ... };

public List<List<String>> diagonalize() {
    final List<List<String>> diags = new ArrayList<>();
    for (int row = M - 1; row > 1; --row) {
        diags.add(getDiagonal(row, 0));
    }
    for (int col = 0; col < N; ++col) {
        diags.add(getDiagonal(0, col));
    }
    return diags;
}

private List<String> getDiagonal(int x, int y) {
    final List<String> diag = new ArrayList<>();
    while (x < M && y < N) {
        diag.add(mtx[x++][y++]);
    }
    return diag;
}
于 2013-06-11T14:14:18.643 に答える
2

これは解決すべき興味深い問題でした。

ネストされたループに巻き込まれるのは簡単です。

単語を1つの文字列にまとめると、パターンが浮かび上がることに気づきました。

OPを例にとると、「SUGAR」、「GLASS」、「MOUSE」の3つの単語が連結されてSUGARGLASSMOUSEになります。

連結された文字列から取得する必要がある文字のゼロベースの文字位置は次のとおりです。柄が見やすいように並べました。

          10     M
     5    11     GO
0    6    12     SLU
1    7    13     UAS
2    8    14     GSE
3    9           AS
4                R

まだパターンを見ますか?5回の反復で構成される3つのインデックスがあります。私は5文字からなる3つの単語を持っています。

対角線の単語数はですletters + words - 1。文字位置0の最初の文字は1回しか使用されないため、1を減算します。

これが私が実行したテストの結果です。

[ "SUGAR" "GLASS" "MOUSE" "STATE" "PUPIL" "TESTS" ]
[ "T" "PE" "SUS" "MTPT" "GOAIS" "SLUTL" "UASE" "GSE" "AS" "R" ]

[ "SUGAR" "GLASS" "MOUSE" ]
[ "M" "GO" "SLU" "UAS" "GSE" "AS" "R" ]

そしてここにコードがあります:

import java.util.ArrayList;
import java.util.List;

public class Matrix {

    public static final int DOWN_RIGHT = 1;
    public static final int DOWN_LEFT = 2;
    public static final int UP_RIGHT = 4;
    public static final int UP_LEFT = 8;

    public String[] getMatrixDiagonal(String[] grid, int direction) {
        StringBuilder builder = new StringBuilder();
        for (String s : grid) {
            builder.append(s);
        }
        String matrixString = builder.toString();

        int wordLength = grid[0].length();
        int numberOfWords = grid.length;
        List<String> list = new ArrayList<String>();


        if (wordLength > 0) {
            int[] indexes = new int[numberOfWords];

            if (direction == DOWN_RIGHT) {
                indexes[0] = matrixString.length() - wordLength;
                for (int i = 1; i < numberOfWords; i++) {
                    indexes[i] = indexes[i - 1] - wordLength;
                }

                int wordCount = numberOfWords + wordLength - 1;

                for (int i = 0; i < wordCount; i++) {
                    builder.delete(0, builder.length());
                    for (int j = 0; (j <= i) && (j < numberOfWords); j++) {
                        if (indexes[j] < wordLength * (wordCount - i)) {
                            char c = matrixString.charAt(indexes[j]);
                            builder.append(c);
                            indexes[j]++;
                        }
                    }
                    String s = builder.reverse().toString();
                    list.add(s);
                }
            }

            if (direction == DOWN_LEFT) {
                // Exercise for original poster
            }

            if (direction == UP_RIGHT) {
                // Exercise for original poster
            }

            if (direction == UP_LEFT) {
                // Exercise for original poster
                // Same as DOWN_RIGHT with the reverse() removed
            }
        }

        return list.toArray(new String[list.size()]);
    }

    public static void main(String[] args) {
        String[] grid1 = { "SUGAR", "GLASS", "MOUSE", "STATE", "PUPIL", "TESTS" };
        String[] grid2 = { "SUGAR", "GLASS", "MOUSE" };

        Matrix matrix = new Matrix();
        String[] output = matrix.getMatrixDiagonal(grid1, DOWN_RIGHT);
        System.out.println(createStringLine(grid1));
        System.out.println(createStringLine(output));

        output = matrix.getMatrixDiagonal(grid2, DOWN_RIGHT);
        System.out.println(createStringLine(grid2));
        System.out.println(createStringLine(output));
    }

    private static String createStringLine(String[] values) {
        StringBuilder builder = new StringBuilder();
        builder.append("[ ");

        for (String s : values) {
            builder.append("\"");
            builder.append(s);
            builder.append("\" ");
        }

        builder.append("]");

        return builder.toString();
    }

}
于 2013-06-11T15:45:36.763 に答える
2
    String[] grid = {"SUGAR", 
             "GLASS", 
             "MOUSE"};
    System.out.println("Result: " + Arrays.toString(diagonals(grid)));

public static String[] diagonals(String[] grid) {
    int nrows = grid.length;
    int ncols = grid[0].length();
    int nwords = ncols + nrows - 1;
    String[] words = new String[nwords];
    int iword = 0;
    for (int col = 0; col < ncols; ++col) {
        int n = Math.min(nrows, ncols - col);
        char[] word = new char[n];
        for (int i = 0; i < n; ++i) {
            word[i] = grid[i].charAt(col + i);
        }
        words[iword] = new String(word);
        ++iword;
    }
    for (int row = 1; row < nrows; ++row) {
        int n = Math.min(ncols, nrows - row);
        char[] word = new char[n];
        for (int i = 0; i < n; ++i) {
            word[i] = grid[row + i].charAt(i);
        }
        words[iword] = new String(word);
        ++iword;
    }
    assert iword == nwords;
    return words;
}

Result: [SLU, UAS, GSE, AS, R, GO, M]

最初に、列の最初の要素を持つループ。次に、行0をスキップして、行をループします。両方のループのコードは非常に対称的です。難しいことは何もありません。すべての文字列の長さが同じであると想定されます。

1つのループとして:

public static String[] diagonals(String[] grid) {
    int nrows = grid.length;
    int ncols = grid[0].length();
    int nwords = ncols + nrows - 1;
    String[] words = new String[nwords];

    // Position of first letter in word:
    int row = 0;
    int col = ncols - 1;

    for (int iword = 0; iword < nwords; ++iword) {
        int n = Math.min(nrows - row, ncols - col);
        char[] word = new char[n];
        for (int i = 0; i < n; ++i) {
            word[i] = grid[row + i].charAt(col + i);
        }
        words[iword] = new String(word);

        if (col > 0) {
            --col;
        } else {
            ++row;
        }
    }
    return words;
}

の宣言はword、ループの外に持ち出すことができます。左と上の縁を(列、列)と一緒に歩くだけです。

于 2013-06-11T16:09:16.197 に答える
0

2次元配列を使用して行列を表すことができます。

char[][]行列=char[] []

次に、forループを使用して、ループを繰り返し処理し、必要な出力を抽出できます。アルゴリズムの入力は、必要な対角線方向になります。

例の場合; 考えられる入力の1つはすぐ下です

可能な入力に基づいて、ループの初期条件と終了条件を反復処理する方法を決定する必要があります。

最後の列の最初の行の文字から開始

r = 0、c = coulmn_count -1;

終了条件は、first_column最後の行のインデックスの文字になります。

r = row_count -1、c = 0;

最後の行または最後の列で文字を読み取るときの各反復は、サブループの終了です

于 2012-05-23T04:55:28.043 に答える