c# - 使用另一个字符串数组中的字符串搜索字符串数组

问题描述:

就像在标题中一样。我得到了一个字符串数组和第二个字符串数组。我想在这种模式下显示结果:第一个数组的第一个元素 - 然后是第一个数组的第一个元素中出现的第二个数组中的所有元素。在第一个数组的第二个元素和第二个数组的第二个元素中出现的所有元素之后。等等。 例如:c# - 使用另一个字符串数组中的字符串搜索字符串数组

string[] arrayA = {"Lorem ipsum dolor sit amet, justo", "notgin like good cold beer"}; 
string[] arrayB = {"justo","beer","lorem"} 
for (int i = 0; i < arrayA.Length; i++) 
    { 
     Console.WriteLine(arrayA[i]); 

     for (int j = 0; j < arrayB.Length; j++) 
     { 
      int controlIndex = arrayA[i].IndexOf(arrayB[j]); 
      if (controlIndex != -1) 
      { 
       Console.Write(" :--contains-->" + arrayB[j]); 
      } 

    } 

}

所以结果应该是这样的:

  • Lorem存有悲坐阿梅德,胡斯托: - 包含 - >胡斯托,LOREM
  • 喜欢好的冷啤酒: - 包含 - >啤酒

但我的结果是: - Lorem存有悲坐阿梅德,胡斯托: - 包含 - >胡斯托 - notgin想好冰镇啤酒: - 包含 - >啤酒

因此,大家可以看到有没有LOREM上市

这并不难,如果你打破你的问题一些。首先,远离处理数组和索引的问题。只需使用IEnumerable<T>,它会让你的生活更轻松。

我是这样看的:

首先,你要找到一个数组needles的所有字符串,是一个字符串,haystack的一部分。

public static IEnumerable<string> MatchingStrings(string haystack, IEnumerable<string> needles) 
{ 
    return needles.Where(needle => haystack.Contains(needle)); 
} 

这将从needles是的haystack的一部分返回所有字符串的IEnumerable。

然后,你只需遍历所有的搜索字符串,我会打电话给haystacks

static void Main(string[] args) 
    { 
     var haystacks = new[] { 
      "Lorem ipsum dolor sit amet, justo", 
      "notgin like good cold beer" 
     }; 

     var needles = new[] {"justo", "beer", "lorem"}; 

     foreach (var haystack in haystacks) { 
      Console.Write(haystack + " contains --> "); 
      var matches = MatchingStrings(haystack, needles); 

      Console.WriteLine(String.Join(",", matches)); 
     } 

     Console.ReadLine(); 
    } 

注意String.Contains()区分大小写。所以“Lorem”不会匹配“lorem”。如果你想要这种行为,你必须先将它们转换为小写。

public static IEnumerable<string> MatchingStringsCaseInsensitive(string haystack, IEnumerable<string> needles) 
{ 
    var h = haystack.ToLower(); 
    return needles.Where(needle => h.Contains(needle.ToLower())); 
} 
+0

这很好,但也会返回像这样的LoremTy,这是不好的。只有在有“Lorem”时才应该返回。 – born2fr4g 2012-07-22 01:46:05

+0

你从来没有用文字说过。然而,人们应该可以修改这个,使用'String.Split'将每个干草堆分割成单词和搜索这些干草堆。 – 2012-07-22 02:06:52

+0

再次感谢那个例子。有很多要学习;)。 – born2fr4g 2012-07-22 20:14:02

string[] arrayA = {"Lorem ipsum dolor sit amet, justo", "notgin like good cold beer"}; 
string[] arrayB = {"justo","beer","lorem"}; 

foreach (var s in arrayA) 
{ 
    Console.Write(s + " contains: " + 
        string.Join(",", arrayB.Where(s.Contains))); 
} 

如果你想忽略大小写:

foreach (var s in arrayA) 
{ 
    Console.Write(s + " contains: " + 
        string.Join(",", arrayB.Where(x => 
         s.IndexOf(x, StringComparison.OrdinalIgnoreCase) != -1))); 
} 
+0

尼斯:)。我真的需要使用lambda表达式。但是在认为我的代码是好的之后(我与大写的Lorem犯了一个错误,所以这就是为什么它没有被列出)。不管怎样,谢谢你。 – born2fr4g 2012-07-22 00:35:28

foreach(var a in arrayA) 
{ 
    Console.WriteLine("a: " + a); 
    Console.WriteLine("bs: " + 
     String.Join(", ", arrayB.Where(b => a.IndexOf(b) > -1))); 
} 

此外,如果你的意思是不关心的情况下,a.IndexOf(b)将是a.IndexOf(b, StringComparison.OrdinalIgnoreCase)

+0

在.net 4中不需要'.ToArray()';) – SimpleVar 2012-07-22 00:40:36

+0

@YoryeNathan谢谢,也习惯了3.5。我希望他们将相同的重载添加到字符串构造函数中。 – 2012-07-22 00:42:39

