[英]compare the characters in two strings
在C#中,如何比較兩個字符串中的字符。
例如,假設我有這兩個字符串
“ bc3231dsc”和“ bc3462dsc”
如何以編程方式找出字符串
都以“ bc3”開頭並以“ dsc”結尾?
因此,給定的將是兩個變量:
var1 = "bc3231dsc";
var2 = "bc3462dsc";
比較從var1到var2的每個字符后,我希望輸出為:
leftMatch = "bc3";
center1 = "231";
center2 = "462";
rightMatch = "dsc";
條件:
1.字符串的長度始終為9個字符。
2.字符串不區分大小寫。
字符串類可以使用2種方法(StartsWith和Endwith)。
在閱讀了您的問題和已經給出的答案之后,我認為缺少一些約束,這些約束可能對您來說很明顯,但對社區而言卻不是。 但是也許我們可以做一些猜測工作:
由於事實,字符串只是char的枚舉,您可以在此處使用LINQ來了解匹配字符,如下所示:
private IEnumerable<bool> CommonChars(string first, string second)
{
if (first == null)
throw new ArgumentNullException("first");
if (second == null)
throw new ArgumentNullException("second");
var charsToCompare = first.Zip(second, (LeftChar, RightChar) => new { LeftChar, RightChar });
var matchingChars = charsToCompare.Select(pair => pair.LeftChar == pair.RightChar);
return matchingChars;
}
有了這個,我們可以繼續進行,現在找出使用此方法的每個連續的true和false標志塊有多長時間:
private IEnumerable<Tuple<int, int>> Pack(IEnumerable<bool> source)
{
if (source == null)
throw new ArgumentNullException("source");
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
yield break;
}
bool current = iterator.Current;
int index = 0;
int length = 1;
while (iterator.MoveNext())
{
if(current != iterator.Current)
{
yield return Tuple.Create(index, length);
index += length;
length = 0;
}
current = iterator.Current;
length++;
}
yield return Tuple.Create(index, length);
}
}
目前,我不知道是否已經存在提供相同功能的LINQ功能。 據我所讀, SelectMany()
應該是可能的SelectMany()
理論上,您可以使用此方法完成任何LINQ任務),但是作為一個即席實現,以上操作(對我來說)更容易。
然后可以按以下方式使用這些功能:
var firstString = "bc3231dsc";
var secondString = "bc3462dsc";
var commonChars = CommonChars(firstString, secondString);
var packs = Pack(commonChars);
foreach (var item in packs)
{
Console.WriteLine("Left side: " + firstString.Substring(item.Item1, item.Item2));
Console.WriteLine("Right side: " + secondString.Substring(item.Item1, item.Item2));
Console.WriteLine();
}
然后您將向哪個輸出:
左側:bc3右側:bc3
左側:231右側:462
左側:dsc右側:dsc
最大的缺點是在某種程度上使用了Tuple
因為它導致了丑陋的屬性名稱Item1
和Item2
,而這些屬性名稱遠不能立即讀取。 但是,如果真的需要,可以引入一個擁有兩個整數的簡單類,並具有一些堅如磐石的屬性名稱。 同樣,當前丟失了有關兩個塊是否共享每個塊或它們是否不同的信息。 但是,再次將這些信息也帶入元組或您自己的班級應該相當簡單。
static void Main(string[] args)
{
string test1 = "bc3231dsc";
string tes2 = "bc3462dsc";
string firstmatch = GetMatch(test1, tes2, false);
string lasttmatch = GetMatch(test1, tes2, true);
string center1 = test1.Substring(firstmatch.Length, test1.Length -(firstmatch.Length + lasttmatch.Length)) ;
string center2 = test2.Substring(firstmatch.Length, test1.Length -(firstmatch.Length + lasttmatch.Length)) ;
}
public static string GetMatch(string fist, string second, bool isReverse)
{
if (isReverse)
{
fist = ReverseString(fist);
second = ReverseString(second);
}
StringBuilder builder = new StringBuilder();
char[] ar1 = fist.ToArray();
for (int i = 0; i < ar1.Length; i++)
{
if (fist.Length > i + 1 && ar1[i].Equals(second[i]))
{
builder.Append(ar1[i]);
}
else
{
break;
}
}
if (isReverse)
{
return ReverseString(builder.ToString());
}
return builder.ToString();
}
public static string ReverseString(string s)
{
char[] arr = s.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
您需要的偽代碼..
int stringpos = 0
string resultstart = ""
while not end of string (either of the two)
{
if string1.substr(stringpos) == string1.substr(stringpos)
resultstart =resultstart + string1.substr(stringpos)
else
exit while
}
resultstart有您開始的字符串..您可以執行相同的倒退...
您可以使用的另一個解決方案是正則表達式。
Regex re = new Regex("^bc3.*?dsc$");
String first = "bc3231dsc";
if(re.IsMatch(first)) {
//Act accordingly...
}
匹配時可以為您提供更大的靈活性。 上面的模式匹配以bc3開始並以dsc結尾的任何字符串,除了換行符外,其他任何字符串之間都應匹配。 通過更改。*? 到\\ d,可以指定兩個字段之間只希望數字。 從那里開始,無限的可能性。
using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
class Sample {
static public void Main(){
string s1 = "bc3231dsc";
string s2 = "bc3462dsc";
List<string> common_str = commonStrings(s1,s2);
foreach ( var s in common_str)
Console.WriteLine(s);
}
static public List<string> commonStrings(string s1, string s2){
int len = s1.Length;
char [] match_chars = new char[len];
for(var i = 0; i < len ; ++i)
match_chars[i] = (Char.ToLower(s1[i])==Char.ToLower(s2[i]))? '#' : '_';
string pat = new String(match_chars);
Regex regex = new Regex("(#+)", RegexOptions.Compiled);
List<string> result = new List<string>();
foreach (Match match in regex.Matches(pat))
result.Add(s1.Substring(match.Index, match.Length));
return result;
}
}
更新條件
using System;
class Sample {
static public void Main(){
string s1 = "bc3231dsc";
string s2 = "bc3462dsc";
int len = 9;//s1.Length;//cond.1)
int l_pos = 0;
int r_pos = len;
for(int i=0;i<len && Char.ToLower(s1[i])==Char.ToLower(s2[i]);++i){
++l_pos;
}
for(int i=len-1;i>0 && Char.ToLower(s1[i])==Char.ToLower(s2[i]);--i){
--r_pos;
}
string leftMatch = s1.Substring(0,l_pos);
string center1 = s1.Substring(l_pos, r_pos - l_pos);
string center2 = s2.Substring(l_pos, r_pos - l_pos);
string rightMatch = s1.Substring(r_pos);
Console.Write(
"leftMatch = \"{0}\"\n" +
"center1 = \"{1}\"\n" +
"center2 = \"{2}\"\n" +
"rightMatch = \"{3}\"\n",leftMatch, center1, center2, rightMatch);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.