1

単一の長い行を含む US-ASCII のテキスト ファイルがあります。アクセスする必要があるテキスト項目は、次のようにさまざまな数のスペースで区切られています。

metadata1 attrib1     metadata2 attrib2   attrib2a trackstart attrib1   attrib2   trackstart attrib1 atrib2 attrib3

ファイルには最大 99 個の「トラック」エントリを含めることができ、ほとんどメモリを消費しません。

私は何をする必要がありますか

これらのエントリを、反復処理、値へのアクセス、アイテムのカウントが可能なメモリ内構造に抽出する必要があります。たとえば、「トラック」の数を取得する必要があります (上記の例では「トラック開始」をカウントし、各トラックの属性をobject.track1.attribute1.

私が試したこと

スキャナーを使用してファイルを読み取り、テキスト エントリをステップ実行しました。これはうまくいくようです。次に、ネストされた HashMaps を次のように作成しました。

HashMap<String, String> overallMap = new HashMap<String, String>(); // contains the tracks map and some other metadata
HashMap<String, Map> tracks = new HashMap<String, Map>();  // contains a map of all tracks
HashMap<String, String> track = new HashMap<String, String>(); // contains an individual track

しかし、問題は (私が思うに) HashMaps ではキーをカウントできないことです (つまり、テキスト ファイル内の「トラック」の数を取得できません)。このデータ構造で他の問題に遭遇すると思います。

質問

  1. この場合、スキャナはファイルを読み込んで操作するための最良の方法ですか?
  2. どのメモリ内データ構造を選択すればよいですか? トラック リストを作成し、トラックを数え、この構造内の個々の属性にアクセスするにはどうすればよいですか?
4

2 に答える 2

0

Java は OO 言語であるため、データ構造だけに依存するのではなく、独自のオブジェクトを作成する必要があります。これにより、書き込み、読み取り、および保守がすべて簡単になります。

したがって、または属性Trackを含むクラスが必要です。選択は、属性の順序を気にするかどうか、および重複を削除する必要があるかどうかによって異なります。ListSet

Track クラスでは、属性を追加および取得できるようにする必要があります。これは、実行する必要があるためです。また、最初のトラックの前の行の他の情報ではなく、トラックのみに関心があるように見えるので、すべてのトラックを保持するためにトラックのリストが必要です。

したがって、アルゴリズムは非常に単純なはずです。

  • 行をトークンに分割する
  • 空を作るList<Track>
  • トークンを繰り返す
    • 現在のトークンが の場合trackstart、新しい を作成し、Trackこの新しいTrackインスタンスを変数 に割り当てますcurrentTrack。このトラックをトラックのリストに追加
    • 現在のトークンがそれ以外の場合、
      • いずれかcurrentTrackが null であり、トークンを無視する必要があります
      • またはcurrentTracknull でない場合、呼び出して現在のトラックの属性としてトークンを追加する必要があります。currentTrack.addAttribute(token)

アルゴリズムの最後にはList<Track>、ライン内のトラックと同じ順序で、完全な Track インスタンスがあります。また、各 Track インスタンスにはList<String>、トラックの属性を含む があります。

于 2013-10-27T13:22:02.553 に答える
0

いくつかのメタデータ オブジェクトといくつかのトラックがあり、それぞれが可変数の属性を持つため、それぞれを表す「MyObjects」という名前の基本クラスを作成できます。

public class MyObject implements java.io.Serializable
{
    String name;
    ArrayList attributes;
    public MyObject(String name)
    {
       this.name = name;
    }
    public void addAttribute(String attr)
    {
        this.attributes.add(attr);
    }
}

次に、読み取った各ファイルを表すクラス MyFile を用意します。

public class MyFile
{
    MyObject[] metadata;
    MyObject[] track;

    public int check(String s)
    {
        if(s.substring(0,s.length()-1).equals("metadata")) return 0;
        if(s.equals("trackstart")) return 1;
        return 2;
    }
}

次に、メイン関数でファイルを読み取ることができます

File f = new File(filepath); 
BufferedReader br = new InputStreamReader(f.getInputStream());
String line = "",content = "";
while((line = br.readLine())!=null) content += line;

MyFile myfile = new MyFile();
StringTokenizer t = new StringTokenizer(content," ");
int status;
String word = "";
while(t.hasMoreTokens())
{
    word = t.nextToken();
    status = myfile.check(word);

    // add the attributes to the to metadata or tracks

 }
于 2013-10-27T13:30:34.010 に答える