+0

你是什么意思,像'新字符串(myIEnumerable)'?这个想法会是什么? – SimpleVar 2012-07-22 00:45:32

这是Linq的解决方案:

var result = arrayA.Select(a => new{ 
    A = a, 
    bContains = arrayB.Where(b => a.IndexOf(b, 0, StringComparison.CurrentCultureIgnoreCase) > -1)    
}); 

foreach(var x in result) 
{ 
    Console.WriteLine("{0}:--contains-->{1}", x.A, string.Join(",", x.bContains)); 
} 

这里有一个演示:http://ideone.com/wxl6I

+0

为什么在你不需要时使用匿名类型? – SimpleVar 2012-07-22 00:44:05

+0

@YoryeNathan:因为我不知道想要的结果,它可能是一个'Console.WriteLine',它可能是一个数组,列表,类或元组。所以我创造了最有活力的东西,让OP可以用它来创造他想要的东西。 – 2012-07-22 00:45:45

+0

但是你确实知道理想的结果 - 他想打印它们。他甚至希望以一种非常特定的方式。看起来没有更多。 – SimpleVar 2012-07-22 00:46:45

这是我尝试

string[] arrayA = {"lorem ipsum dolor sit amet, justo", "notgin like good cold beer"}; 
string[] arrayB = {"justo", "beer", "lorem"}; 

foreach (var item in from a in arrayA from b in arrayB where a.Contains(b) select new {a, b}) 
{ 
    Console.WriteLine(item.a); 
    Console.WriteLine(item.b); 
} 

注:Contains是敏感的情况下,比较和你”你需要编写一个自定义比较器(其他答案已经完成)

Lorem是大写。尝试使用不区分大小写的搜索:.indexOf(string, StringComparison.CurrentCultureIgnoreCase)

我已经给你所有可能的答案,但包含方法将创建一个问题,它也将在下面提到的情况下返回true。

reference_string = "Hello Stack Overflow" 
test_string = "Over" 

所以尽量避免含有因为contains方法将

“返回指示是否在此字符串中出现指定的System.String对象的值”

注:StringComparer.OrdinalIgnoreCase为不区分大小写而添加。

/// <summary> 
     /// Compares using binary search 
     /// </summary> 
     /// <param name="input"> search input</param> 
     /// <param name="reference"> reference string</param> 
     /// <returns> returns true or false</returns> 
     public bool FatMan(string input, string reference) 
     { 
      string[] temp = reference.Split(); 
      Array.Sort(temp); 
      List<string> refe = new List<string> { }; 
      refe.AddRange(temp); 

      string[] subip = input.Split(); 
      foreach (string str in subip) 
      { 
       if (refe.BinarySearch(str, StringComparer.OrdinalIgnoreCase) < 0) 
       { 
        return false; 
       } 
      } 

      return true; 
     } 

     /// <summary> 
     /// compares using contains method 
     /// </summary> 
     /// <param name="input"> search input</param> 
     /// <param name="reference"> reference string</param> 
     /// <returns> returns true or false</returns> 
     public bool Hiroshima(string input, string reference) 
     { 
      string[] temp = reference.Split(); 
      Array.Sort(temp); 
      List<string> refe = new List<string> { }; 
      refe.AddRange(temp); 
      string[] subip = input.Split(); 

      foreach (string str in subip) 
      { 
       if (!refe.Contains(str, StringComparer.OrdinalIgnoreCase)) 
       { 
        return false; 
       } 
      } 

      return true; 
     } 


     public bool Nakashaki(string input, string reference) 
     { 
      string[] temp = reference.Split(); 
      Array.Sort(temp); 
      List<string> refe = new List<string> { }; 
      refe.AddRange(temp); 
      string[] subip = input.Split(); 

      int result = (from st in subip where temp.Contains(st, StringComparer.OrdinalIgnoreCase) select st).Count(); 

      if (result <= 0) 
      { 
       return false; 
      } 

      return true; 
     } 

     /// <summary> 
     /// compares using contains method 
     /// </summary> 
     /// <param name="input"> search input</param> 
     /// <param name="reference"> reference string</param> 
     /// <returns> returns true or false</returns> 
     public bool LittleBoy(string input, string reference) 
     { 
      string[] subip = input.Split(); 
      foreach (string str in subip) 
      { 
       if (!reference.Contains(str)) 
       { 
        return false; 
       } 
      } 

      return true; 
     } 

bool oupt ; 
string[] strarray1 = new string[3]{"abc","def","ghi" }; 
string[] strarray2 = new string[4] { "648", "888", "999", "654" }; 
if (strarray1.All(strarray.Contains)) 
    oupt = true; 
else 
    oupt = false; 
+1

嗨,欢迎来到SO!请在代码中添加几行以解释为什么您认为您的答案是原始问题的一个很好的解决方案,谢谢。 – m4rtin 2014-09-06 23:24:26