2012-03-28 20 views
7

に最も効率的な方法:私はこの文字列が持っている別の文字列

「B82V16814133260」を

それから2つの文字列を取得するための最も効率的な方法であるもの:

左部分文字列: " B82V " リグ部分文字列:" 16814133260 "

ルールはこれです:右側のすべての数字を取り出して文字列を作成し、リマインダを取り出して別の文字列に配置します。

これは私のソリューションですが、大きすぎます!それを短く効率的にする方法は?

 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

「効率的」とはどういう意味ですか?効率的なメモリまたはパフォーマンスですか? – Tigran

+0

好奇心の疎外さえ、あなたのソリューションはなぜ「かさばる」のですか?それは私にとって機能の良い長さに見えます。 – Bob2Chiv

+2

私は関連するRegexを投稿しますが、誰かが最初に投稿した場合は神に誓ってください... – mowwwalker

答えて

14

これは、あなたが期待しているものを得られます。

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:理論的には 'ch < '0' || ch > '9''まで文字列をスキャンしてインデックスを分割するのが最速のように聞こえるが、違いを伝えるには科学的なアプリが必要だろう。 – Jon

+0

うわー、これは神のようなものです! – Andrew

+3

優雅なソリューションです。私はTrimEndについて知らなかった。 – captncraig

4

これは非常に高速である必要があります:

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

何に比べて非常に速いですか? –

+0

@AshBurlaczenko:文字列の 'string'と' reversing'の不要な割り当てはなく、 'array'割り当てはありません。 *速くなければならない。 – Tigran

+0

実際に私はこの答えを最も正しいものとして選ぶでしょう。なぜなら、最も投票された人が間違いなく「もっとかわいい」と認めなければならないとしても、それはより明確で*最もすばやく投票すべきです。 – Tigran

1

私は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); 

おそらく最も優れたソリューションではありませんが、テスト文字列で使用できます。

+0

逆は、逆の結果を保持する必要がないので、労力の無駄です。 s.Last(ch => '0' <= ch && ch <= '9')はより高速になります。 –

+0

私は同意します。まだオースティンのソリューションほど良くはないので、私はそれを編集しても構いません。 – captncraig

5

まあ、他の答えは、おそらくより良いですが、私はとにかくこれを書いたので、私はそれを掲示しています:

ニーズ:

using System.Text.RegularExpressions; 

コード:

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

それはまた非常に素晴らしい解決策です! – Andrew

+1

@walkerneoこれは正規表現(コンパイル済みの正規表現も、リリースビルド)は1605.3秒か856.4倍かかりました。)速度が「効率的」であれば、正規表現は「効率的」ではありません。 – payo

+0

@payo、申し訳ありません、ありがとうございました。彼の要求は変わっても、文字列が数字だけで終わらないように、これは変更しやすくなります。彼の状況でそれが可能かどうかはわかりません。私が知っている限り、それらの文字列は常に同じ形式になりますが、それでもあなたは決してわかりません。 – 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

「最も効率的」は「最速」と読みました。

私は1000万回実行する長い文字列で簡単なテストを書いた。 TrimEndを使用する

オースティンのソリューションは、私の解決策は、(デバッグでは、私の解決策は遅いですが、それがあるためである私のビルド注意デバッグなかった1.927秒で

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); 

を走った4.649s

に走りましたTrimEndはデバッグビットで実行されていません)。したがって、アプリケーションで自分のコードを実行していて、デバッグを構築している場合は、処理速度が遅くなります。

+0

+1タイミングマイニング。 –

関連する問題