0

default.txt と current.txt の 2 つのテキスト ファイルがあります。

デフォルト.txt:

ab_abcdefghi_EnInP005M3TSub.csv FMR: 0.0009 FNMR: 0.023809524 SCORE: -4  Conformity: True
ab_abcdefghi_EnInP025M3TSub.csv FMR: 0.0039 FNMR: 0 SCORE: -14  Conformity: True
ab_abcdefghi_EnInP050M3TSub.csv FMR: 0.01989 FNMR: 0 SCORE: -18  Conformity: True
ab_abcdefghi_EnInP075M3TSub.csv FMR: 0.0029 FNMR: 0 SCORE: -17  Conformity: True
ab_abcdefghi_EnInP090M3TSub.csv FMR: 0.0002 FNMR: 0 SCORE: -7  Conformity: True

current.txt は次のようになります

ab_abcdefghi_EnUsP005M3TSub.csv FMR: 0.0041 FNMR: 0 SCORE: -14  Conformity: True
ab_abcdefghi_EnUsP025M3TSub.csv FMR: 0.00710000000000001 FNMR: 0 SCORE: -14  Conformity: True
ab_abcdefghi_EnUsP050M3TSub.csv FMR: 0.0287999999999999 FNMR: 0 SCORE: -21  Conformity: True
ab_abcdefghi_EnUsP090M3TSub.csv FMR: 0.0113 FNMR: 0 SCORE: -23  Conformity: True

私がする必要があるのは、デフォルトから現在の値を減算することです(デフォルト電流)。

例えば:

FMR_DIFF = FMR(default) - FMR(test)
FNMR_DIFF = FNMR(default) - FNMR(test)
SCORE_DIFF = SCORE(default) - SCORE(test)

これをテキストファイルに出力する必要があり、出力は次のようになります

O/P:

result:   005M3TSub FMR_DIFF: -0.0032 FNMR_DIFF: 0.023809524 SCORE_DIFF: 10

私はC#でこれをやろうとしています。これまでのところ、両方のファイルの行を読み取ろうとしました。それらを比較することができました。実装する必要があるロジックを理解できません。私はプログラミングに非常に慣れていません。どんな助けでも大歓迎です。

4

3 に答える 3

1

値を比較するには、まずそれらを解析する必要があります。(False / Non-False) MatchRates の 1 行を表すクラスを作成できます。

public class MatchRateLine
{
    public int LineNumber { get; set; }

    public decimal FMR { get; set; }
    public decimal FNMR { get; set; }
    public int Score { get; set; }
    public bool Conformity { get; set; }
}

次に、パーサーで次のようなメソッドを使用できます。

public List<MatchRateLine> ParseFile(string filename)
{
    var result = new List<MatchRateLine>();

    using (var reader = new StreamReader(filename))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            result.Add(ParseLine(line));
        }
    }

    return result;
}

そして、実際の解析を行う 1 つの方法は次のとおりです。

public MatchRateLine ParseLine(string line)
{
    var result = new MatchRateLine();

    int fmrPosition = line.IndexOf("FMR: ");
    int fmnrPosition = line.IndexOf("FMNR: ");

    string fmrValueString = line.Substring(fmrPosition, fmnrPosition - fmrPosition);
    decimal fmrValue;
    if (decimal.TryParse(fmrValueString, out fmrValue))
    {
        result.FMR = fmrValue;
    }

    // repeat for other values

    return result;
}

パーサーで、「行の FMR 値」「'FMR:' と 'FMNR:' の間のテキストで、10 進数として解析される」と定義しました。抽出する値ごとにこのロジックを適用する必要があります。

2 つのコレクションがある場合、それらをループして値などを比較できます。

var defaultLines = Parser.ParseFile("default.txt");
var currentLines = Parser.ParseFile("current.txt");

