2017-06-22 7 views
-1

---- 1.TXT ----読み取りテキストファイルが重複し

オリジ先のdatetime価格

YYZ,YTC,2016-04-01 12:30,$550 
YYZ,YTC,2016-04-01 12:30,$550 
LKC,LKP,2016-04-01 12:30,$550 

---- 2.txt ----

オリジ先の日時価格

YYZ|YTC|2016-04-01 12:30|$550 
AMV|YRk|2016-06-01 12:30|$630 
LKC|LKP|2016-12-01 12:30|$990 

私は2つのtxtファイルの上に持っている「」と 『|』私はC#の のコンソールアプリケーションを作成したいのですが、コマンドプロンプトから発信元と宛先の場所を渡すと2つのファイルが読み込まれます。 また、私はまた、{発信}のようになります価格順に

出力を、結果を表示したい場合、重複行を無視したい検索中 - > {先} - >日時 - 価格>

をどのように助けが必要実行する。

+5

これまでに得たもののコードサンプルはありますか? – Gareth

+1

テキストファイルの読み方を知っていますか?また、コンソールアプリケーションを作成している場合は、なぜそれを 'asp.net'でタグ付けしましたか? –

+3

ファイルを1行ずつ読む方法を学びます。 指定した区切り文字で文字列を分割する方法を学ぶ: '、' | ' 文字列を比較する方法を学びます。 $ドル記号と{}括弧を変数に使用して文字列補間を使用して文字列と変数を連結する方法を学習します。 両方のファイルを1行ずつ読み込みます。文字列の補間を使用して新しい文字列を作成するかどうかによって、コレクションをコレクションの両方または一方に追加して一致させない場合、文字列を分割および比較します。 もし私がいくつかのコードサンプルを表示することを知っていれば、私たちはそれらを改善するのを助けることができます –

答えて

0

ここではあなたの例のファイルのために働くシンプルなソリューションです。ファイルが不正な形式であるかどうかをチェックするエラーはありません。

using System; 
using System.Collections.Generic; 

class Program 
{ 
    class entry 
    { 
     public string origin; 
     public string destination; 
     public DateTime time; 
     public double price; 
    } 

    static void Main(string[] args) 
    { 
     List<entry> data = new List<entry>(); 

     //parse the input files and add the data to a list 
     ParseFile(data, args[0], ','); 
     ParseFile(data, args[1], '|'); 

     //sort the list (by price first) 
     data.Sort((a, b) => 
     { 
      if (a.price != b.price) 
       return a.price > b.price ? 1 : -1; 
      else if (a.origin != b.origin) 
       return string.Compare(a.origin, b.origin); 
      else if (a.destination != b.destination) 
       return string.Compare(a.destination, b.destination); 
      else 
       return DateTime.Compare(a.time, b.time); 
     }); 

     //remove duplicates (list must be sorted for this to work) 
     int i = 1; 
     while (i < data.Count) 
     { 
      if (data[i].origin == data[i - 1].origin 
       && data[i].destination == data[i - 1].destination 
       && data[i].time == data[i - 1].time 
       && data[i].price == data[i - 1].price) 
       data.RemoveAt(i); 
      else 
       i++; 
     } 

     //print the results 
     for (i = 0; i < data.Count; i++) 
      Console.WriteLine("{0}->{1}->{2:yyyy-MM-dd HH:mm}->${3}", 
       data[i].origin, data[i].destination, data[i].time, data[i].price); 

     Console.ReadLine(); 
    } 

    private static void ParseFile(List<entry> data, string filename, char separator) 
    { 
     using (System.IO.FileStream fs = System.IO.File.Open(filename, System.IO.FileMode.Open)) 
     using (System.IO.StreamReader reader = new System.IO.StreamReader(fs)) 
      while (!reader.EndOfStream) 
      { 
       string[] line = reader.ReadLine().Split(separator); 
       if (line.Length == 4) 
       { 
        entry newitem = new entry(); 
        newitem.origin = line[0]; 
        newitem.destination = line[1]; 
        newitem.time = DateTime.Parse(line[2]); 
        newitem.price = double.Parse(line[3].Substring(line[3].IndexOf('$') + 1)); 
        data.Add(newitem); 
       } 
      } 
    } 
} 
+0

コマンドプロンプトでもう一度質問してみましょう。ユーザーは '$ search -o YYZ -d YYC'を追加し、これに基づいて全プロセスを検証し、結果を表示する必要があります。また、私のtxtファイルでは、私はそのヘッダーの解析をスキップする方法の上に静的ヘッダーのデータがありますか?事前に感謝 – cshah

