2012-03-28 38 views
7

Tôi có chuỗi này:cách hiệu quả nhất để chuỗi riêng biệt

"B82V16814133260"

những gì sẽ là cách hiệu quả nhất để có được hai chuỗi ra khỏi nó:

phần trái String: " B82V " chuỗi phần cứng:" 16814133260 "

Quy tắc là: lấy tất cả các số ở bên phải và tạo chuỗi trong số đó, sau đó lấy lời nhắc và đặt nó vào chuỗi khác.

Đây là giải pháp của tôi, nhưng nó quá cồng kềnh! Làm thế nào để làm điều đó ngắn và hiệu quả?

 String leftString = ""; 
     String rightString=""; 

     foreach (char A in textBox13.Text.Reverse()) 
     { 
      if (Char.IsNumber(A)) 
      { 
       rightString += A; 
      } 
      else 
      { 
       break; 
      } 
     } 

     char[] arr = rightString.ToArray(); 
     Array.Reverse(arr); 

     rightString=new string(arr); 
     leftString = textBox13.Text.Replace(rightString, ""); 
+2

ý bạn là nói gì 'hiệu quả'? Hiệu quả trong bộ nhớ hoặc hiệu suất? – Tigran

+0

Trong sự tò mò, tại sao giải pháp của bạn 'quá cồng kềnh'? Nó có vẻ là một chiều dài tốt của một chức năng với tôi. – Bob2Chiv

+2

Tôi sẽ đăng Regex có liên quan, nhưng tôi thề với Chúa nếu ai đó đăng nó lên trước ... – mowwwalker

Trả lời

14

Điều này mang lại những gì bạn đang mong đợi:

var given = "B82V16814133260"; 
var first = given.TrimEnd("".ToCharArray()); 
var rest = given.Substring(first.Length); 

Console.Write("{0} -> {1} -- {2}", given, first, rest); 
// B82V16814133260 -> B82V -- 16814133260 
+0

+1: Trong khi lý thuyết quét chuỗi cho đến khi 'ch < '0' || ch > '9'' và sau đó tách trên chỉ mục có âm thanh nhanh nhất, nó sẽ có một ứng dụng khoa học để nói sự khác biệt (có thể). – Jon

+0

Chà, điều này giống như thần! – Andrew

+3

Một giải pháp thanh lịch. Tôi không biết về TrimEnd. – captncraig

4

này nên được rất nhanh:

int index = text.Length - 1; 
while (index >= 0 && Char.IsDigit(text[index])) 
{ 
    index--; 
} 
string left = text.Substring(0, index + 1); 
string right = text.Substring(index + 1); 
+0

Rất nhanh so với những gì? –

+0

@AshBurlaczenko: không có phân bổ không cần thiết của 'chuỗi',' đảo chiều' của chuỗi và không có phân bổ 'mảng'. * Nên * nhanh hơn. – Tigran

+0

Thực ra tôi sẽ chọn câu trả lời này có thể giống như câu trả lời đúng, khiến nó rõ ràng hơn và * nên * nhanh hơn bình chọn nhiều nhất, ngay cả khi phải thừa nhận rằng người được bầu chọn nhất chắc chắn là "dễ thương hơn". – Tigran

1

Tôi thích LINQ.

var s = "B82V16814133260"; 
    var lastNonNumeric = s.Reverse().Where(x => !char.IsDigit(x)).FirstOrDefault(); 
    var index = s.LastIndexOf(lastNonNumeric); 
    var secondString = s.Substring(index + 1); 
    var firstString = s.Substring(0, index+1); 

Có lẽ không phải là giải pháp tốt nhất hoặc mạnh mẽ nhất, nhưng nó hoạt động cho chuỗi thử nghiệm của bạn.

+0

Đảo ngược sẽ là một sự lãng phí nỗ lực vì bạn không cần phải giữ kết quả đảo ngược. s.Last (ch => '0' <= ch && ch <= '9') sẽ nhanh hơn. –

+0

Tôi đồng ý. Vẫn không tốt như giải pháp của Austin, vì vậy tôi sẽ không bận tâm chỉnh sửa nó. – captncraig

5

Vâng, câu trả lời khác có lẽ là tốt hơn, nhưng tôi đã viết này dù sao, vì vậy tôi đăng nó:

Nhu cầu:

using System.Text.RegularExpressions; 

Code:

string str = "B82V16814133260"; 
string[] match = Regex.match(str, @"^([\d\w]+?\w)(\d+)$").Groups; 
string left = match[1]; 
string right = match[2]; 
+0

nó cũng là một giải pháp rất tốt đẹp! – Andrew

+1

@walkerneo chỉ là một thực tế thú vị, chạy regex cho điều này (biên soạn regex quá, phát hành xây dựng) mất 1605,3 giây, hoặc 856,4 lần lâu hơn) Vì vậy, nếu tốc độ là 'hiệu quả', regex không phải là 'hiệu quả'. – payo

+0

@payo, Được rồi, cảm ơn, tôi đã giả định càng nhiều. Tuy nhiên, các yêu cầu của anh ta có thay đổi không, vì vậy mà chuỗi không chỉ kết thúc bằng chữ số, điều này sẽ dễ sửa đổi hơn. Tôi không thể biết được điều đó có thể xảy ra trong tình huống của anh ta hay không, và tất cả những gì tôi biết, những sợi dây đó sẽ luôn ở cùng một định dạng, nhưng vẫn vậy, bạn không bao giờ biết. – mowwwalker

0
string Source = textBox13.Text; 

for (i = Source.Length - 1; i >=0; i--) 
{ 
     if (! Char.IsNumber(Source[i]) 
     break; 
} 

string leftString = Source.Left(i+1); 
string rightString = Source.Right(i+1,Source.Length-i-1); 
2

Tôi đọc 'hiệu quả nhất' là 'nhanh nhất'.

Tôi đã viết một bài kiểm tra nhanh với chuỗi dài, chạy 10 triệu lần.

giải pháp Austin để sử dụng TrimEnd chạy trong 4.649s

Giải pháp của tôi chạy trong 1,927 giây

int j = given.Length - 1; 

    for (; j >= 0; j--) 
    { 
     char c = given[j]; 
     if (c < '0' || c > '9') 
     { 
     break; 
     } 
    } 

    var first = given.Substring(0, j + 1); 
    var rest = given.Substring(j + 1); 

Lưu ý rằng tôi xây dựng không debug (trong gỡ lỗi, giải pháp của tôi là chậm hơn, nhưng đó là bởi vì TrimEnd không chạy trong các bit gỡ lỗi). Vì vậy, nếu bạn đang chạy mã của tôi trong ứng dụng của bạn và đang xây dựng gỡ lỗi, nó sẽ chậm hơn.

+0

+1 cho thời gian của tôi. –

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