2011-12-14 23 views
18

Có phương pháp so sánh chuỗi exsting sẽ trả về giá trị dựa trên lần xuất hiện đầu tiên của một ký tự không khớp giữa hai chuỗi không?Phương pháp so sánh chuỗi C# không trả về chỉ số đầu tiên không khớp

tức

string A = "1234567890" 

string B = "1234567880" 

Tôi muốn để có được một trở lại giá trị mà sẽ cho phép tôi để thấy rằng sự xuất hiện đầu tiên của một đột phá phù hợp là A [8]

+2

là cán của riêng bạn không có thể là (có lẽ) một phương pháp mở rộng? – glosrob

+8

+1 để kiểm tra xem điều này đã tồn tại trong thư viện chuẩn trước chưa. –

+0

Hoàn toàn. Không có gì tệ hơn là niềm kiêu hãnh trong việc đánh bóng một sự thực thi thực sự tốt khi bạn nhận ra nó nằm trong khuôn khổ kể từ 1.1! –

Trả lời

7
/// <summary> 
/// Gets a first different char occurence index 
/// </summary> 
/// <param name="a">First string</param> 
/// <param name="b">Second string</param> 
/// <param name="handleLengthDifference"> 
/// If true will return index of first occurence even strings are of different length 
/// and same-length parts are equals otherwise -1 
/// </param> 
/// <returns> 
/// Returns first difference index or -1 if no difference is found 
/// </returns> 
public int GetFirstBreakIndex(string a, string b, bool handleLengthDifference) 
{ 
    int equalsReturnCode = -1; 
    if (String.IsNullOrEmpty(a) || String.IsNullOrEmpty(b)) 
    { 
     return handleLengthDifference ? 0 : equalsReturnCode; 
    } 

    string longest = b.Length > a.Length ? b : a; 
    string shorten = b.Length > a.Length ? a : b;  
    for (int i = 0; i < shorten.Length; i++) 
    { 
     if (shorten[i] != longest[i]) 
     { 
      return i; 
     } 
    } 

    // Handles cases when length is different (a="1234", b="123") 
    // index=3 would be returned for this case 
    // If you do not need such behaviour - just remove this 
    if (handleLengthDifference && a.Length != b.Length) 
    { 
     return shorten.Length; 
    } 

    return equalsReturnCode; 
} 
+1

Có lý do nào để bạn kiểm tra 'a.Equals (b)' thay vì 'a == b'? Mã của bạn sẽ bị hỏng nếu 'a' là null. –

+0

Cuộc gọi đến bằng sẽ lặp lại toàn bộ chuỗi cho đến khi ngắt đầu tiên chặn các trường hợp cắt ngắn, trước khi bạn lặp lại toàn bộ chuỗi. Tôi muốn gọi 'ReferenceEquals' như là một đoạn ngắn, nhưng bỏ qua phần còn lại của' Equals' vì công việc của nó sẽ được nhân đôi. –

+0

Cảm ơn các bạn đã chỉ tới số – sll

3

Một phương pháp mở rộng dọc theo dòng dưới đây sẽ thực hiện công việc:

public static int Your_Name_Here(this string s, string other) 
{ 
    string first = s.Length < other.Length ? s : other; 
    string second = s.Length > other.Length ? s : other; 

    for (int counter = 0; counter < first.Length; counter++) 
    { 
     if (first[counter] != second[counter]) 
     { 
      return counter; 
     } 
    } 
    return -1; 
} 
+0

Điều gì sẽ xảy ra nếu 'khác' ngắn hơn' s'? – Oded

+0

Nó bom :) bình luận công bằng, sẽ sửa đổi – glosrob

+0

Tên khủng khiếp - thích câu trả lời dưới đây từ @sll – glosrob

2

Không mà tôi biết, nhưng nó khá tầm thường:

public static int FirstUnmatchedIndex(this string x, string y) 
{ 
    if(x == null || y == null) 
    throw new ArgumentNullException(); 
    int count = x.Length; 
    if(count > y.Length) 
    return FirstUnmatchedIndex(y, x); 
    if(ReferenceEquals(x, y)) 
    return -1; 
    for(idx = 0; idx != count; ++idx) 
    if(x[idx] != y[idx]) 
     return idx; 
    return count == y.Length? -1 : count; 
} 

Đây là so sánh thứ tự đơn giản. So sánh không phân biệt dạng chữ thường là một sự thay đổi dễ dàng, nhưng cơ sở văn hóa thì khó xác định; "Weißbier" không phù hợp "WEISSBIERS" trên S cuối cùng trong chuỗi thứ hai, nhưng điều đó có được tính là vị trí 8 hoặc vị trí 9 không?

+0

LOL, tất nhiên là không @Oded, cảm ơn. –

+1

Hey ... tất cả chúng ta làm điều đó ... SO nên tích hợp một trình biên dịch trực tuyến;) – Oded

+0

@Oded Phục vụ tôi đúng cho việc gọi nó là "tầm thường". Vâng, nó là, nhưng vẫn có một sự không hoàn hảo trong bản thảo đầu tiên của mỗi câu trả lời. –

2

Nếu bạn đã NET 4.0 cài đặt, điều này có thể là một cách:

string A = "1234567890"; 
    string B = "1234567880"; 

    char? firstocurrence = A.Zip(B, (p, q) => new { A = p, B = q }) 
     .Where(p => p.A != p.B) 
     .Select(p => p.A) 
     .FirstOrDefault(); 

chỉnh sửa:

Mặc dù, nếu bạn cần các vị trí:

int? firstocurrence = A.Zip(B, (p, q) => new { A = p, B = q }) 
      .Where(p => p.A != p.B) 
      .Select((p, i) => i) 
      .FirstOrDefault(); 
+0

Không tìm thấy điểm có "abc" không khớp "abcdef". –

+0

Đó không phải là một yêu cầu trong câu hỏi. Loại dễ dàng để kiểm tra sau đó anyway, nếu hai dây có chiều dài khác nhau – Francisco

+0

Không thực sự, bởi vì để tìm nơi "abc123432343234" mismatches "abcdefghijk" yêu cầu bạn phải làm một cái gì đó mà có thể đã trả lời câu hỏi ở nơi đầu tiên. –

0

Nó có thể để viết tiện ích chuỗi như

public static class MyExtensions 
{ 
    public static IList<char> Mismatch(this string str1, string str2) 
    { 
     var char1 = str1.ToCharArray(); 
     var char2 = str2.ToCharArray(); 
     IList<Char> Resultchar= new List<char>(); 
     for (int i = 0; i < char2.Length;i++) 
     { 
      if (i >= char1.Length || char1[i] != char2[i]) 
       Resultchar.Add(char2[i]); 
     } 
     return Resultchar; 
    } 
} 

Sử dụng nó như

var r = "1234567890".Mismatch("1234567880"); 

Nó không phải là một thuật toán tối ưu hóa cho việc tìm kiếm phù hợp.

Nếu bạn chỉ quan tâm để tìm ra những không phù hợp đầu tiên,

public static Char FirstMismatch(this string str1, string str2) 
     { 
      var char1 = str1.ToCharArray(); 
      var char2 = str2.ToCharArray();    
      for (int i = 0; i < char2.Length;i++) 
      { 
       if (i >= char1.Length || char1[i] != char2[i]) 
        return char2[i]; 
      } 
      return ''c; 
     } 
Các vấn đề liên quan