C# Display repeated letter in string - c#

I'm trying to figure out how to display the repeated letter in a string. For example if the entered string was "red house" it would show that the letter "e" was repeated, then it would be displayed in the label I created. This is a basic program, Here is what I've written thus far. Any help is appreciated.
private void button1_Click(object sender, EventArgs e)
{
string enteredWord = textBox1.Text;
char letter;
for (int index = 0; index < enteredWord.Length; index++)
{
letter = enteredWord[index];
if (letter == enteredWord[index])
{
label1.Text = (letter.ToString());
}
else
{ return;
}

You could also use Linq for that:
var query = from l in enteredWord
group l by l into g
where g.Count() > 1
select new { letter = g.Key, count = g.Count() };
foreach (var item in query)
{
label1.Text += item.letter + " ";
}

This should do what you're looking for:
public static Dictionary<char, int> Count(string input)
{
Dictionary<char, int> d = new Dictionary<char, int>();
foreach (char c in input)
{
if (d.Keys.Contains(c))
d[c]++;
else
d.Add(c, 1);
}
return d;
}
static void Main(string[] args)
{
Dictionary<char, int> d = Count("Red House");
foreach (char c in d.Keys)
{
Console.WriteLine("{0}: {1}", c, d[c]);
}
Console.ReadKey();
}

Could build a HashSet and check each letter. I'm sure there's a more efficient way, but this should work: (untested)
string enteredWord = textBox1.Text;
HashSet<char> letters = new HashSet<char>();
foreach(char c in enteredWord)
{
if (letters.Contains(c))
label1.Text += c.ToString();
else
letters.Add(c);
}
EDIT: I suppose this will print out duplicates of the letters if they appear 3 or more times, but you get the idea.

I would suggest using a List and add the value if you have not encountered it, and update the textbox if you have already encountered it. For a future FYI, you could use a Dictionary if you need to know the exact counts, also.
List<char> charactersThatHaveOccurred = new List<char>();
string enteredWord = textBox1.Text;
foreach(var character in enteredWord)
{
if(charactersThatHaveOccurred.Contains(character ))
label1.Text += character ;
else
charactersThatHaveOccurred.Add(character );
}

The first thing that comes to mind is:
List<char> repeats = enteredWord.Where(c1 => enteredWord.Count(c2 => c1 == c2) > 1).Distinct().ToList();
That will return a List<char> of all the repeated characters. You can grab the first one, or whatever you want.
It may not be optimal in terms of speed, but it's simple.

See other answers for better ways to solve this problem, but I'm trying to see what you were trying to do. (Note, the code below is very inefficient, using a HashSet of already seen characters would be my solution at it.)
Perhaps you're missing an inner for loop? Currently you assign something (enteredword[index]) to letter, and then immediately compare them. So you're comparing each letter to itself.
something like
for (int index = 0; index < enteredWord.Length; index++)
{
letter = enteredWord[index];
for (int index2 = 0; index < enteredWord.Length; index++)
{
if (index != index2 && letter == enteredWord[index2])
{
label1.Text = (letter.ToString());
return;
}
}
}

string s = "red house";
foreach (char c in s)
{
if (s.IndexOf(c) != s.LastIndexOf(c))
{
label1.Text += c.ToString();
}
s.Replace(c.ToString(), string.Empty);
}

Related

Delete part of string value

I want to mix 2 string in 1 randomly using foreach but I don't know how I delete the part I used on the string for the foreach like:
string s = "idontknow";
string sNew = "";
foreach(char ss in s){
s = s + ss;
ss.Delete(s); //don't exist
}
Full code here i'm trying to do:
do
{
if (state == 0)
{
for (int i = 0; random.Next(1, 5) > variable.Length; i++)
{
foreach (char ch in variable)
{
fullString = fullString + ch;
}
}
state++;
}
else if (state == 1)
{
for (int i = 0; random.Next(1, 5) > numbers.Length; i++)
{
foreach (char n in numbers)
{
fullString = fullString + n;
}
}
state--;
}
} while (variable.Length != 0 && numbers.Length != 0);
I'm pretty confident, that in your first code snippet, you are creating an infinite loop, since you are appending the used char back to the string while removing it from the first position.
Regarding your specification to shuffle two stings together, this code sample might do the job:
public static string ShuffleStrings(string s1, string s2){
List<char> charPool = new();
foreach (char c in s1) {
charPool.Add(c);
}
foreach (char c in s2) {
charPool.Add(c);
}
Random rand = new();
char[] output = new char[charPool.Count];
for(int i = 0; i < output.Length; i++) {
int randomIndex = rand.Next(0, charPool.Count);
output[i] = charPool[randomIndex];
charPool.RemoveAt(randomIndex);
}
return new string(output);
}
In case you just want to shuffle one string into another string, just use an empty string as the first or second parameter.
Example:
string shuffled = ShuffleStrings("TEST", "string");
Console.WriteLine(shuffled);
// Output:
// EgsTtSnrTi
There are possibly other solutions, which are much shorter, but I think this code is pretty easy to read and understand.
Concerning the performance, the code above should works both for small stings and large strings.
Since strings are immutable, each modify-operation on any string, e.g. "te" + "st" or "test".Replace("t", ""), will allocate and create a new string in the memory, which is - in a large scale - pretty bad.
For that very reason, I initialized a char array, which will then be filled.
Alternatively, you can use:
using System.Text;
StringBuilder sb = new();
// append each randomly picked char
sb.Append(c);
// Create a string from appended chars
sb.ToString();
And if your question was just how to remove the first char of a string:
string myStr = "Test";
foreach (char c in myStr) {
// do with c whatever you want
myStr = myStr[1..]; // assign a substring exluding first char (start at index 1)
Console.WriteLine($"c = {c}; myStr = {myStr}");
}
// Output:
// c = T; myStr = est
// c = e; myStr = st
// c = s; myStr = t
// c = t; myStr =

Need to display the average letters of each word in a string and display it

Here is what I have so far, it is set up to display the total number of words, which I need to keep, or modify to keep to allow the average number of letters in each word to be displayed, please assist anyone if you can. thank you so much!:
private void btnCheck_Click(object sender, EvenArgs e)
{
string words = tbxArgument.Text.Trim();
MessageBox.Show("Number of Words: " + CountWords(words));
}
private int CountWords(string words)
{
string[] allWords = words.Split(' ');
return allWords.Length;
}
Not sure If this is what you are trying to accomplish.
But this will give you the average length of all the words.
double totalCharacters = 0;
double avgCharacters = 0;
string[] words = new string[] {"Word1","Word2","Word3" } ;
foreach (string tmpString in words)
{
totalCharacters = totalCharacters + tmpString.Length;
}
avgCharacters = totalCharacters/words.Length;
This is a method that only interate over the string, without making splits that require allocate extra memory. Just an optimization, for entertainment:
public static double GetAvgLetters(string text, out int wordsCount)
{
wordsCount = 0;
if (string.IsNullOrWhiteSpace(text))
{
return double.NaN;
}
var lettersCount = 0;
var isLetter = text[0] != ' ';
var readingLetter = isLetter;
for (int i = 0; i < text.Length; i++)
{
isLetter = text[i] != ' ';
if (isLetter != readingLetter)
{
readingLetter = isLetter;
if (readingLetter)
{
lettersCount++;
}
else
{
wordsCount++;
}
}
else if (isLetter)
{
lettersCount++;
}
}
if (isLetter == readingLetter && isLetter)
{
wordsCount++;
}
return lettersCount / (double)wordsCount;
}
I simply iterate checking the changes between blank and not blank (to count words) and, while reading letters, counting letters. At the end, if we are reading letters and last char is a letter, we must add the last word to count.

how do I get my while statement to execute properly in C#?

I am trying to create a program by the name of "Count Vowels" that accepts a phrase from a user and outputs the number of vowels within that phrase.
I used a while statement with a nested if statement that runs through all the vowels, and counts the vowels, so that it can be displayed. When ever I run the program it is not going through my while statement and checking the vowels as intended. Instead it just keeps adding one to my count variable after each iteration.
I am new to C# and tried to understand the issue logically, but am having trouble trying to get my program to execute. If someone could please help me understand what I'm doing wrong I would greatly appreciate it. Below is the code that I am using.
using System;
using static System.Console;
class CountVowels
{
static void Main()
{
string phrase;
int count=0;
int i=0;
Console.WriteLine("please enter a phrase of your choice");
phrase=Console.ReadLine();
while(i < phrase.Length)
{
if(phrase[i]=='a' ||
phrase[i]=='A' ||
phrase[i]=='e' ||
phrase[i]=='E' ||
phrase[i]=='i' ||
phrase[i]=='I' ||
phrase[i]=='o' ||
phrase[i]=='O' ||
phrase[i]=='u' ||
phrase[i]=='U')
{
count++;
}
{
i++;
}
Console.WriteLine("The number of vowels in your phrase is {0}",count);
Console.ReadLine();
}
}
}
A while loop is overkill for this but I am assuming you have a requirement for this? How about a little refactor to clean it up? You will need LINQ for this example.
using System.Linq;
string phrase;
int count=0;
int i=0;
Console.WriteLine("please enter a phrase of your choice");
phrase=Console.ReadLine();
while(i < phrase.Length)
{
string[] vowels = {"a", "e", "i", "o", "u"};
var characterValue = phrase[i].ToString().ToLower();
if(vowels.Contains(characterValue))
{
count++;
}
i++;
}
Console.WriteLine("The number of vowels in your phrase is {0}",count);
Console.ReadLine();
Or mush shorter still using LINQ but no loop:
using System.Linq;
Console.WriteLine("please enter a phrase of your choice");
var phrase=Console.ReadLine();
var count = phrase.Count(x => "aeiou".Contains(char.ToLower(x)));
Console.WriteLine("The number of vowels in your phrase is {0}",count);
Console.ReadLine();
Fixing your problem
var phrase = "asd";
var vowels = "aeiou";
int i = 0, count = 0;
while (i < phrase.Length)
{
if (vowels.Contains(char.ToLower(phrase[i])))
count++;
i++;
}
for loop
for (int i = 0; i < phrase.Length; i++)
if (vowels.Contains(char.ToLower(phrase[i])))
count++;
foreach
foreach (var c in phrase)
if (vowels.Contains(char.ToLower(c)))
count++;
foreach C#9 pattern matching
foreach (var c in phrase.ToLower())
if (c is 'a' or 'e' or 'o' or 'u')
count++;
Linq 1
count = phrase.Count(c => vowels.Contains(char.ToLower(c)));
Linq 2
count = phrase.ToLower().Count(c => vowels.Contains(c));
Regex
var count = Regex.Matches(phrase, "[aeiou]",RegexOptions.IgnoreCase).Count;
Efficient with a hashset
var hash = new HashSet<char>("aeiou".ToCharArray());
var count = phrase.ToLower().Count(x => hash.Contains(x));
Note this is not really an answer, it was more showing option.

C# counting characters

I am trying to complete a brain teaser which has a bug and I cant find it. Just wondering if anyone knows the answer. My goal is to return the character that appears most often.
public string solution(string S)
{
int[] occurrences = new int[26];
foreach (char ch in S)
{
occurrences[ch - 'a']++;
}
char best_char = 'a';
int best_res = 0;
for (int i = 1; i < 26; i++)
{
if (occurrences[i] >= best_res)
{
best_char = (char)('a' + i);
best_res = occurrences[i];
}
}
return best_char.ToString();
}
You have small mistake. Your index should start from 0, not 1
for (int i = 0; i < 26; i++)
{
if (occurrences[i] >= best_res)
{
best_char = (char)('a' + i);
best_res = occurrences[i];
}
}
Another and safer version is that
public string Solution(string text)
{
string strResponse = string.Empty;
if (!string.IsNullOrEmpty(text))
{
List<KeyValuePair<char, int>> occurance = text.GroupBy(ch => ch)
.Where(grp => char.IsLetter(grp.Key))
.Select(grp => new KeyValuePair<char, int>(grp.Key, grp.Count()))
.OrderByDescending(c => c.Value)
.ToList();
if (occurance.Any())
strResponse = occurance.First().Key.ToString();
}
return strResponse;
}
There could actually be more than one character with the maximum number of occurrences, so:
private static Char[] GetMostFrequentChars(String text)
{
Dictionary<Char,Int32> rank = new Dictionary<Char,Int32>();
foreach (Char c in text.Where(c => !char.IsWhiteSpace(c)))
{
if (rank.ContainsKey(c))
rank[c]++;
else
rank.Add(c, 1);
}
return rank.Where(r => r.Value == rank.Values.Max()).Select(x => x.Key).ToArray();
}
If you don't care about special characters (like spaces), you could do this with LINQ:
public static GetMostFrequentCharacter(string value)
{
return value
.GroupBy(o => o)
.OrderByDescending(o => o.Count())
.First()
.Key
.ToString()
}
There are at least 2 problems:
as #Adem Çatamak says, for loop should start at index 0
ch - 'a' will throw an exception if the string contains any other character than a-z lowercase,
public static string solution(string S)
{
var charDict = new Dictionary<char, int>();
foreach (char c in S.Where(c => !char.IsWhiteSpace(c)))
{
if(!charDict.TryGetValue(c, out int count))
{
charDict[c] = 1;
}
charDict[c]++;
}
return charDict.OrderByDescending(kvp => kvp.Value).First().Key.ToString();
}
Using a dictionary and LINQ is going to be better I think. Don't just copy this code and paste it into what ever homework or class this is for, use it to learn otherwise its a waste of my time and yours really

Check if string is anagram of palindrome

My question is:
How do you check if a given string is the anagram of a palindrome?
I found some solutions in Python on the internet, but I'm not sure how can I check this yet. I was thinking about converting the strig to a char [], and then get the HashCode for every character, but I'm stuck.
If you're not interested in the palindrome or anagram being a real word then I think you can reframe the problem as check if a given string has no more than one character that appears an uneven number of times. This is on the basis that only the middle character can possibly occur an odd number of times. As long as that is satisfied then you can form a palindrome from the string.
To do that you can use Linq. Something like this perhaps:
private static bool IsPalindromeAnagram(string test)
{
var charCount = test.GroupBy(c => c, (c, i) => new
{
character = c,
count = i.Count()
});
return charCount.Count(c => c.count % 2 == 1) <= 1;
}
Saved char in a dictionary as key, then check if more than one key is odd. this way also have all unique char ready to make anagram.
var length = s.Length;
if (length == 0) return false;
var dic = new Dictionary<char, int>();
for (var i = 0; i < length; i++)
{
if (dic.ContainsKey(s[i]))
{
dic[s[i]]++;
continue;
}
dic.Add(s[i], 1);
}
int odd = 0;
foreach (var pv in dic)
{
if (odd > 1) return false;
if (pv.Value % 2 == 0)
{
continue;
}
odd++;
}

Categories

Resources