1

まず、タイトルが非常に説明的で申し訳ありませんが、正直なところ、私の問題を 1 つの文で説明する方法を思いつきませんでした。私がやっていることを説明するには:モノラルアルファベット暗号化のキーを最初に持つアルファベットを作成しています。正常に機能する重複を削除する方法を作成しました。私はこの割り当てのために少し余分な時間を持っているので、遊んでいます。重複を含まないセットを発見しました。

したがって、 Set を文字列に戻すと、次の文字列が得られます

[s、e、c、u、r.....x、y、z]

文字列には、必要のないこれらすべての文字が含まれています。そのため、私が書いた方法を使用して、文字以外のものをすべて削除します。初めて呼び出すと、

セキュリ....xyz

楽しみのために、メソッドをもう一度呼び出します。私は今残っています

セキュア....xyz

したがって、メソッドが最初にコンマと角かっこを削除することに成功し、スペースを削除せずに2回目の呼び出しでスペースを削除する理由を誰かが教えてくれれば、それは素晴らしいことです. 参考までに、私のコード

public static String createMonoAlphabet(String key){
    String crypticAlphabet = key;       
    crypticAlphabet = crypticAlphabet.concat("abcdefghijklmnopqrstuvwxyz");
    //crypticAlphabet = removeDuplicates(crypticAlphabet);
    Set alphabet = new LinkedHashSet();
    for(int i = 0; i<crypticAlphabet.length(); i++){
        alphabet.add(crypticAlphabet.charAt(i));
    }

    crypticAlphabet = alphabet.toString();
    crypticAlphabet = parseInput(crypticAlphabet);
    crypticAlphabet = parseInput(crypticAlphabet);
    return crypticAlphabet;
}        

セットを使った方法です。注意として、私はここで遊んでいる前にそれらを使用したことがないので、それが悪い習慣か何かである場合は問題ありません. お気軽にお知らせください。でも、今はそれほど気にしていません。次に、非文字を削除する方法について説明します。

    public static String parseInput(String input){
    StringBuffer buf = new StringBuffer(input);

    for(int i = 0; i < buf.length(); i++){
        char c = buf.charAt(i);
        if(!(((int)c >= 65 && (int)c <= 90) || 
                ((int)c >= 97 && (int)c <= 122))){
            System.out.print(buf.charAt(i));
            buf =  buf.deleteCharAt(i);
        }   
    }
    System.out.print(".");
    System.out.println();
    input = buf.toString();
    return input;
}
4

4 に答える 4

2

parseInputコードに関するいくつかのコメント:

  • StringBuffer を反復処理し、同時に変更します ( を呼び出しdeleteCharAt(i)ます)。この種のことを行うことは、しばしば悪い考えです。

  • Java では、char を ASCII 値にキャストするような低レベルの操作を行うべきではありません (C コードのように見えます)。

私の意見では、問題を解決する最善の方法は、正規表現を使用することです。私はそのようなものを書いたでしょう:

public static String parseInput(String input) {
    return input.replaceAll("[^a-zA-Z]+","");
}

これは、文字ではないすべてのものを空の文字列に置き換えることを意味します。SOへようこそ!

于 2012-09-26T07:05:02.350 に答える
1

alphabet.toString()呼び出しは、不要なすべての文字を追加します。セットの文字列表現は常に次のとおりです。

[item1、item2、item3、...]

セットを再度文字列に変換するには、セットを繰り返し処理し、StringBuilderを使用して文字列を作成します。

StringBuilder builder = new StringBuilder();
for(String s: alphabet) { builder.append(s); }
crypticAlphabet = builder.toString();
于 2012-09-26T06:41:51.470 に答える
0

parseInputメソッド内の for ループの順序を逆にする必要があります。adeleteCharAtを実行すると、特定の文字を見逃すことを意味する左シフトを引き起こします。順序を逆にすると、これが修正されます。

for ループに対して次のことを試してください。

for (int i = buf.length() - 1; i >= 0; i--)

于 2012-09-26T06:38:18.323 に答える
0

あなたの実際の問題を解決するために、私はあなたのparseInput方法をより簡単な解決策に変更しました:

public static String parseInput(String input) {
    char[] chars = input.toCharArray();
    StringBuilder sb = new StringBuilder();
    for(int i = 0; i < chars.length; i++) {
        if ((chars[i] >= 65 && chars[i] <= 90) ||
            (chars[i] >= 97 && chars[i] <= 122)) {
            sb.append(chars[i]);
        }
    }
    return sb.toString();
}

後期のコードに問題がありました。インデックスを使用して配列から要素を削除してから次のインデックスに移動するのは良くありません。[s, e]これは、文字列(空白を含む) を使用したサンプルになります。

最初は、次の配列 (短い形式) が得られます。

0 1 2 3 4 5
[ s ,   e ]

インデックスは 0 です。[文字ではない a が見つかったため、実際の配列を持って削除されます

0 1 2 3 4
s ,   e ]

要素が配列内の 1 つの位置に戻ったことを確認しますが、インデックスは 1 ずつロールアップされるため、インデックスは 1 であり、見つかりました,( s! ではありません)。その場合の出力は次のようになります。

0 1 2 3
s   e ]

これで、インデックスは 2 になります。空白が 1 位置戻って 1 になったことを確認します。これが、アルゴリズムが失敗する理由です。

補足として、次のアドバイスを考慮する必要があります。

  • コレクションを使用する場合は、コンテナーのクラスを定義します。この場合、 と を使用Set<Character>LinkedHashSet<Character>ます。
  • StringBuilderの代わりに使用しStringBufferます。詳しくはこちら
于 2012-09-26T06:39:50.187 に答える