defaultあなたの実際の質問は、おそらくとの特定の行を比較したいということcurrentですが、互いに属している行を特定するのに苦労しています。5行目で見られるようにab_abcdefghi_EnInP090M3TSub、4行目です(注)。defaultab_abcdefghi_EnUsP090M3TSubcurrentIn/Us

このために、プロパティを使用してクラスを拡張できます。この場合MatchRateLine、ファイル名またはその部分文字列をその意味で保存し、この値で両方のリストで一意の行を見つけることができます。

Substring()メソッドで、このメソッドを再度使用できますParseLine()

// Position:  0123456789012345678901234567890
// Filename: "ab_abcdefghi_EnInP090M3TSub.csv"

result.ReportCode = line.Substring(17, 6);

これにより、結果に値MatchRateLineを持つReportCodeプロパティが含まれますP090M3

行の 2 つのリストが再び与えられます。

var p090m3DefaultLine = defaultLines.First(l => l.ReportCode == "P090M3");
var p090m3CurrentLine = currentLines.First(l => l.ReportCode == "P090M3");

var fmrDiff = p090m3DefaultLine.FMR - p090m3CurrentLine.FMR;

このコードは形式について多くの仮定を行っており、解析中の行がその形式と一致しない場合に例外をスローする可能性があることに注意してください。

于 2013-12-30T11:13:56.877 に答える
1

これは興味深い問題です。解決策を確認してください。適切に最適化されていません。

まず、文字列を表す単純な FileStructure クラスを作成します。

public class DefaultFileStructure
    {
        public string FileId;
        public decimal FMR;
        public decimal FNMR;
        public int Score;
        public bool Conformity;
    }

解析用の定数キー名を定義します。

private static string DEFAULT_KN = "tv_rocscores_DeDeP";
private static string TEST_KN    = "tv_rocscores_FrFrP";

次に、ファイルを解析し、データをリスト構造に保存します。

    private List<DefaultFileStructure> GetFileStructure(string filePath, string keyName)
            {
                List<DefaultFileStructure> _defaultFileStructure = new List<DefaultFileStructure>();

                if(!File.Exists(filePath))
                {
                    Console.WriteLine("Error in loading the file");               
                }else{
                    string[] readText = File.ReadAllLines(filePath);
                    foreach (string s in readText)
                    {
                        _defaultFileStructure.Add(ParseLine(s, keyName));                    
                    }
                }

                return _defaultFileStructure;
            }

private DefaultFileStructure ParseLine(string Line, string Keyname)
        {
            DefaultFileStructure _dFileStruc = new DefaultFileStructure();

            string[] groups = Line.Split(new[] { ' ', ' ' },StringSplitOptions.RemoveEmptyEntries);

            /* -- Format Strucure, if the log provide same format always..
               Can also implement Expando concepts of C# 5.0 ***
                0[tv_rocscores_DeDeP005M3TSub.csv]
                1[FMR:]
                2[0.0009]
                3[FNMR:]
                4[0.023809524]
                5[SCORE:]
                6[-4]
                7[Conformity:]
                8[True]
             */

            _dFileStruc.FileId = groups[0].Replace(Keyname, "");
            _dFileStruc.FMR = decimal.Parse(groups[2]);
            _dFileStruc.FNMR = decimal.Parse(groups[4]);
            _dFileStruc.Score = int.Parse(groups[6]);
            _dFileStruc.Conformity = bool.Parse(groups[8]);

            return _dFileStruc;
        }

