2016-08-25 5 views
0

txtファイルから読み込むときにアルファベットの各文字の出現を数えようとしています。これまでのところ、私のコードは文字aを数えます。txtファイルからのアルファベット文字の出現をカウントする

int counter = 0; 
    try (BufferedReader reader = new BufferedReader(new FileReader(file))) { 
     int ch; 
     for (char a : "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()) { 

      char toSearch = a; 
      counter = 0; 
      while ((ch = reader.read()) != -1) { 
       if (a == Character.toUpperCase((char) ch)) { 
        counter++; 
       } 
      } 
      System.out.println(toSearch + " occurs " + counter); 

     } 

すべての文字がカウントされるようにするにはどうすればよいですか? }

+1

「簡単」/「便利」な方法は、アルファベットのすべての文字のためのキーでハッシュマップを作成し、その同じハッシュマップの値としてカウンタを格納することができます。 – fvu

+0

2次元アレイ/リストは多分できますか?私はC#であれば 'List 'に行きますが、意味があることを祈っています:) – uTeisT

+0

[Java:String内のcharの出現回数はどのように数えますか?] http://stackoverflow.com/questions/275944/java-how-do-i-count-the-number-of-occurrences-of-a-char-in-a-string) – xenteros

答えて

1

のカウントとなります。 reader.read()を呼び出すたびに次の文字に移動するので、ループが終了するとファイルの最後まで読み込まれます。 forループの最後に、バッファされたリーダーをリセットして、ファイルの先頭を再度指すようにする必要があります。 これを行うには、新しいバッファ付きの読者オブジェクトを作成する必要があります。その場合は、コードが機能するforループの後に行BufferedReader reader = new BufferedReader(new FileReader(file))を移動するだけです。

public class Test { 
public static void main(String [] args) { 

    File file = new File("test.txt"); 
    int counter = 0; 
    try { 

     int ch; 
     for (char a : "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()) { 
      BufferedReader reader = new BufferedReader(new FileReader(file)); 
      char toSearch = a; 
      counter = 0; 

      while ((ch = reader.read()) != -1) { 
       if (a == Character.toUpperCase((char) ch)) { 
        counter++; 
       } 
      } 
      System.out.println(toSearch + " occurs " + counter); 

     } 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 

}

1

ブルートフォースロジック:

  • ファイル。 readAllLines() /ループ= FileReader + BufferedReader 行をファイルから読み取る。

  • 読み込んだ行ごとに、小文字に変換します(AとAを別々にカウントすることはありません)。char配列を取得します。 マップを作成する

  • char配列と各charに対して、マップ内に既に が存在するかどうかを確認します。それが存在しない場合は、キーが存在する場合は、値を取得 値1でマップに追加し、それに1を追加し、バック

3

を 値を入れて、あなたが持っている問題は、あなたがしていることですファイル全体を読むと最初の文字が比較され、2番目の文字に来るまでにファイルが残っていません。

ネストされたループを使用する代わりに、値の配列の各要素を1文字ずつインクリメントできます。例えばこの場合

int[] letterCount = new int[27]; 
for (int ch; (ch = reader.read()) != -1;) { 
    if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) 
     letterCount[ch % 32]++; // update the counter for the letter. 
} 

letterCount[1]aまたはAletterCount[2]のカウントになりますあなたの問題は、バッファリーダーであるbまたはB

+1

それは私を驚かせることは決してありません多くの注文と手配のテクニックは、ASCIIテーブルで共通の操作を簡略化するために行われました... – fvu

+0

残念なことに、このようなソリューションを使用すると、一見するとどれほどエレガントに見えるかもしれませんが、国際化について考えてみてください。 (OK、OPの質問にも同じ問題がありますが、彼は定義配列を更新するだけです。)つまり、それは2016年にASCIIテーブルで数字のトリッキーに頼っている人がまだいることを私に驚かせることは決してありません。 – mtj

+0

@mtjあなたは 'Character.toUpperCase'と' int [65536] 'を使うことができますコードポイントの場合はそれ以上です。劇的な変化ではありません。 OPが 'a 'のような文字を' a'にマップするかどうかは明らかではありません。 toUpperCaseでさえ、2つの文字を取得できるので問題があります。 –

関連する問題