-1

解析する必要があるファイルがあります。問題は一見単純ですが、私は前進していません。問題は次のとおりです。ファイルには、20 ~ 22 行のチャンクにデータが含まれており、その後に不明な数の空白行が続き、さらに 20 ~ 22 行のチャンクが続きます。これらのデータのチャックのデータ構造を作成する必要があります。私は次のことを試しました

File f1 = new File(PATH_TO_TRAINING_FILE);
FileInputStream fis1 = new FileInputStream(f1);
readerTrainingFile = new BufferedReader(new InputStreamReader(fis1));
String trainLine;
while (( trainLine =readerTrainingFile.readLine()) != null) {
    ArrayList<String> train = new ArrayList<String>();
    while (!trainLine.trim().equals("")) {
        train.add(trainLine);
        trainLine =readerTrainingFile.readLine();
    }
    while (readerTrainingFile.readLine().trim().equals("")) {
    }
}

したがって、上記のコードの問題は、3 番目の while ループで、空白行のチェックが終了すると、読み取り行のポインターが次のチャンクの最初のスペース以外の行に移動することです。したがって、コントロールが最初の while ループに到達すると、必要なデータを 2 行スキップします。質問が本当に簡単でしたら、本当に申し訳ありません。私は今2日間立ち往生しています。助けてくれてありがとう。

4

5 に答える 5

2

これをリファクタリングして、この行readerTrainingFile.readLine()がプログラムで 1 回だけ表示されるようにします。ネストされた while ループは、人生を悲惨なものにする素晴らしい方法です。continue行をスキップする必要がある場合は、ステートメントを使用します。デバッグのために、System.out.println(trainLine)何を読んでいるのか、毎回スキップする可能性があるのか​​ を確認します。これらの手順で問題が解決するはずです。

于 2012-12-04T23:06:06.027 に答える
1

このようなことを検討してください

List<List<String>> trains = new ArrayList<List<String>>();
List<String> curTrain = null;
while (( trainLine=readerTrainingFile.readLine()) != null) {
    if (!trainLine.trim().equals(""))
        curTrain = null;
    else 
    {
        if (curTrain == null)
        {
            curTrain = new ArrayList<String>();
            trains.add(curTrain);
        }
        curTrain.add(trainLine)
    }
}

trainsすべてのチャンクを含むリストです。データを読み込みながら、curTrain現在行が追加されているチャンクを参照します。空白でない行を取得するたびに、それを現在のチャンクに追加しますが、現在のチャンクがない場合 (先頭にいる、または以前の 1 つ以上の行が空白だったため)、新しいチャンクを作成し、チャンクのリストに追加します。

于 2012-12-04T23:20:24.457 に答える
0
Scanner scanner = new Scanner(f1);
ArrayList<String> train = new ArrayList<String>();
while(scanner.hasNextLine()){
    String temp = scanner.nextLine();
    if(!temp.trim().equals(""))
        train.add(temp);
}

scanner.hasNextLine をバッファリングされたリーダーと同等のものに置き換えることができます

(temp = reader.nextLine()) != null

しかし、スキャナーは少し使いやすく、理解できます。最初の while ループ内から文字列を追加しているため、arraylist はローカルであり、ループの終了後は保持されません (reader.nextLine() == null)。

同じ型で != と !.equals() を使用していることに注意してください。これは文字列の場合は問題ありませんが、通常、.equals はオブジェクト用で、== はプリミティブ用です (Java はオブジェクトとプリミティブの間のどこかで文字列を扱います)。

于 2012-12-04T23:24:32.867 に答える
0
while (( trainLine =readerTrainingFile.readLine()) != null) {
            ArrayList<String> train = new ArrayList<String>();
            while (!trainLine.trim().equals("")) {
                train.add(trainLine);
                trainLine =readerTrainingFile.readLine();
            }
            while (readerTrainingFile.readLine().trim().equals("")) {

            }
 }

それはあなたの問題だ。行を 2 回読みます。このコードを最初のwhileループに入れるだけです。

if (trainLine.trim().equals("")) {
    train.add(trainLine);
}

また、別の問題:これを移動します:

ArrayList<String> train = new ArrayList<String>();

ループ外。そうしないと、行を読み取るたびに新しい行が作成されます。

于 2012-12-04T23:08:22.683 に答える
0

これらの「チャンク」が何を表しているのかはわかりませんが、文字列のリストよりも優れた抽象化を想像することから始めます。

これに対処する方法の 1 つを次に示します。

package cruft;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * FileChunkParser description here
 * @author Michael
 * @link
 * @since 12/4/12 6:06 PM
 */
public class FileChunkParser {

    public static void main(String[] args) {
        try {
            File f = new File((args.length > 0) ? args[0] : "resources/chunk.txt");
            Reader reader = new FileReader(f);
            FileChunkParser parser = new FileChunkParser();
            Map<Integer, List<String>> chunks = parser.parse(reader);
            for (int index : chunks.keySet()) {
                System.out.println(String.format("index: %d chunk: %s", index, chunks.get(index)));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Map<Integer, List<String>> parse(Reader reader) throws IOException {
        Map<Integer, List<String>> chunks = new TreeMap<Integer, List<String>>();
        BufferedReader br = null;
        try {
            if (reader != null) {
                br = new BufferedReader(reader);
                int chunkCount = 0;
                String line = "";
                List<String> chunk = null;
                while ((line = br.readLine()) != null) {
                    if (StringUtils.isBlank(line)) {
                        if (chunk != null) {
                            chunks.put(chunkCount++, new LinkedList<String>(chunk));
                            chunk = null;
                        }
                        continue;
                    } else {
                        if (chunk == null) {
                            chunk = new LinkedList<String>();
                        }
                        chunk.add(line);
                    }
                }
                if (chunk != null) {
                    chunks.put(chunkCount++, chunk);
                }
            }
        } finally {
            IOUtils.closeQuietly(reader);
        }
        return chunks;
    }
}

この入力ファイルで実行しました:

this
is
how
you
do
it



see
how
it
handles
arbitrary
sized
chunks
with
any
blank
lines
between

try
it
and
see

出力は次のとおりです。

index: 0 chunk: [this, is, how, you, do, it]
index: 1 chunk: [see, how, it, handles, arbitrary, sized, chunks, with, any, blank, lines, between]
index: 2 chunk: [try, it, and, see]
于 2012-12-04T23:26:38.253 に答える