Alan Auckland
Alan Auckland

Reputation: 125

Allow only a set number of characters in a string

I am working on a function that will evaluate a string and only allow x instances of each character.

For example, you can have 2 allowed character so

aaaabbbbbcddddd

would be evaluated to

aabbcdd

So far I have written this:

public static string removeDuplicateCharacters(String text, int allowedDuplicates)
{
    string seen="";
    foreach (char c in text){

       if(!seen.Contains(c)){
           seen = seen + c;
       } else if(seen.Contains(c)){

             // while the sting contains < allowedDuplicates
            // add c
           }
       }
    return seen; 
 }      

I can't at the moment work out how create a while condition that is also going to count through my seen string for the number of current instances of the char currently being evaluated.

Upvotes: 0

Views: 749

Answers (4)

Frank J
Frank J

Reputation: 1696

Easy solution with a Dictionary to keep track of the character counts:

public static string removeDuplicateCharacters(String text, int allowedDuplicates)
{
    string seen="";
    Dictionary<char, int> charCount = new   Dictionary<char, int>();
    foreach (char c in text)
    {
        if(!charCount.ContainsKey(c))
        {
            seen += c;
            charCount.Add(c, 1);
        }
        else if(charCount[c] < allowedDuplicates)
        {
            charCount[c] += 1;
            seen += c;
        }
        else
        {
            //Reached max, do nothing
        }
    }
    return seen; 
 }      

This is your base and you can make it as nice and fancy as you want from here.

E.g.: I would suggest a StringBuilder if the strings can get long as it less taxing on memory since you don't have to allocate permanently new Strings when doing += on them.

public static string removeDuplicateCharacters(String text, int allowedDuplicates)
{
    StringBuilder seen = new StringBuilder();

    Dictionary<char, int> charCount = new   Dictionary<char, int>();
    foreach (char c in text)
    {
        if(!charCount.ContainsKey(c))
        {
            seen.Append(c);
            charCount.Add(c, 1);
        }
        else if(charCount[c] < allowedDuplicates)
        {
            charCount[c] += 1;
            seen.Append(c);
        }
        else
        {
            //Reached max, do nothing
        }
    }
    return seen.ToString(); 
 }     

Another thing would be if you want lower and uppercase to be treated the same. Then I would change the test to upper or lower case, but if you want to keep the casing of the original character in the return string you could do the following.

public static string removeDuplicateCharacters(String text, int allowedDuplicates)
{
    StringBuilder seen = new StringBuilder();

    Dictionary<char, int> charCount = new   Dictionary<char, int>();
    foreach (char c in text)
    {
        char upperCase = c.ToUpper();
        if(!charCount.ContainsKey(upperCase))
        {
            seen.Append(c);
            charCount.Add(upperCase , 1);
        }
        else if(charCount[upperCase] < allowedDuplicates)
        {
            charCount[upperCase ] += 1;
            seen.Append(c);
        }
        else
        {
            //Reached max, do nothing
        }
    }
    return seen.ToString(); 
 }      

Just customize from here on.

Upvotes: 2

shawnt00
shawnt00

Reputation: 17915

This is possibly a more appropriate approach for a beginner student. It doesn't require the use of arrays or dictionaries and sticks to simple algorithmic primitives. (I'm not objecting to their use, I just have a hunch that this is a student exercise and might even be one designed to motivate their introduction.)

public static string removeDuplicateCharacters(String text, int allowedDuplicates)
{
    string seen= "";
    int count = 0;
    foreach (char c in text) {
        count = 0;
        foreach (char c2 in seen) {
            if (c2 == c) count++;
        }
        if (count < allowedDuplicates) {
            seen = seen + c;
        }
    }
    return seen; 
}      

Upvotes: 0

Stephen Kennedy
Stephen Kennedy

Reputation: 21548

Here we keep track of the seen characters and how many times we have seen them by using a Dictionary, and we assemble the output string with a StringBuilder:

        public static string RemoveDuplicateCharacters(string text, int allowedDuplicates)
        {
            var seen = new Dictionary<char, int>();
            var sb = new StringBuilder();

            foreach (char c in text)
            {
                int count;
                if (seen.TryGetValue(c, out count))
                {
                    count++;
                } else
                {
                    count = 1;
                }

                seen[c] = count;

                if (count <= allowedDuplicates)
                    sb.Append(c);
            }

            return sb.ToString();
        }   

Test:

Console.WriteLine(RemoveDuplicateCharacters("aaaabbbbbcddddda", 3));

Output:

aaabbbcddd

Upvotes: 0

thumbmunkeys
thumbmunkeys

Reputation: 20764

Use a dictionary to keep track of character count

    public static string removeDuplicateCharacters(string text, int allowedDuplicates)
    {
        var frequency = new Dictionary<char, int>();
        StringBuilder output = new StringBuilder();
        foreach (char c in text)
        {
            int count = 1;
            if (frequency.ContainsKey(c))
                count = ++frequency[c];
            else
                frequency.Add(c, count);

            if (count <= allowedDuplicates)
                output.Append(c);
        }
        return output.ToString();
    }

Upvotes: 0

Related Questions