跟踪上次访问的节点 - C#

时间:2014-04-07 20:29:46

标签: c# linq

我有一个字符串,如下所示

string longText = "A CKJH VII D FZ A A A A A C C D";

空格后面的每个单词都被视为“单词”。我需要打印所有单词,直到我反击5个相同的连续单词。我有一个可行的解决方案。但是,我想看看有没有更好的方法来做到这一点。对此有什么更好的解决方案?

注意:这是的作业问题。我有这个要求,我想确保我使用最好的方式。

CODE

static void Main(string[] args)
{
    List<string> recentFive = new List<string>();

    string longText = "A CKJH VII D FZ A A A A A C C D";
    string[] namesArray = longText.Split(' ');
    List<string> namesList = new List<string>(namesArray.Length);
    namesList.AddRange(namesArray);

    foreach(string word in namesList)
    {

        Console.WriteLine(word);

        if (recentFive.Count < 5)
        {
            recentFive.Add(word);
        }
        else
        {
            recentFive[0] = recentFive[1];
            recentFive[1] = recentFive[2];
            recentFive[2] = recentFive[3];
            recentFive[3] = recentFive[4];
            recentFive[4] = word;

            if ((recentFive[0] == recentFive[1]) &&
                (recentFive[1] == recentFive[2]) &&
                (recentFive[2] == recentFive[3]) &&
                (recentFive[3] == recentFive[4]) )
            {
                break;
            }
        }
    }

    Console.ReadLine();
}

3 个答案:

答案 0 :(得分:2)

如果我们花时间首先编写一个帮助方法,在满足给定条件的情况下对项目进行分组,我们可以这样写:

var resultGroup = data.GroupWhile((prev, curr) => prev == curr)
    FirstOrDefault(group => group.Count() >= 5);

此方法的实现如下:

public static IEnumerable<IEnumerable<T>> GroupWhile<T>(
    this IEnumerable<T> source, Func<T, T, bool> predicate)
{
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
            yield break;

        List<T> list = new List<T>() { iterator.Current };

        T previous = iterator.Current;

        while (iterator.MoveNext())
        {
            if (!predicate(previous, iterator.Current))
            {
                yield return list;
                list = new List<T>();
            }

            list.Add(iterator.Current);
            previous = iterator.Current;
        }
        yield return list;
    }
}

答案 1 :(得分:2)

string lastWord = null;
int consec = 1;
foreach(string word in namesList)
{
   Console.WriteLine(word);
   if ( lastWord != null )
   {
      if( lastWord == word ){
         consec++;
         if ( consec == 4 )
         {
            break;  // 5 consecutive..
         }
      }
      else{
        consec = 0;
      }
   }
   lastWord = word;
 }

答案 2 :(得分:0)

我可能会这样做:

public static IEnumerable<string> TakeUntilDupesLimitReached( this IEnumerable<string> source , int limit , StringComparison comparisonType )
{
  if ( limit < 1 ) throw new ArgumentOutOfRangeException("limit") ;

  string p = null ;
  int    n = 0 ;

  foreach ( string s in source )
  {
    bool areEqual = s.Equals( p ?? s , comparisonType ) ;

    n = 1 + ( areEqual ? n : 0 ) ;
    p = s ;

    yield return s ;

    if ( n >= limit ) break ;
  }

}

然后你可以说出以下几点:

string[] x = "a b c d e e f f f g h i j".Split(new char[]{' '} , StringSplitOptions.RemoveEmptyEntries) ;
string[] y = x.TakeUntilDupesLimitReached(3,StringComparison.Ordinal).ToArray() ;