Reputation: 21
I am not very experienced with C# and have got a task to develop a simple program that can take two parameters; one string and one integer. The string is to be returned, and the integer is supposed to define the max number of each specific character that is returned in the string, i.e.:
input: "aaabbbbc", "2" output: aabbc
input: "acc", "1" output: ac
I've tried looking at different collections like IEnumerator
to help make the code easier to write, but as I'm not very experienced I can't sort out how to utilize them.
This is the code that I've written so far:
public static string TwoParameters()
{
Console.Write("Write some characters (i.e. 'cccaabbb'): ");
string myString = Console.ReadLine();
return myString;
Console.Write("Write a number - ");
int max = Convert.ToInt32(Console.Read());
}
public static void Counter(string myString, int max)
{
string myString = TwoParameters(myString);
foreach (char a in myString)
{
var occurences = myString.Count(x => x == 'a');
if (occurences > max)
max = occurences;
}
}
Errors I get when running:
CS0136: Local or parameter 'myString' cannot be declared in scope because of enclosing local scope.
CS1501: No overload for method 'TwoParameters' takes 1 arg.
CS1061: 'string' does not contain a definition for count.
CS0165: Use of unassigned local variable 'myString'.
CS7036: There is no argument given that corresponds to the required formal parameter 'myString' of 'Program.Counter(string, int)'
Any kind of pointers to what I'm doing wrong, suggestions to how I can improve my code and/or finish it up for the program to make the output will be hugely appreciated.
Upvotes: 1
Views: 287
Reputation: 51643
Pointers to what you are doing wrong:
TwoParameters
function has unreachable codeUsing Linq is probably somewhat overkill for your level of knowledge. This is a simpler Version of Oliver's answer - respecting order of letters as well:
public static void Main()
{
var input = "abbaaabcbcccd";
var max = 2;
// stores count of characters that we added already
var occurences = new Dictionary<char,int>();
var sb = new StringBuilder();
foreach (var c in input)
{
// add with a count of 0 if not yet encountered
if (!occurences.ContainsKey(c))
{
// if you want only "consecutive" letters not repeated over max:
// uncomment the following line that resets your dict - you might
// want to use a single integer and character instead in that case
// occurences.Clear(); // better use a single int-counter instead
occurences[c] = 0;
}
// add character if less then max occurences
if (occurences[c] < max)
{
sb.Append(c);
occurences[c]+=1;
}
}
Console.WriteLine(sb.ToString());
}
Output:
abbaccd
Upvotes: 0
Reputation: 45101
This function would also respect the order within the string, so aabcabc, 2
would result into aabcbc
:
static string ReturnMaxOccurences(string source, int count)
{
return source.Aggregate(new Accumulator(), (acc, c) =>
{
acc.Histogram.TryGetValue(c, out int charCount);
if (charCount < count)
acc.Result.Append(c);
acc.Histogram[c] = ++charCount;
return acc;
}, acc => acc.Result.ToString());
}
But you need also this little helper class:
public class Accumulator
{
public Dictionary<char, int> Histogram { get; } = new Dictionary<char, int>();
public StringBuilder Result { get; } = new StringBuilder();
}
This method iterates the whole string and save within a histogram the occurences of each character. If the value is lower than the desired max value it will be added to the result string, otherwise it simply steps over the character and continues with the next.
Upvotes: 1
Reputation: 131374
A string can be treated as an IEnumerable<char>
. You can use LINQ to first group the characters then take only 2 from each group, eg :
var input="aaabbbbc";
var max=2;
var chars=input.GroupBy(c=>c)
.SelectMany(g=>g.Take(2))
.ToArray();
var result=new String(chars);
This produces
aabbc
This query groups the characters together with GroupBy
and then takes only max
from each group with Take
. SelectMany
flattens all the IEnumerable<char>
returned from Take
into a single IEnumerable<char>
that can be used to create a string
Upvotes: 3