1

ファイル内のすべての文字を解析し、各文字の出現回数を見つけるクラスを作成しています。

1 つのステップで、文字を追加するファイルを調べているときに、現在の特定の文字が文字のリストに既に含まれているかどうかを確認します。そうでない場合は、出現値 1 でリストに追加し、既に含まれている場合は、出現値を 1 増やします。

ただし、以下のコードは、リストに特定の文字が既に含まれているかどうかを正しく判断していません。

私は ArrayList を使用していますが、contains() が使用する equals() メソッドを適切に機能させるために、CharProfile クラスの equals メソッドをオーバーライドする必要があることを知っています。

CharProfile の equals メソッドをオーバーライドしました:

    @Override
    public boolean equals(Object o) {
        if (this.character == ((Character)o)) {
            return true;
        }
        else {
            return false;
        }
    }

コード:

import java.util.*;
import java.io.*;

public class HuffmanCoder {
    public static void main(String[] args) throws IOException {
        Scanner keyboard = new Scanner(System.in);

        System.out.print("Please enter the name of the file to be read from: ");
        String fileName = keyboard.nextLine();

        File file = new File(fileName);
        Scanner inputFile = new Scanner(file);

        int charCount = 0;
        ArrayList<CharProfile> charOccurrences = new ArrayList<CharProfile>();

        while (inputFile.hasNext()) {
            // Grabs the next word in the file and converts it into a char array
            String word = inputFile.next();
            char[] wordArray = word.toCharArray();

            // Parses the word on a char-by-char basis
            for (int i = 0; i < wordArray.length; i++) {
                if (wordArray[i] != ' ') {
                    charCount++;

                    // Constructs the list of chars and their respective number of occurrences
                    if (!charOccurrences.contains(wordArray[i])) {
                        charOccurrences.add(new CharProfile(wordArray[i]));
                    }
                    else {
                        for (int j = 0; j < charOccurrences.size(); j++) {
                            if (charOccurrences.get(j).getCharacter() == wordArray[i]) {
                                charOccurrences.get(j).incremementOccurrences();
                                break;
                            }
                        }
                    }
                }
            }
        }

        // Figure out each char's probability
        for (int i = 0; i < charOccurrences.size(); i++) {
            System.out.println(charOccurrences.get(i).getCharacter());
        }
    }   
}

完全な CharProfile クラス:

public class CharProfile {
    private char character;
    private int occurrences;
    private double probability;

    public CharProfile(char character) {
        this.character = character;
        occurrences = 1;
    }

    public void incremementOccurrences() {
        occurrences++;
    }

    public char getCharacter() {
        return character;
    }

    public void setCharacter(char character) {
        this.character = character;
    }

    public int getOccurrences() {
        return occurrences;
    }

    public void setOccurrences(int occurrences) {
        this.occurrences = occurrences;
    }

    public double getProbability() {
        return probability;
    }

    public void setProbability(double probability) {
        this.probability = probability;
    }

    public boolean equals(char character) {
        if (this.character == character) {
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this.character == ((Character)o)) {
            return true;
        }
        else if (this.character == ((Character)o).charValue()) {
            return true;
        }
        else {
            return false;
        }
    }
}

簡単に言えば、リストにその文字が既に含まれているかどうかを確認するときに true を返す代わりに、常に false を返すように見えるため、ファイル内のすべての文字がリストに追加されます。

4

2 に答える 2

1

これは、オブジェクト参照のみが同じであり、インスタンスがCharacternotであることを比較していCharProfileます。

@Override
public boolean equals(Object o) {
    if (this.character == ((Character)o)) {
        return true;
    }
    else {
        return false;
    }
}

次のように、 equals メソッドを変更してインスタンスを受け入れ、そのCharProfile中の文字値を比較する必要があります。

@Override
public boolean equals(Object o) {
    if(this.character == ((CharProfile)o).getCharacter()) {
        return true;
    }else {
        return false;
    }
}

編集:メソッドに char を渡しているため、equal メソッドは呼び出されていませんcontains

それを次のように変更してください:

         // Constructs the list of chars and their respective number of occurrences
         CharProfile charProfile = new CharProfile(wordArray[i]);
         if (!charOccurrences.contains(charProfile)) {
              charOccurrences.add(charProfile);
         }
于 2012-10-28T23:56:28.950 に答える
0

あなたは古典的な間違いを犯しました: と混同==していequals()ます。

Java の場合 (javascript とは異なります):

  • ==2 つのオペランドが同じインスタンスかどうかをテストします
  • equals()デフォルトの動作は と同じですが、実装すると通常は 2 つのオペランドが同じ==かどうかをテストします

すべてを変更する==.equals()、問題は修正されるはずです。


メソッドequals()のコードが多すぎます。まったく同じことを行う次のコードに置き換えることができます。

@Override
public boolean equals(Object o) {
    return this.character.equals(o);
}

しかし、すべての合理的なタイプを処理するには、次のようにします。

@Override
public boolean equals(Object o) {
    if (o instanceof Character) {
        return character.equals(o);
    }
    if (o instanceof CharProfile) {
        return character.equals(((CharProfile)o).character);
    }
    return false;
}


また、オーバーライドするときは、一貫性を保つためにequals()もオーバーライドする必要があります。hashCode()つまり、次のように、比較される値の hashCode を返します。

@Override
public int hashCode() {
    return character.hashCode();
}
于 2012-10-29T00:27:50.620 に答える