1

私は、文字列に関する非常に一般的な Java の問題の解決に取り組んでいます。文字列が別の順列 (アナグラム) であるかどうかを確認するメソッドを書きたいと思います。

私の解決策は次のとおりです。2 つの文字列を受け取るメソッドを作成しています。1 つの String を繰り返し処理し、見つかった文字を HashMap に入れます。キーは文字で、値はその文字の出現回数 (int) です。最初の String の反復処理が終了したら、2 番目の String を反復処理し、同じ HashMap で見つかった各文字の値を減らします。

キーがゼロになると、キーと値のペアを HashMap から完全に削除します。2 番目の String の反復処理が終了したら、HashMap が空かどうかを確認するだけです。そうである場合、2 つの文字列は互いの順列/アナグラムであり、そうでない場合、メソッドは false を返します。

私の方法は次のとおりです。

public boolean checkPermutation (String stringA, String stringB) {

        if (stringA.length() != stringB.length()) {

            return false;

        }

        else {


        HashMap alpha = new HashMap();

        for (int i = 0; i < stringA.length(); i++) {

            if (!alpha.containsKey(stringA.charAt(i))) {

                alpha.put(stringA.charAt(i), 0);
            }

            else {

                Integer value = (Integer) alpha.get(stringA.charAt(i));
                int newValue = value.intValue();
                alpha.put(stringA.charAt(i), newValue++);

            }

        }

        for (int j = 0; j < stringB.length(); j++) {

            if (alpha.containsKey(stringB.charAt(j))) {

                Integer value = (Integer) alpha.get(stringA.charAt(j));
                int newValue = value.intValue();//null pointer exception here

                if (newValue > 1) {

                    alpha.put(stringB.charAt(j), newValue--);

                }

                else {

                    alpha.remove(stringB.charAt(j));

                }

            }

        }

        if (alpha.isEmpty())
            return true;

        else
            return false;


        }
    }

私の問題は、私のソリューションでは大文字と小文字が区別されることです (つまり、"Hello" と "oellH" を入力すると、null ポインター例外が発生します)。このソリューションで大文字と小文字を区別しないようにして、Null-Pointer Exception が発生する理由を突き止めたいと思います。誰かが私が間違っていることを見ることができますか?

ちょっとしたフォローアップの質問として、2 つの for ループがあるにもかかわらず、そのようなタイプ O(n) のソリューションはありますか?

4

2 に答える 2

1

ハッシュマップで stringB の char をチェックしてから stringA の値を抽出しているため、null ポインター例外がスローされます。これは、null ポインター エラーがスローされた時点で、その特定の値がハッシュマップから削除される可能性があるためです。

コードを慎重にデバッグする場合

if (alpha.containsKey(stringB.charAt(j))) {
    Integer value = (Integer) alpha.get(stringA.charAt(j));
 ///Your code
}

に変更します

if (alpha.containsKey(stringB.charAt(j))) {
    Integer value = (Integer) alpha.get(stringB.charAt(j));
///Your code
}

他の質問で大文字と小文字を区別しないようにするには、操作を開始する前に文字列を小文字または大文字にします

stringA = stringA.toLowerCase();
stringB = stringB.toLowerCase();
于 2013-02-18T05:24:01.097 に答える
1
Integer value = (Integer) alpha.get(stringA.charAt(j));

stringA を stringB に変更してみてください。

Integer value = (Integer) alpha.get(stringB.charAt(j));

同じ文字が含まれていない別の文字列を指定すると、値はnullになり、NPEを介して行われるためです。

両方の文字列を小文字または大文字に変更します。

stringA= stringA.toLowercase();
stringB= stringB.toLowercase();
于 2013-02-18T05:09:45.160 に答える