Testing for repeated characters in a string

后端 未结 11 697
闹比i
闹比i 2020-12-16 22:55

I\'m doing some work with strings, and I have a scenario where I need to determine if a string (usually a small one < 10 characters) contains repeated characters.

相关标签:
11条回答
  • 2020-12-16 23:30

    I started looking for some info on the net and I got to the following solution.

    string input = "aaaaabbcbbbcccddefgg";
            char[] chars = input.ToCharArray();
            Dictionary<char, int> dictionary = new Dictionary<char,int>();
    
            foreach (char c in chars)
            {
                if (!dictionary.ContainsKey(c))
                {
                    dictionary[c] = 1; //
                }
                else
                {
                    dictionary[c]++;
                }
            }
    
            foreach (KeyValuePair<char, int> combo in dictionary)
            {
                if (combo.Value > 1) //If the vale of the key is greater than 1 it means the letter is repeated
                {
                    Console.WriteLine("Letter " + combo.Key + " " + "is repeated " + combo.Value.ToString() + " times");
                }
    
            }
    

    I hope it helps, I had a job interview in which the interviewer asked me to solve this and I understand it is a common question.

    0 讨论(0)
  • 2020-12-16 23:34
    /(.).*\1/
    

    (or whatever the equivalent is in your regex library's syntax)

    Not the most efficient, since it will probably backtrack to every character in the string and then scan forward again. And I don't usually advocate regular expressions. But if you want brevity...

    0 讨论(0)
  • 2020-12-16 23:34

    When there is no order to work on you could use a dictionary to keep the counts:

    String input = "AABCD";
    var result = new Dictionary<Char, int>(26);
    var chars = input.ToCharArray();
    foreach (var c in chars)
    {
        if (!result.ContainsKey(c))
        {
            result[c] = 0; // initialize the counter in the result
        }
        result[c]++;
    }
    
    foreach (var charCombo in result)
    {
        Console.WriteLine("{0}: {1}",charCombo.Key, charCombo.Value);   
    }
    
    0 讨论(0)
  • 2020-12-16 23:35

    If the string is sorted, you could just remember each character in turn and check to make sure the next character is never identical to the last character.

    Other than that, for strings under ten characters, just testing each character against all the rest is probably as fast or faster than most other things. A bit vector, as suggested by another commenter, may be faster (helps if you have a small set of legal characters.)

    Bonus: here's a slick LINQ solution to implement Jon's functionality:

    int longestRun =
        s.Select((c, i) => s.Substring(i).TakeWhile(x => x == c).Count()).Max();
    

    So, OK, it's not very fast! You got a problem with that?!

    :-)

    0 讨论(0)
  • 2020-12-16 23:35

    I think the easiest way to achieve that is to use this simple regex

    bool foundMatch = false;
    foundMatch = Regex.IsMatch(yourString, @"(\w)\1");
    

    If you need more information about the match (start, length etc)

            Match match = null;
        string testString = "ABCDE AABCD";
        match = Regex.Match(testString, @"(\w)\1+?");
        if (match.Success)
        {
            string matchText = match.Value; // AA
            int matchIndnex = match.Index;  // 6
            int matchLength = match.Length; // 2
        }
    
    0 讨论(0)
  • 2020-12-16 23:36

    Since you're using 3.5, you could do this in one LINQ query:

    var results = stringInput
      .ToCharArray() // not actually needed, I've left it here to show what's actually happening
      .GroupBy(c=>c)
      .Where(g=>g.Count()>1)
      .Select(g=>new {Letter=g.First(),Count=g.Count()})
    ;
    

    For each character that appears more than once in the input, this will give you the character and the count of occurances.

    0 讨论(0)
提交回复
热议问题