Reputation: 125
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
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 String
s 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
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
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
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