違いを一致させ、質問に従って定義された結果を取得します。

 public void getDiff(String FirstFile, string SecondFile, string ResultFile)
        {
            try
            {
                //check if file exits....
                if (!File.Exists(FirstFile)) { return; }
                if (!File.Exists(SecondFile)) { return; }

                //Keep the result String..
                StringBuilder ResultBuilder = new StringBuilder();

                //Get the List of default file.
                List<DefaultFileStructure> DefaultList = GetFileStructure(FirstFile, DEFAULT_KN);

                //Get the List of test file.
                List<DefaultFileStructure> TestList = GetFileStructure(SecondFile, TEST_KN);


                //Get the diff and save in StringBuilder.
                foreach (DefaultFileStructure defFile in DefaultList)
                {
                    bool checkALL = false;
                    foreach (DefaultFileStructure testFile in TestList)
                    {
                        //Compare the file for diff.
                        if (defFile.FileId == testFile.FileId)
                        {
                            checkALL = false;
                            ResultBuilder.AppendLine(String.Format("result: {0} FMR_DIFF: {1} FNMR_DIFF: {2} SCORE_DIFF: {3}", defFile.FileId, defFile.FMR - testFile.FMR, defFile.FNMR - testFile.FNMR, defFile.Score - testFile.Score));
                            break;
                        }
                        else
                        {
                            checkALL = true;                      
                        }                        
                    }
                    if (checkALL == true)
                    {
                        ResultBuilder.AppendLine(String.Format("result: {0} FMR_DIFF: {1} FNMR_DIFF: {2} SCORE_DIFF: {3}", defFile.FileId, "N/A", "N/A", "N/A"));

                    }
                }

                //File processing completed.
                using (StreamWriter outfile = new StreamWriter(ResultFile))
                {
                    outfile.Write(ResultBuilder.ToString());
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

次のメソッドを呼び出します。

 getDiff(@"I:\Default_DeDe_operational_points_verbose.txt",
         @"I:\FrFr_operational_points_verbose.txt", 
         @"I:\Result.txt");

ありがとう、アジト

于 2014-01-12T23:00:27.180 に答える
0

どの行を出力する必要があるかを指定する必要があります: デフォルトのすべての "file".csv? 現在からすべて?両方 (2 つのファイルのいずれかに欠落している場合、出力にはこの csv が含まれている必要があります)?

それがわかったら、ロジックを実装できます。

  • ラインのプロパティを持つクラス (たとえば FileLine という名前) を作成します。つまり、名前の文字列 (この文字列の名前: CsvName)、FMR の 10 進数 (FmrValue など)、FNMR の 10 進数 (FnmrValue) です。 、SCORE (ScoreValue) の int
  • プロセスのメソッドを作成します。そうなる:

  • 現在のファイルの構造を確認してください: 有効でない場合は、プロセスを停止します

  • defaultLines という名前の新しいリストを作成します
  • currentLines という名前の新しいリストを作成します
  • processedLine という文字列を作成します (後のステップで使用します)。
  • デフォルト ファイルの読み取り: foreach 行、FileLine の作成、行の解析、FileLine のプロパティの実装、および fileLine のリストへの追加 (defaultLines)
  • 現在のファイルを読み取ります: foreach 行を作成し、FileLine を作成し、行を解析して FileLine のプロパティを実装し、fileLine をリスト (currentLines) に追加します。
  • 次に、比較を処理します (後述)

    public void comparisonGenerator() {

    // HERE: add currentFile check
    
    // Initialization
    List<FileLine> defaultLines = new List<FileLine>();
    List<FileLine> currentLines = new List<FileLine>();
    
    // HERE: add file reading to populate defaultLines and currentLines 
    
    
    // Comparison
    foreach(FileLine item in defaultLines)
    {
        // for the item with the same name (using Linq, you could do it easily):
        FileLine cLine = currentLines.Single(l => l.CsvName.Equals(item.CsvName));
        if(cLine != null)
        {
            processedLine = String.Format("result: {0} FMR_DIFF: {1} FNMR_DIFF: {2} SCORE_DIFF: {3}", item.CsvName, item.FmrValue - cLine.FmrValue, item.FnmrValue - cLine.FnmrValue, item.ScoreValue - cLine.ScoreValue);
            // HERE: add this line to future output
        }
    }
    
    // When all lines are processed, write the output to a file using FileStream
    

    }

于 2013-12-30T11:24:00.467 に答える