1

私は C プログラマーで、現在は Java に移行しています。CプログラムをJavaプログラムに変換しようとしています。C プログラムは、単純に用語頻度と逆文書頻度 ( tf/idf ) を計算します。

1 つのデータ クラスを作成しました

public class Data {
    private String fileName,fileText;
    private int fileId;
    private float value;

    public void addData(String fileName, String fileText, float value){
        this.fileName = fileName;
        this.fileText = fileText;
        this.value = value;
    }

    public int getFileId(){
        return this.fileId;
    }


    public String getFileName(){
        return this.fileName;
    }

    public String getFileText(){
        return this.fileText;
    }

    public float getValue(){
        return this.value;
    }
}

このクラスは、ファイル名、ファイル テキスト、および値 (tf 値または idf 値) を格納します。

次のクラスは、データを格納する責任があります。

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

        HashMap<String, Data> map = new HashMap<String, Data>();
        Data dt = new Data();

        dt.addData("abc.txt", "some contents", 2);
        map.put("1",dt);
        dt.addData("w", "some more contents in second file", 3);
        map.put("2",dt);

        System.out.println(map);

    }

}

マップを印刷すると、奇妙な値が表示されます。私は、データクラスの配列を宣言する必要があると思いますか? ファイルの数がわからないため、静的配列番号を入れることはできません。

また、このデータ構造に基づいて TF と IDF を計算するにはどうすればよいですか?

C プログラムでは、単純にファイルを読み取り、単語を合計単語数で割って TF を取得し、単語をすべてのファイル内のその単語の合計出現回数で割って IDF を取得します。上記のデータ構造を使用してそれを行う方法がわかりません。

私は奇妙な値を取得します。多分これらはオブジェクトです:

{2=test2.Data@19821f, 1=test2.Data@19821f}

getFileNameetc. 関数を使用して Data クラスから特定の値を取得する方法はありますか?

4

4 に答える 4

1

質問1の場合、オーバーライドしない限りtoString()、オブジェクトを直接stdoutに出力するだけでは、意味のある出力が得られない可能性があります。'test2.Data@19821f'は、Object.toString()クラス名の後にオブジェクトハッシュが続くことを返します。この場合、両方の値が同じオブジェクトであることを非常に役立ちます。

java.io.Fileおよびを使用してファイルを開いたり読み取ったりできますjava.io.FileInputStream。文字列から整数へのマップは、java.util.Map<String,Integer>おそらくそれらのファイル内の単語を数えるのに役立ちます。

この単純なアプリケーションでは、データクラスはそれほど必要ではないようです。従うべきアルゴリズムについてはすでに説明しましたが、これはJava構文で記述した場合にすぎません。

型安全性の素晴らしい世界へようこそ。メモリリークを心配する必要はありません。

于 2010-12-23T22:18:56.267 に答える
0

ほとんどの場合、データ文字列表現が表示されることを期待しています。

任意のオブジェクト ( map を含む) に対して println を呼び出すと、システムはObject.toString()を呼び出します。

マップの場合、toString メソッドはマップのコンテンツを次のような形式で返します。

{ key = value, key2, value2 }

つまり、キーと値のペアを出力します。

現在、キーと値もオブジェクトであるため、独自のtoString()メソッドが呼び出されます。文字列の場合、値はそれ自体です。ただし、の場合、Data独自の実装を提供していないため、デフォルトのものが得られます。これ object fully qualified name @ object.hashCode() はおそらく次のようなものになります。

 { 1 = Data@0xa6f2be, 2 = Data@0xa6f2be }

これを変更するには、toString()メソッドをオーバーライドする必要があります。

 class Data { 
  ... etc. etc. 
     public String toString() { 
       // return something meaningful like:
       return String.format( "Data( fileName = %s, fileText = %s, etc ", this.fileName, this.fileText );
     }
  }

2 番目の質問については、基本的に C で行う場合と同じ方法で行います。おそらく、ファイルを開き、カウントを開始するcalculate()メソッドを作成する必要があります。おそらく、これは独自の質問に値します。

于 2010-12-23T22:32:16.353 に答える
0

のインスタンスを 1 つだけ作成していますData。おそらく、次のようなことをしたいと思うでしょう:

    Data dt = new Data();
    dt.addData("abc.txt", "some contents", 2);
    map.put("1",dt);

    dt = new Data();
    dt.addData("w", "some more contents in second file", 3);
    map.put("2",dt);

またはさらに良いDataことに、コンストラクターでプロパティを取得するように変更します。

    map.put("1", new Data("abc.txt", "some contents", 2));
    map.put("2", new Data("w", "some more contents in second file", 3));
于 2010-12-23T22:25:23.893 に答える
0

あなたの質問が何であるかは明確ではありませんが (質問の下のコメントを参照してください)、コードにいくつか問題があります。オブジェクト内のデータを置き換えるaddDataメソッドの紛らわしい名前です。しかし、本当の問題はここにあります:

  dt.addData("abc.txt", "some contents", 2);
  map.put("1",dt);
  dt.addData("w", "some more contents in second file", 3);
  map.put("2",dt);

これにより、2 つのエントリを含むマップが作成されます。どちらも同じ Dataオブジェクトを参照しており、最後の呼び出しからの値が含まれますaddData。コンストラクターに変更addDataします。

public Data(String fileName, String fileText, float value) {

次に、マップ コードを次のように変更します。

map.put("1", new Data("abc.txt", "some contents", 2));
map.put("2", new Data("w", "some more contents in second file", 3));
于 2010-12-23T22:26:15.307 に答える