在字符串列表中找到一个通用字符串 [英] Find a common string within a list of strings

查看:99
本文介绍了在字符串列表中找到一个通用字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对此非常了解.昨天我有一个开发人员向我提出的问题,如果我能看看这个问题的话.

I'm very close on this. I got a question posed to me yesterday by a developer if I could have a look at this.

我感觉很亲密,但我认为这里的某些人也会体会到挑战,而我却迷失了.

I feel close, but I think some people here would appreciate the challenge too and I am lost.

如果我有一个具有以下成员的List<string>:

If I have a List<string> which has the following members:

今天

星期一

星期二

星期三

我想获取返回字符串day,因为这是List<string>中的最大公共字符串.无论位置和字符串长度如何,都应该这样做,只是想在许多字符串中找到最大长度的通用字符串.

I want to get a return string day because this is the largest common string in the List<string>. This should be done irrespective of position and string length, just want to find the largest length common string in a host of strings.

我的尝试失败了,我选择了:

My attempt failed a bit miserably, I selected:

星期一-星期二

Monday - Tuesday

星期一-星期三

,然后在每个之间做一个Intersect.显然,这将返回多个字符串,但是对于Monday - Wednesday,您会得到nday,因为这是它常见的字母.

And then did an Intersect between each. Obviously this would return multiple strings, however for Monday - Wednesday you get nday because that is what letters it has common.

这是我的代码:

  List<string> strs = new List<string>();
  strs.Add("Monday");
  strs.Add("Tuesday");
  strs.Add("Wednesday");

  var v = strs.SelectMany((day, i) => strs.Select((day2, j) => new
  {
    iDay = i,
    Day = day,
    iDay2 = j,
    Day2 = day2
  })).Where(x => x.iDay != x.iDay2).Select(x => new string(x.Day.Intersect(x.Day2).ToArray()));

有人有一个很好的整洁的解决方案吗?

Anybody have a nice and neat solution?

注意

不必是LINQ

如果没有通用字符串,请返回null或空字符串.

If there isn't a common string, return null or empty string.

推荐答案

这比我的第一种方法(删除)效果更好.

This works better than my first approach(striked out).

您可以使用以下扩展名来获取列表中最短字符串的所有子字符串(以提高效率):

You can use following extension to get all substrings of the shortest string in the list(for efficiency):

public static IEnumerable<string> getAllSubstrings(this string word)
{
    return from charIndex1 in Enumerable.Range(0, word.Length)
           from charIndex2 in Enumerable.Range(0, word.Length - charIndex1 + 1)
           where charIndex2 > 0
           select word.Substring(charIndex1, charIndex2);
}

  • 现在按Length(最长的优先顺序)
  • 对这些子字符串进行排序
  • 查看所有其他字符串(不包括字符串本身,因为该测试是多余的)是否包含该子字符串( Enumerable.All 如果一个字符串不包含给定的子字符串,则会立即返回)
  • 如果一个字符串出现在所有其他字符串中,则您发现最长的公共子字符串
  • 否则,请重复该操作,直到您检查了所有子字符串(如果未找到公用字符串)
    • now order these substrings by Length(longest first)
    • look if all other strings(excluding the string itself because that test is redundant) contain that substring (Enumerable.All returns immediately if one string doesn't contain a given substring)
    • if one string appears in all others you have found the longest common substring
    • otherwise repeat that until you've checked all substrings(if no common string was found)
    • string shortest = list.OrderBy(s => s.Length).First();
      IEnumerable<string> shortestSubstrings = shortest
          .getAllSubstrings()
          .OrderByDescending(s => s.Length);
      var other = list.Where(s => s != shortest).ToArray();
      string longestCommonIntersection = string.Empty;
      foreach (string subStr in shortestSubstrings)
      {
          bool allContains = other.All(s => s.Contains(subStr));
          if (allContains)
          {
              longestCommonIntersection = subStr;
              break;
          }
      }
      

      演示

      这篇关于在字符串列表中找到一个通用字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