1

以下のコードでは、アイテムがファイルに表示される回数を数えようとしています。ただし、キーとその値を印刷すると、実際の数より1つ多い数になります。0に初期化totalすると問題は解決しますが、理由はわかりません。

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;

public class Problem {
   public static void main(String[] arg) {
      HashSet QID = new HashSet();
      HashMap QIDToCorrect = new HashMap();
      try {
         // Open the file that is the first command line parameter
         FileInputStream fstream = new FileInputStream(
               "C:/Users/lol/Downloads/data.csv");

         // Get the object of DataInputStream
         DataInputStream in = new DataInputStream(fstream);
         BufferedReader br = new BufferedReader(new InputStreamReader(in));

         //Read File Line By Line
         String strLine;
         br.readLine(); //skip header line
         int total = 0;
         int blah = 0;
         while ((strLine = br.readLine()) != null) {

            String[] split = strLine.split(",");

            if (!QID.contains(split[0])) {
               total = 1;
               QID.add(split[0]);
               QIDToCorrect.put(split[0], total);
            } else {
               total += 1;
               QIDToCorrect.put(split[0], total);
            }

            //System.out.println();
         }
      } catch (Exception e) {
      }
   }
}
4

3 に答える 3

0

あなたのアルゴリズムは奇妙に見えますが、あなたがやろうとしていることを正しく理解していれば、私は置き換えます

if (!QID.contains(split[0])) {
               total = 1;
               QID.add(split[0]);
               QIDToCorrect.put(split[0], total);
            } else {
               total += 1;
               QIDToCorrect.put(split[0], total);
            }

Integer lasttotal = (Integer)QIDToCorrect.get(split[0]);
total = 1 + lasttotal!=null ? lasttotal : 0;
QID.add(split[0]);
QIDToCorrect.put(split[0], total);

そうすれば、アイテムがソートされていなくても、totalはアイテムを正しくカウントします...しかし、それはあなたの問題を説明するものではありません。値を正しく印刷してもよろしいですか?ステップバイステップのデバッグを試しましたか?

于 2013-01-18T23:23:51.943 に答える
0

キーを更新する前に、キーの値を取得する必要があります...以下を参照してください。

if (!QID.contains(split[0])) {
   total = 1;
   QID.add(split[0]);
   QIDToCorrect.put(split[0], total);
} else {
   total = QIDToCorrect.get(split[0]);  // RETRIEVE VALUE FOR KEY
   total += 1;
   QIDToCorrect.put(split[0], total);
}
于 2013-01-19T00:34:28.050 に答える
0

各行の最初の要素が次のように入力されたとします。

foo
foo
bar
foo

次に、この入力でループが何をするかを考えてみましょう

while((strLine = br.readLine())!= null){

        String[] split = strLine.split(",");

split[0]最初の「foo」です。

        if (!QID.contains(split[0])) {

「foo」はまだ追加されていません

           total = 1;
           QID.add(split[0]);
           QIDToCorrect.put(split[0], total);

totalに設定すると1、「foo」が追加されQID、(「foo」、1)が追加されますQIDToCorrect

        String[] split = strLine.split(",");

split[0]2番目の「foo」です

        if (!QID.contains(split[0])) {

falseと評価されるため、ifステートメントはに分類されelseます。

        } else {
           total += 1;
           QIDToCorrect.put(split[0], total);
        }

total2にインクリメントQIDToCorrectされ、( "foo"、2)に更新されます。

        String[] split = strLine.split(",");

split[0]「バー」が含まれるようになりました。

        if (!QID.contains(split[0])) {
           total = 1;
           QID.add(split[0]);
           QIDToCorrect.put(split[0], total);

QIDバーが含まれていないため、total1にリセットされ、「bar」がに追加されQID、(「bar」、1)がに挿入されQIDToCorrectます。

        String[] split = strLine.split(",");

3番目の「foo」split[0]が含まれるようになりました

        if (!QID.contains(split[0])) {

「foo」は以前に見られたので、に落ちてelseください。

        } else {
           total += 1;
           QIDToCorrect.put(split[0], total);
        }

total2にインクリメントQIDToCorrectされ、( "foo"、2)で更新されます。

したがって、カウンターを保持するマップは、 2つ しかなかったと考えていますfoo。ここに問題があります。total新しいアイテムが表示されるたびに、カウンターがリセットされます。したがって、電話をかけるときQIDToCorrect.put()は、過去にそのアイテムを見た回数を考慮しないでください。QIDToCorrect.get()アイテムの以前のカウントを取得するには、おそらくを使用する必要があります。これにより、変数が不要になりtotalます(表示したすべてのアイテムの総数を知りたい場合を除く)。また、 HashSetにはすでにキーが含まれているかどうかQIDを照会できるため、HashSetは不要です。QIDToCorrect

于 2013-01-19T00:52:29.017 に答える