2009-08-07 57 views
6

Với tệp đầu vào của dòng văn bản, tôi muốn xác định và xóa các dòng trùng lặp. Vui lòng hiển thị một đoạn mã C# đơn giản để thực hiện điều này.Xóa các dòng trùng lặp khỏi tệp văn bản?

+0

Có nhiều phương pháp khác nhau, dễ thực hiện hơn hơn những người khác. Cách tiếp cận được thực hiện có thể phụ thuộc vào kích thước của tệp văn bản và số lượng các dòng phù hợp dự kiến. Bạn có thể mô tả vấn đề cụ thể mà bạn đang cố giải quyết không? Cảm ơn :) –

+0

. . . và hiệu suất mong muốn. –

Trả lời

18

này nên làm (và sẽ sao chép với các tập tin lớn).

Lưu ý rằng nó chỉ loại bỏ trùng lặp liên tiếp dòng, tức là

a 
b 
b 
c 
b 
d 

sẽ kết thúc như

a 
b 
c 
b 
d 

Nếu bạn không muốn có bản sao bất cứ nơi nào, bạn sẽ cần phải giữ một bộ dòng bạn đã thấy.

using System; 
using System.IO; 

class DeDuper 
{ 
    static void Main(string[] args) 
    { 
     if (args.Length != 2) 
     { 
      Console.WriteLine("Usage: DeDuper <input file> <output file>"); 
      return; 
     } 
     using (TextReader reader = File.OpenText(args[0])) 
     using (TextWriter writer = File.CreateText(args[1])) 
     { 
      string currentLine; 
      string lastLine = null; 

      while ((currentLine = reader.ReadLine()) != null) 
      { 
       if (currentLine != lastLine) 
       { 
        writer.WriteLine(currentLine); 
        lastLine = currentLine; 
       } 
      } 
     } 
    } 
} 

Lưu ý rằng điều này giả định Encoding.UTF8 và bạn muốn sử dụng tệp. Thật dễ dàng để khái quát như một phương pháp mặc dù:

static void CopyLinesRemovingConsecutiveDupes 
    (TextReader reader, TextWriter writer) 
{ 
    string currentLine; 
    string lastLine = null; 

    while ((currentLine = reader.ReadLine()) != null) 
    { 
     if (currentLine != lastLine) 
     { 
      writer.WriteLine(currentLine); 
      lastLine = currentLine; 
     } 
    } 
} 

(. Lưu ý rằng điều đó không đóng bất cứ điều gì - người gọi nên làm điều đó)

Dưới đây là một phiên bản đó sẽ loại bỏ tất cả bản sao, chứ không phải là những người chỉ liên tiếp:

static void CopyLinesRemovingAllDupes(TextReader reader, TextWriter writer) 
{ 
    string currentLine; 
    HashSet<string> previousLines = new HashSet<string>(); 

    while ((currentLine = reader.ReadLine()) != null) 
    { 
     // Add returns true if it was actually added, 
     // false if it was already there 
     if (previousLines.Add(currentLine)) 
     { 
      writer.WriteLine(currentLine); 
     } 
    } 
} 
28

Đối với các file nhỏ:

string[] lines = File.ReadAllLines("filename.txt"); 
File.WriteAllLines("filename.txt", lines.Distinct().ToArray()); 
+0

Tôi tự hỏi cách nó xử lý .Distinct() trên T []. – user7116

+0

Có vẻ như Distinct sử dụng một lớp Set bên trong có vẻ như là một parred xuống lớp HashSet. Cung cấp 'đường' không phải là lớn w.r.t. bộ nhớ này nên thực hiện rất tốt. – user7116

2

Đối với một tập tin dài (và sự trùng lặp không liên tiếp) tôi muốn sao chép các dòng file theo đường xây dựng một bảng tra cứu băm // vị trí như tôi đi.

Khi mỗi dòng được sao chép kiểm tra giá trị băm, nếu có một va chạm đôi kiểm tra xem dòng có giống nhau không và chuyển sang dòng tiếp theo. (

Chỉ có giá trị nó cho các tập tin khá lớn mặc dù.

2

Dưới đây là một cách tiếp cận streaming nên phải chịu ít bước đầu hơn đọc tất cả các chuỗi độc đáo vào bộ nhớ.

var sr = new StreamReader(File.OpenRead(@"C:\Temp\in.txt")); 
    var sw = new StreamWriter(File.OpenWrite(@"C:\Temp\out.txt")); 
    var lines = new HashSet<int>(); 
    while (!sr.EndOfStream) 
    { 
     string line = sr.ReadLine(); 
     int hc = line.GetHashCode(); 
     if(lines.Contains(hc)) 
      continue; 

     lines.Add(hc); 
     sw.WriteLine(line); 
    } 
    sw.Flush(); 
    sw.Close(); 
    sr.Close(); 
+1

Nó đòi hỏi ít bộ nhớ hơn, nhưng nó cũng tạo ra đầu ra không chính xác nếu có xung đột băm. –

0

Tôi mới vào net & có viết một cái gì đó đơn giản hơn, có thể không hiệu quả lắm.Vui lòng điền vào để chia sẻ suy nghĩ của bạn.

class Program 
{ 
    static void Main(string[] args) 
    { 
     string[] emp_names = File.ReadAllLines("D:\\Employee Names.txt"); 
     List<string> newemp1 = new List<string>(); 

     for (int i = 0; i < emp_names.Length; i++) 
     { 
      newemp1.Add(emp_names[i]); //passing data to newemp1 from emp_names 
     } 

     for (int i = 0; i < emp_names.Length; i++) 
     { 
      List<string> temp = new List<string>(); 
      int duplicate_count = 0; 

      for (int j = newemp1.Count - 1; j >= 0; j--) 
      { 
       if (emp_names[i] != newemp1[j]) //checking for duplicate records 
        temp.Add(newemp1[j]); 
       else 
       { 
        duplicate_count++; 
        if (duplicate_count == 1) 
         temp.Add(emp_names[i]); 
       } 
      } 
      newemp1 = temp; 
     } 
     string[] newemp = newemp1.ToArray(); //assigning into a string array 
     Array.Sort(newemp); 
     File.WriteAllLines("D:\\Employee Names.txt", newemp); //now writing the data to a text file 
     Console.ReadLine(); 
    } 
} 
+0

Một ý nghĩ: nó sẽ hữu ích nếu bạn có thể nhận xét mã của bạn để giải thích những gì bạn đang làm (và tại sao) - điều đó sẽ giúp người khác hiểu được phương pháp của bạn và áp dụng nó vào tình huống của họ trong tương lai. –

Các vấn đề liên quan