1

次のデータを含むtxtファイルがあります

(0010,0010) : Patient's Name                : LANE^LOIS^^^

(0010,0020) : Patient ID                    : AM-0053

(0010,0030) : Patient's Birth Date          : 4/15/1982

(0010,0040) : Patient's Sex                 : F

コンテンツを 1 行ずつ読み、 患者の名前、患者 ID、患者の生年月日、患者の性別の詳細を含むデータ テーブルを作成する必要があります。定数 (例: (0010,0010) ) は変更されません。患者の名前を表します。タスクの背後にあるロジックを教えてください。こんなに持ってるのに、

行単位で読む

最初の 11 文字を取得し、(0010,0010) かどうかを確認します

行末に移動するか、行を分割し:て配列の 2 番目の要素を取得します。

私はよく考えていますか?または、どうすればパフォーマンスを向上させることができますか?

4

5 に答える 5

2

あなたのアプローチは賢明に聞こえます。「:」で区切るのは合理的な考えのように見えます。

この種の文字列処理は非常に高速であり、結果のデータ レコードをディスクやデータベースに書き込むよりもはるかに高速であるため、効率はおそらく問題になりません。

于 2011-11-02T14:00:40.807 に答える
2

問題があることがわかるまではパフォーマンスについて心配する必要はありませんが、一般に、過剰なメモリ割り当てを回避できれば、それは有利になります。したがって、最後の部分だけが必要な場合は、StartsWith()on string を使用して、後でガベージ コレクションされる部分文字列を作成する必要がないようにし、 を使用LastIndexOf()して最後の部分の開始を見つけ、残りを部分文字列にすることができます。

while((line = Console.ReadLine()) != null)
{
    if (line.StartsWith("0010,0010"))
    {
        var pos = line.LastIndexOf(':');

        if (pos != -1)
        {
            // do whatever with part
            var part = line.SubString(pos+1).Trim();
        }    
    }
}
于 2011-11-02T14:02:59.520 に答える
1

この小さな方法でほとんどの問題が解決するはずです。:) 行をループします (ループを調整して、テキストリーダーに置き換える必要があります)。

すべてを患者のリストに入れます。

void Main()
{
    var input = @"(0010,0010) : Patient's Name                : LANE^LOIS^^^
    (0010,0020) : Patient ID                    : AM-0053
    (0010,0030) : Patient's Birth Date          : 4/15/1982
    (0010,0040) : Patient's Sex                 : F
    (0010,0010) : Patient's Name                : LANE^LOIS^^^
    (0010,0020) : Patient ID                    : AM-0053
    (0010,0030) : Patient's Birth Date          : 4/15/1982
    (0010,0040) : Patient's Sex                 : F
    (0010,0010) : Patient's Name                : LANE^LOIS^^^
    (0010,0020) : Patient ID                    : AM-0053
    (0010,0030) : Patient's Birth Date          : 4/15/1982
    (0010,0040) : Patient's Sex                 : F";
    List<Patient> patients = new List<Patient>();

    Patient p = null;
    foreach(var line in input.Split(new[] {'\n'}))
    {
        var value = line.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries).Last().Trim();
        if(line.Trim().StartsWith("(0010,0010)"))
        {
            if(p != null)
                patients.Add(p);
            p = new Patient();
            p.Name = value;
        }
        else if(line.Trim().StartsWith("(0010,0020)"))
        {
            p.ID = value;
        }
        else if(line.Trim().StartsWith("(0010,0030)"))
        {
            DateTime birthDate;
            if(DateTime.TryParse(value, out birthDate))
                p.BirthDate = birthDate;
        }
        else if(line.Trim().StartsWith("(0010,0040)"))
        {
            p.Sex = value.ToCharArray()[0]; 
        }
    }
    if(p != null)
        patients.Add(p);
}

public class Patient
{
    public string Name { get; set; }
    public string ID { get; set; }
    public DateTime? BirthDate { get; set; }
    public char Sex { get; set; }
}
于 2011-11-02T14:23:53.213 に答える
1

行に (0010,0010) または (4 桁の後に , と別の 4 桁) が含まれている場合は、分割する前でも行を確認できます。検出された場合は、文字列の配列に分割し、スペースを削除して、テーブルの行に入力できます。次の式を使用して (0010,0010) を見つけることができます

Regex.IsMatch("line string here...", "[(]{1}[0-9]{4},{1}[0-9]{4}[)]{1}") // should be true if found
于 2011-11-02T14:02:42.817 に答える
1

それは合理的なアプローチのように思えます。問題が発生するまで、パフォーマンスについて心配することはありません。

議論のために、これらが 100,000 個あると仮定しましょう。最初に動作するコードを書き、aSystem.Diagnostics.Stopwatchを使用して 100 の所要時間を計ります。プロセスの中で最も長く実行されている部分を見つけて、それを短縮しようとします。ファイルを1行ずつ読み取っている可能性があります(試したことはありません)。ファイルを一度に読み取って、改行文字で分割してみてください。プロセッサのすべてのコアを使用して、それらを並行して実行する方がよい場合があります。

于 2011-11-02T14:02:59.043 に答える