开发者

Find out how long the longest sequence is in a string

开发者 https://www.devze.com 2023-01-10 22:32 出处:网络
I recently had this question in an interview and this is what I came up with.Any feedback? Find out how long the longest sequence is in a string.For example, in the string \"abccdeeeeef\"the answer w

I recently had this question in an interview and this is what I came up with. Any feedback?

Find out how long the longest sequence is in a string. For example, in the string "abccdeeeeef" the answer would be 5.

    static int LongestSeq(string strPass)
    {
        int longestSeq 开发者_高级运维= 0;

        char[] strChars = strPass.ToCharArray();

        int numCurrSeq = 1;
        for (int i = 0; i < strChars.Length - 1; i++)
        {
            if (strChars[i] == strChars[i + 1])
            {
                numCurrSeq++;
            }
            else
            {
                numCurrSeq = 1;
            }

            if (longestSeq < numCurrSeq)
            {
                longestSeq = numCurrSeq;
            }
        }

        return longestSeq;
    }


This will return 0 for strings of length 1 (when it should return 1).


First comment: you don't need to convert it to a char array. You can index straight into the string.

Second comment: you could easily generalize this to IEnumerable<T> if you wanted to, using foreach and remembering the "current" item.

Third comment: I think the comparison between longestSeq and numCurrSeq would be clearer as:

if (numCurrSeq > longestSeq)

To me that's more natural as I usually have the varying part of the expression first.


Just to add my 2 pence in, here's an alternative using Regex:

string source = "eeabccdeeeeef";
Regex reg = new Regex(@"(\w)\1+");
MatchCollection matches = reg.Matches(source);

int longest = 0;
foreach (System.Text.RegularExpressions.Match match in matches)
{
    if (longest < match.Length) longest = match.Length;
}

Due to not reading the question properly in the first place when posting my previous answer, I should probably add in some actual feedback considering that's the question posted by the OP. However, every point I've come up with has been mentioned by Henrik or Job Skeet, so I'll just stress the point Jon Skeet made; you do not have to convert a string to a char array, you can just index a particular point in the string as follows:

char letter = someString[4];

So it should all still work if you replace strChars with strPass.


You can always rember the last character, so you don't need to access the array twice in an iteration.

Inside your loop you can use another loop which iterates as long as the current character is the same as the last character. After this subloop you can place the check if the current numCurrSeq > longestSeq you you don't need this check every iteration but for every subsequence.


I don't really know whatever langauge this is (C#?) so excuse any minor syntactic glitches (I don't know if it's "else if" or "elseif" or "elif" or something else)

static int LongestSeq(string strPass)
{
    int longestSeq = 1;

    int curSeqStart = 0;
    for (int i = 1; i < strPass.Length; i++)
    {
        if (strPass[i] != strPass[curSeq])
        {
            curSeqStart = i;
        }
        else if (i - curSeqStart + 1 > longestSeq) 
        {
            longestSeq = i - curSeqStart + 1;
        }
    }
    return longestSeq;
}

It might be more efficient to do

...
else
{
    len = i - curSeqStart + 1
    if ( len > longestSeq )
    {
        longestSeq = len;
    }
}

or even just

...
else
{
    longestSeq = max(longestSeq, i - curSeqStart + 1)
}

depending on how good your 'max' implementation and compiler are.


I think this works? I don't ussually write recursive methods, I would have totally come up with the posters answer..

public static int recurse(Char last, int seqLength, int currentIndex, int largestSeqLength, string source)
{
    if (currentIndex > source.Length)
    {
        return largestSeqLength;
    }

    if (source[currentIndex] == last)
    {
        seqLength++;
        if (seqLength > largestSeqLength)
        {
            largestSeqLength = seqLength;
        }
    }
    else
    {
        seqLength = 1;
    }

    return recurse(source[currentIndex], seqLength, currentIndex++, largestSeqLength, source);
}


And another implementation

public static int LongestSeq<T>(this IEnumerable<T> source)
{
    if (source == null)
        throw new ArgumentNullException("source");

    int result = 0;
    int currentCount = 0;

    using (var e = source.GetEnumerator())
    {
        var lhs = default(T);

        if (e.MoveNext())
        {
            lhs = e.Current;
            currentCount = 1;
            result = currentCount;
        }

        while (e.MoveNext())
        {
            if (lhs.Equals(e.Current))
            {
                currentCount++;
            }
            else
            {
                currentCount = 1;
            }

            result = Math.Max(currentCount, result);
            lhs = e.Current;
        }
    }

    return result;
}


A simple (untested) solution would be:

int GetLongestSequence(string input)
{
  char c = 0;
  int maxSequenceLength = 0;
  int maxSequenceStart = 0;
  int curSequenceLength = 0;
  int length = input.Length;

  for (int i = 0; i < length; ++i)
  {
    if (input[i] == c)
    {
      ++curSequenceLength;
      if (curSequenceLength > maxSequenceLength)
      {
        maxSequenceLength = curSequenceLength;
        maxSequenceStart = i - (curSequenceLength - 1);
      }
    }
    else
    {
      curSequenceLength = 1;
      c = input[i];
    }
  }
  return maxSequenceStart;
}

Or a better structured code (also untested):

private int GetSequenceLength(string input, int start)
{
  int i = start;
  char c = input[i];
  while (input[i] == c) ++i; // Could be written as `while (input[i++] == c);` but i don't recommend that
  return (i - start);
}

public int GetLongestSequence(string input)
{
  int length = input.Length;
  int maxSequenceLength = 0;
  int maxSequenceStart = 0;

  for (int i = 0; i < length; /* no ++i */)
  {
    int curSequenceLength = this.GetSequenceLength(input, i);
    if (curSequenceLength > maxSequenceLength)
    {
      maxSequenceLength = curSequenceLength;
      maxSequenceStart = i;
    }
    i += curSequenceLength;
  }
  return maxSequenceStart;
}


This extension method find the longest sequence of same characters in a string.

   public static int GetLongestSequenceOfSameCharacters(this string sequence)
        {
            var data = new List<char>();
            for (int i = 0; i < sequence.Length; i++)
            {
                if (i > 0 && (sequence[i] == sequence[i - 1]))
                {
                    data.Add(sequence[i]);
                }               
            }

            return data.GroupBy(x => x).Max(x => x.Count()) + 1;
        }

 [TestMethod]
        public void TestMethod1()
        {
            // Arrange
            string sequence = "aabbbbccccce";

            // Act
            int containsSameNumbers = sequence.GetLongestSequenceOfSameCharacters();

            // Assert
            Assert.IsTrue(containsSameNumbers == 5);

        }
0

精彩评论

暂无评论...
验证码 换一张
取 消