+0

私はスキップする方法を得た - reader.ReadLine()。Skip(1);他のコマンドプロンプトはまだ保留中です – cshah

0

あなたのプログラムの出力が何を想定しているかについて100%明確ではないので、実装のその部分をお伝えします。私の戦略は、文字列(ファイルから読み込む)と区切り文字(さまざまなので)を使用し、操作できるオブジェクトを作成するために(たとえばハッシュセットに追加するなど)コンストラクタメソッドを使用することでした。

PriceObject.cs

using System; 
using System.Globalization; 

namespace ConsoleApplication1 
{ 
class PriceObject 
{ 
    public string origination { get; set; } 
    public string destination { get; set; } 
    public DateTime time { get; set; } 
    public decimal price { get; set; } 



    public PriceObject(string inputLine, char delimiter) 
    { 
     string[] parsed = inputLine.Split(new char[] { delimiter }, 4); 
     origination = parsed[0]; 
     destination = parsed[1]; 
     time = DateTime.ParseExact(parsed[2], "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture); 
     price = Decimal.Parse(parsed[3], NumberStyles.Currency, new CultureInfo("en-US")); 
    } 


    public override bool Equals(object obj) 
    { 
     var item = obj as PriceObject; 
     return origination.Equals(item.origination) && 
      destination.Equals(item.destination) && 
      time.Equals(item.time) && 
      price.Equals(item.price); 
    } 

    public override int GetHashCode() 
    { 

     unchecked 
     { 
      var result = 17; 
      result = (result * 23) + origination.GetHashCode(); 
      result = (result * 23) + destination.GetHashCode(); 
      result = (result * 23) + time.GetHashCode(); 
      result = (result * 23) + price.GetHashCode(); 
      return result; 
     } 
    } 


} 
} 

Program.csの

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     HashSet<PriceObject> list1 = new HashSet<PriceObject>(); 
     HashSet<PriceObject> list2 = new HashSet<PriceObject>(); 

     using (StreamReader reader = File.OpenText(args[0])) 
     { 
      string line = reader.ReadLine(); // this will remove the header row 

      while (!reader.EndOfStream) 
      { 
       line = reader.ReadLine(); 
       if (String.IsNullOrEmpty(line)) 
        continue; 
       // add each line to our list 
       list1.Add(new PriceObject(line, ',')); 
      } 

     } 

     using (StreamReader reader = File.OpenText(args[1])) 
     { 
      string line = reader.ReadLine(); // this will remove the header row 

      while (!reader.EndOfStream) 
      { 
       line = reader.ReadLine(); 
       if (String.IsNullOrEmpty(line)) 
        continue; 
       // add each line to our list 
       list2.Add(new PriceObject(line, '|')); 
      } 

     } 

     // merge the two hash sets, order by price 
     list1.UnionWith(list2); 
     List<PriceObject> output = list1.ToList(); 

     output.OrderByDescending(x => x.price).ToList(); 

     // display output here, e.g. define your own ToString method, etc 
     foreach (var item in output) 
     { 
      Console.WriteLine(item.ToString()); 
     } 

     Console.ReadLine(); 
    } 
} 
} 
+0

あなたのコメントによるとちょうどメモC:\ temp \ test1.txt C:\ temp \ test2.txt –

+0

コマンドプロンプトでもう一度質問してみましょう。ユーザーは ' $ search -o YYZ -d YYC 'これに基づいて、私はプロセス全体を検証し、結果をどのように表示する必要があるのでしょうか?また、私のtxtファイルでは、私はそのヘッダーの解析をスキップする方法の上に静的ヘッダーのデータがありますか?事前に感謝します – cshah

+0

「プロセス全体を検証する」とは何を意味するのかよくわかりませんが、たとえば一致する結果を見つけようとしている場合は、起点 "YYZ"、目的地 "YTC"では、これらのパラメータを変数としてlinqクエリに取り込むことができます。例えば。 'PriceObject outputObject = output.Where(x => x.origination.Equals(" YYZ ")&& x.destination.Equals(" YTC "))。FirstOrDefault();'。ヘッダーをスキップするには、最初にこれを行いました。whileループの前の 'reader.ReadLine()'はヘッダーをはがします。これをもっと明確にするためにコメントを編集します。 –

関連する問題