2015-03-13 26 views
4

我面临一个问题,我甚至不知道要在Google/Stack Overflow中搜索什么。 如果您觉得需要进一步解释,提问,请发表评论。相交两个列表与第一个保存顺序

基本上我想交叉两个列表并返回与原始第一个字符串值的保留顺序的相似性。

例子:

我有两个字符串,我转换为CharArray。 我想交叉这两个数组并返回类似的值,包括/与第一个字符串(s1)的顺序。


正如你所看到的第一个字符串包含E15(在特定的顺序),也是如此秒一个。

所以这两个字符串将返回:{ 'E', '1', '5'}

string s1 = "E15QD(A)"; 
string s2 = "NHE15H"; 

我现在面临的问题是,如果我取代 “S2” 有:

string s2 = "NQE18H" // Will return {'Q', 'E', '1' } 

我的操作将返回:{ 'Q', 'E', '1'}

结果应该是:{ 'E', '1'}因为Q没有弗洛w字母

目前我的操作不是最大的努力,因为我不知道在.NET中使用哪些方法能够做到这一点。

当前代码:

List<char> cA1 = s1.ToList(); 
List<char> cA2 = s2.ToList(); 

var result = cA1.Where(x => cA2.Contains(x)).ToList(); 

随时帮助我,在正确的方向指针是可以接受的,以及一个完整的解决方案。

+0

使用'Intersect'会给你从第一个字符串订单[例这里( https://dotnetfiddle.net/KqSIPC)。但是你的需求表明你可能想编写自己的[与自定义相等比较器相交](http://stackoverflow.com/questions/4340273/intersect-with-a-custom-iequalitycomparer-using-linq) – 2015-03-13 10:23:11

+0

应该怎么做是's1 =“AXBYC”'和's2 =“ABACUS”'的输出? – dasblinkenlight 2015-03-13 10:26:03

+0

@CoderofCode会马上寻找。 – 2015-03-13 10:26:47

回答

2

这是一个"longest common substring"的问题。

你可以使用这个扩展名来获取所有子懒洋洋地:

public static class StringExtensions 
{ 
    public static IEnumerable<string> GetSubstrings(this string str) 
    { 
     if (string.IsNullOrEmpty(str)) 
      throw new ArgumentException("str must not be null or empty", "str"); 

     for (int c = 0; c < str.Length - 1; c++) 
     { 
      for (int cc = 1; c + cc <= str.Length; cc++) 
      { 
       yield return str.Substring(c, cc); 
      } 
     } 
    } 
} 

那么它很容易和可读性与此LINQ查询:

string longestIntersection = "E15QD(A)".GetSubstrings() 
    .Intersect("NQE18H".GetSubstrings()) 
    .OrderByDescending(s => s.Length) 
    .FirstOrDefault(); // E1 

Enumerable.Intersect也相当有效,因为它使用一组。一注:如果两个字符串比其他那么它的效率更高(在内存方面),以第一次使用它更大:

longString.GetSubstrings().Intersect(shortString.GetSubstrings()) 
1

我想这应该这样做:

string similar = null; 

for (int i = 0; i < s1.Length; i++) 
{ 
    string s = s1.Substring(0, i + 1); 

    if (s2.Contains(s)) 
    { 
     similar = s; 
    } 
} 

char[] result = similar.ToCharArray(); 
+0

在我最初的测试中,这个工程!谢啦。 @TimSchmelter在原帖的评论中也提供了LongestSubstring解决方案的链接。我也会上传这个答案。 – 2015-03-13 10:40:44

0

@TimSchmelter在原岗位的评论中提供的链接这个答案。

public int LongestCommonSubstring(string str1, string str2, out string sequence) 
    { 
     sequence = string.Empty; 
     if (String.IsNullOrEmpty(str1) || String.IsNullOrEmpty(str2)) 
      return 0; 

     int[,] num = new int[str1.Length, str2.Length]; 
     int maxlen = 0; 
     int lastSubsBegin = 0; 
     StringBuilder sequenceBuilder = new StringBuilder(); 

     for (int i = 0; i < str1.Length; i++) 
     { 
      for (int j = 0; j < str2.Length; j++) 
      { 
       if (str1[i] != str2[j]) 
        num[i, j] = 0; 
       else 
       { 
        if ((i == 0) || (j == 0)) 
         num[i, j] = 1; 
        else 
         num[i, j] = 1 + num[i - 1, j - 1]; 

        if (num[i, j] > maxlen) 
        { 
         maxlen = num[i, j]; 
         int thisSubsBegin = i - num[i, j] + 1; 
         if (lastSubsBegin == thisSubsBegin) 
         {//if the current LCS is the same as the last time this block ran 
          sequenceBuilder.Append(str1[i]); 
         } 
         else //this block resets the string builder if a different LCS is found 
         { 
          lastSubsBegin = thisSubsBegin; 
          sequenceBuilder.Length = 0; //clear it 
          sequenceBuilder.Append(str1.Substring(lastSubsBegin, (i + 1) - lastSubsBegin)); 
         } 
        } 
       } 
      } 
     } 
     sequence = sequenceBuilder.ToString(); 
     return maxlen; 
    } 
相关问题