C# Count Vowels - c#

I am learning to program C# and I am trying to count the vowels. I am getting the program to loop through the sentence, but instead of returning vowel count, it is just returning the length of the string. Any help would be greatly appreciated.
static void Main()
{
int total = 0;
Console.WriteLine("Enter a Sentence");
string sentence = Console.ReadLine().ToLower();
for (int i = 0; i < sentence.Length; i++)
{
if (sentence.Contains("a") || sentence.Contains("e") || sentence.Contains("i") || sentence.Contains("o") || sentence.Contains("u"))
{
total++;
}
}
Console.WriteLine("Your total number of vowels is: {0}", total);
Console.ReadLine();
}

Right now, you're checking whether the sentence as a whole contains any vowels, once for each character. You need to instead check the individual characters.
for (int i = 0; i < sentence.Length; i++)
{
if (sentence[i] == 'a' || sentence[i] == 'e' || sentence[i] == 'i' || sentence[i] == 'o' || sentence[i] == 'u')
{
total++;
}
}
That being said, you can simplify this quite a bit:
static void Main()
{
int total = 0;
// Build a list of vowels up front:
var vowels = new HashSet<char> { 'a', 'e', 'i', 'o', 'u' };
Console.WriteLine("Enter a Sentence");
string sentence = Console.ReadLine().ToLower();
for (int i = 0; i < sentence.Length; i++)
{
if (vowels.Contains(sentence[i]))
{
total++;
}
}
Console.WriteLine("Your total number of vowels is: {0}", total);
Console.ReadLine();
}
You can simplify it further if you want to use LINQ:
static void Main()
{
// Build a list of vowels up front:
var vowels = new HashSet<char> { 'a', 'e', 'i', 'o', 'u' };
Console.WriteLine("Enter a Sentence");
string sentence = Console.ReadLine().ToLower();
int total = sentence.Count(c => vowels.Contains(c));
Console.WriteLine("Your total number of vowels is: {0}", total);
Console.ReadLine();
}

Since Reed has answered your question, I will offer you another way to implement this. You can eliminate your loop by using LINQ and lambda expressions:
string sentence = "The quick brown fox jumps over the lazy dog.";
int vowelCount = sentence.Count(c => "aeiou".Contains(Char.ToLower(c)));
If you don't understand this bit of code, I'd highly recommend looking up LINQ and Lambda Expressions in C#. There are many instances that you can make your code more concise by eliminating loops in this fashion.
In essence, this code is saying "count every character in the sentence that is contained within the string "aeiou". "

That's because your if statement is always true, you need to compare the character at sentence[i], and see if it is a vowel, instead of seeing if the sentence contains a vowel.

Or with linq.
static void Main()
{
int total = 0;
Console.WriteLine("Enter a Sentence");
string sentence = Console.ReadLine().ToLower();
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
total = sentence.Count(x => vowels.Contains(x));
Console.WriteLine("Your total number of vowels is: {0}", total);
Console.ReadLine();
}

You were checking to see if your whole sentence contained vowels for every iteration of your loop, which is why your total was simply the number of characters in your sentence string.
foreach(char ch in sentence.ToLower())
if("aeiou".Contains(ch))
total++;
Better yet use a regular expression. edit You'd only want to use a regex for something a little more complex than matching vowels.
using System.Text.RegularExpressions;
...
int total = Regex.Matches(sentence, #"[AEIOUaeiou]").Count;
EDIT Just for completeness the fastest/most efficient (if you were to do this on a ~million strings) solution. If performance wasn't a concern I'd use Linq for its brevity.
public static HashSet<char> SVowels = new HashSet<char>{'a', 'e', 'i', 'o', 'u'};
public static int VowelsFor(string s) {
int total = 0;
foreach(char c in s)
if(SVowels.Contains(c))
total++;
return total;
}

There are many ways to skin a cat :-) In programming a little lateral thinking can be useful...
total += sentence.Length - sentence.Replace("a", "").Length;
total += sentence.Length - sentence.Replace("e", "").Length;
total += sentence.Length - sentence.Replace("i", "").Length;
total += sentence.Length - sentence.Replace("o", "").Length;
total += sentence.Length - sentence.Replace("u", "").Length;
You could, for example, try removing a vowel from the sentence and looking if the sentence is smaller without the vowel, and by how much.

int cnt = 0;
for (char c in sentence.ToLower())
if ("aeiou".Contains(c))
cnt++;
return cnt;

Maybe too advanced for a starter, but this is the way you do that in C#:
var vowels = new[] {'a','e','i','o','u'};
Console.WriteLine("Enter a Sentence");
var sentence = Console.ReadLine().ToLower();
var vowelcount = sentence.Count(x => vowels.Contains(x));
Console.WriteLine("Your total number of vowels is: {0}", vowelcount);
Console.ReadLine();

This is how I would handle this.
var sentence = "Hello my good friend";
var sb = sentence.ToLower().ToCharArray();
var count = 0;
foreach (var character in sb)
{
if (character.Equals('a') || character.Equals('e') || character.Equals('i') || character.Equals('o') ||
character.Equals('u'))
{
count++;
}
}

You can also do this with switch statement
var total = 0;
var sentence = "Hello, I'm Chris";
foreach (char c in sentence.ToLower())
{
switch (c)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
total++;
break;
default: continue;
}
}
Console.WriteLine(total.ToString());

TMTOWTDI (Tim Toadie as they say: There's More Than One Way To Do It).
How about
static char[] vowels = "AEIOUaeiou".ToCharArray() ;
public int VowelsInString( string s )
{
int n = 0 ;
for ( int i = 0 ; (i=s.IndexOfAny(vowels,i)) >= 0 ; )
{
++n ;
}
return n;
}
Or (another regular expression approach)
static readonly Regex rxVowels = new Regex( #"[^AEIOU]+" , RegexOptions.IgnoreCase ) ;
public int VowelCount( string s )
{
int n = rxVowels.Replace(s,"").Length ;
return n ;
}
The most straightforward is probably the fastest, as well:
public int VowelCount( string s )
{
int n = 0 ;
for ( int i = 0 ; i < s.Length ; +i )
{
switch( s[i] )
{
case 'A' : case 'a' :
case 'E' : case 'e' :
case 'I' : case 'i' :
case 'O' : case 'o' :
case 'U' : case 'u' :
++n ;
break ;
}
}
return n ;
}

static void Main(string[] args)
{
Char[] ch;
Console.WriteLine("Create a sentence");
String letters = Console.ReadLine().Replace(" ", "").ToUpper();
ch = letters.ToCharArray();
int vowelCounter = 0;
int consonantCounter = 0;
for(int x = 0; x < letters.Length; x++)
{
if(ch[x].ToString().Equals("A") || ch[x].ToString().Equals("E") || ch[x].ToString().Equals("I") || ch[x].ToString().Equals("O") || ch[x].ToString().Equals("U"))
{
vowelCounter++;
}
else
{
consonantCounter ++;
}
}
System.Console.WriteLine("Vowels counted : " + vowelCounter);
System.Console.WriteLine("Consonants counted : " + consonantCounter);

Application to count vowels and consonants letters in a sentence.
This is another solution with less lines of code with understanding the idea of using loops and nested loops with char arrays.
An application interface with control names:
namespace Program8_4
{
public partial class Form1 : Form
{
// declare the counter variables in field
int iNumberOfVowels = 0;
int iNumberOfConsonants = 0;
public Form1()
{
InitializeComponent();
}
private void btnFind_Click(object sender, EventArgs e)
{
// call the methods in this event
GetVowels(txtStringInput.Text);
GetConsonants(txtStringInput.Text);
// show the result in a label
lblOutput.Text = "The number of vowels : " + iNumberOfVowels.ToString()+ Environment.NewLine+
"The number of consonants : " + iNumberOfConsonants.ToString();
// assign zero the counters to not add the previous number to new number, and start counting from zero again
iNumberOfVowels = 0;
iNumberOfConsonants = 0;
}
private int GetConsonants(string strFindConsonants)
{
// Declare char array to contain consonants letters
char[] chrConsonants = { 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'X',
'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'x' };
// loop to get each letter from sentence
foreach (char Consonants in strFindConsonants)
{
// another nested loop to compare each letter with all letters contains in chrConsonants array
for (int index= 0; index<chrConsonants.Length;index++)
{
// compare each letter with each element in charConsonants array
if (Consonants == chrConsonants[index])
{
// If it is true add one to the counter iNumberOfConsonants
iNumberOfConsonants++;
}
}
}
// return the value of iNumberOfConsonants
return iNumberOfConsonants;
}
private int GetVowels(string strFindVowels)
{
// Declare char array to contain vowels letters
char[] chrVowels = { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O','U' };
// loop to get each letter from sentence
foreach (char Vowels in strFindVowels)
{
// another nested loop to compare each letter with all letters contains in chrVowels array
for (int index = 0; index< chrVowels.Length; index++)
{
// compare each letter with each element in chrVowels array
if (Vowels == chrVowels[index])
{
// If it is true add one to the counter iNumberOfVowels
iNumberOfVowels = iNumberOfVowels+1;
}
}
}
// return the value of iNumberOfVowels
return iNumberOfVowels;
}

We can use regular expression to match vowels in a sentence.
Regex.Matches() function will return an array with all occurrence of vowel.
Then we can use the count property to find the count of vowels.
Regular expression to match vowels in a string: [aeiouAEIOU]+
Below is the working code snippet:
public static void Main()
{
string pattern = #"[aeiouAEIOU]+";
Regex rgx = new Regex(pattern);
string sentence = "Who writes these notes?";
Console.WriteLine(rgx.Matches(sentence).Count);
}

// Using two loops.
char[] vowels= new char[]{'a', 'e', 'i', 'o', 'u',
'A', 'E', 'I', 'O', 'U'};
string myWord= "This is a beautiful word.";
int numVowels = 0;
foreach(char c in myWord.ToCharArray())
{
foreach(char c2 in vowels)
{
if(c == c2) numVowels++;
}
}
Console.WriteLine($"{numVowels} vowels in: {myWord}");

We check each subsequent letter of the expression if it is equal to the vowels in the array
class Program
{
private static void Main(string[] args)
{
string random = Console.ReadLine();
string toLower = random.ToLower();
char []isVowels = { 'a','e','i','o','u','y' };
byte count = 0;
for (int i = 0; i < toLower.Length; i++)
{
for (int j = 0; j < isVowels.Length; j++)
{
if (toLower[i]==isVowels[j])
{
count++;
}
}
}
Console.WriteLine(count);
}
}

`public static void Main()
{
Console.WriteLine("Enter a Sentence");
string sentence = Console.ReadLine().ToLower();
string voval="aeiou";
int cnt=0;
foreach(char ch in sentence)
{
if(voval.Contains(ch.ToString()))
{
cnt++;
}
}
Console.WriteLine(cnt);
}`

Here was how I did it:
char[] englishWord = new Char[5] { 'a', 'e', 'i', 'o', 'u' };
string input = Console.ReadLine();
input.ToLower();
int count = 0;
for (int i = 0; i < input.Length; i++)
{
for (int j = 0; j < englishWord.Length; j++)
{
if (input[i] == englishWord[j])
{
count++;
break;
}
}
}
Console.WriteLine(count);

this is a nice generic way to count vowels and from here you can do all sorts of things. count the vowels, return a sorted list, etc.
public static int VowelCount(String vowelName) {
int counter = 0;
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
for (int index = 0; index < vowelName.Length; index++)
{
if (vowels.Contains(vowelName[index]))
{
counter++;
}
}
return counter;
}

void main()
{
int x=0;
char ch;
printf("enter a statement:");
while((ch=getche())='\r')
{
if(ch=='a'||ch=='e'||ch=='i'||ch=='o'||ch=='u')
x++;
}
printf("total vowels=");
getch();
}

Related

Unity random characters in string

How do I repeat generating a random char? I want to make a glitched text effect so I set:
textbox.text = st[Random.Range(0, st.Length)];
in my update method. I do however only get one character out of this line - how would I repeat this process in a string with the length of 5? What I am trying to achieve is to randomly generate 5 characters over and over again. There must be a better way than this:
randomChar + randomChar + randomChar + randomChar + randomChar
Thank you in advance!
Could use something similar:
public static readonly char[] CHARS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
static void Main(string[] args)
{
static string GenerateGlitchedString(uint wordCount,uint wordslength)
{
string glitchedString = "";
for (int i = 0; i < wordCount; i++)
{
for (int j = 0; j < wordslength; j++)
{
Random rnd = new Random();
glitchedString += CHARS[rnd.Next(CHARS.Length)];
}
glitchedString += " "; //Add spaces
}
return glitchedString;
}
string output = GenerateGlitchedString(5, 5);
Console.WriteLine(output);
}
You can use Linq to generate any number of random characters from an enumerable:
int howManyChars = 5;
var newString = String.Join("", Enumerable.Range(0, howManyChars).Select(k => st[Random.Range(0, st.Length)]));
textbox.text = newString;
If you want completely glitchy strings, go the way of Mojibake. Take a string, convert it to one encoding and then decode it differently. Most programmers end up familiar with this kind of glitch eventually. For example this code:
const string startWith = "Now is the time for all good men to come to the aid of the party";
var asBytes = Encoding.UTF8.GetBytes(startWith);
var glitched = Encoding.Unicode.GetString(asBytes);
Debug.WriteLine(glitched);
consistently results in:
潎⁷獩琠敨琠浩⁥潦⁲污潧摯洠湥琠潣敭琠桴⁥楡⁤景琠敨瀠牡祴
But, if you just want some text with some random glitches, how about something like this. It uses a set of characters that should be glitched in, a count of how many glitches there should be in a string (based on the string length) and then randomly inserts glitches:
private static Random _rand = new Random();
private const string GlitchChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%&";
public static string GlitchAString(string s)
{
var glitchCount = s.Length / 5;
var buffer = s.ToCharArray();
for (var i = 0; i < glitchCount; ++i)
{
var position = _rand.Next(s.Length);
buffer[position] = GlitchChars[_rand.Next(GlitchChars.Length)];
}
var result = new string(buffer);
Debug.WriteLine(result);
return result;
}
The first two times I ran this (with that same Now is the time... string), I got:
Original String:
Now is the time for all good men to come to the aid of the party
First Two Results:
LowmiW HhZ7time for all good mea to comX to ths aid oV the p1ray
Now is fhO P!me forjall gKod men to #ome to the a#d of F5e Nawty
The algorithm is, to some extent, tunable. You can have more or fewer glitches. You can change the set of glitch chars - whatever you'd like.

String Get/Update Numeric Value After Specific Character

I have a console app with alphanumeric input. I want to extract/update the numeric value from specific position of a character. All characters are unique. No the same characters in an input. For example in my program I want to extract/update numeric value from specific char R. R is unique. It's always 1 and followed by numbers. Please help. Here's my program.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp16
{
class Program
{
static void Main(string[] args)
{
var input = "JPR5AU75";
Console.WriteLine(GetNumericValue(input,'R'));
//Expected output=5
Console.WriteLine(UpdateNumericValue(input, 'R', 7));
//Expected output=JPR7AU75
input = "PR2.9AU75";
Console.WriteLine(GetNumericValue(input, 'R'));
//Expected output=2.9
Console.WriteLine(UpdateNumericValue(input, 'R', 3.5));
//Expected output=PR3.5AU75
input = "PKLR555AU75";
Console.WriteLine(GetNumericValue(input, 'R'));
//Expected output=555
Console.WriteLine(UpdateNumericValue(input, 'R', 765));
//Expected output=PKLR765AU75
Console.ReadLine();
}
static string GetNumericValue(string input, char c)
{
var value = "Get numeric value from position of charcter c";
return value;
}
static string UpdateNumericValue(string input, char c, double newVal)
{
var value = "Replace numeric value from input where character position starts with c";
return value;
}
}
}
Here is the sample code for your methods. Running Code here
Time Complexity will be O(N) in worst case, N -> length of the input
static string GetNumericValue(string input, char c)
{
int charIndex = input.IndexOf(c);
StringBuilder sb = new StringBuilder();
int decimalCount = 0;
for (int i = charIndex + 1; i < input.Length; i++)
{
if (char.IsNumber(input[i]) || input[i] == '.')
{
if (input[i] == '.') decimalCount++;
if (decimalCount > 1) break;
sb.Append(input[i]);
}
else break;
}
return sb.ToString();
}
static string UpdateNumericValue(string input, char c, double newVal)
{
var numericValue = GetNumericValue(input, c);
return input.Replace(c + numericValue, c + newVal.ToString());
}
You can use Regular Expressions to extract the desired part :
$#"{c}([-+]?[0-9]+\.?[0-9]*)" Will match the character c and capture in a groupe 0 or 1 sign, followed by 1 or more digits, followed by 0 or 1 dot, followed by 0 or more digits
using System.Text.RegularExpressions;
// returns an empty string if no match
static string GetNumericValue(string input, char c)
{
Regex regex = new Regex($#"{Regex.Escape(c.ToString())}([-+]?\d+\.?\d*)");
var match = regex.Match(input);
if (match.Success)
{
return match.Groups[1].Value;
}
return string.Empty;
}
The replacement can use the value get above and will replace the first matched string with the expected number :
// returns the unchanged input if no match
static string UpdateNumericValue(string input, char c, double newVal)
{
var needle = $"{c}{GetNumericValue(input, c)}"; // get the numeric value prepended with the searched character
if (!string.IsNullOrEmpty(needle))
{
var regex = new Regex(Regex.Escape(needle));
return regex.Replace(input, $"{c}{newVal.ToString()}", 1); // replace first occurence
}
return input;
}
var input = "JPR5AU75";
Console.WriteLine(GetNumericValue(input,'R'));
//Expected output=5
Console.WriteLine(UpdateNumericValue(input, 'R', 7));
//Expected output=JPR7AU75
input = "PR2.9AU75";
Console.WriteLine(GetNumericValue(input, 'R'));
//Expected output=2.9
Console.WriteLine(UpdateNumericValue(input, 'R', 3.5));
//Expected output=PR3.5AU75
input = "PKLR555AU75";
Console.WriteLine(GetNumericValue(input, 'R'));
//Expected output=555
Console.WriteLine(UpdateNumericValue(input, 'R', 765));
//Expected output=PKLR765AU75
//Console.ReadLine();
input = "ABCDEF";
Console.WriteLine(GetNumericValue(input, 'C'));
//Expected output=""
Console.WriteLine(UpdateNumericValue(input, 'C', 42));
//Expected output="ABCDEF"
input = "ABCDEF";
Console.WriteLine(GetNumericValue(input, 'F'));
//Expected output=""
Console.WriteLine(UpdateNumericValue(input, 'F', 42));
//Expected output="ABCDEF"
input = "666ABC666ABC555";
Console.WriteLine(GetNumericValue(input, 'C'));
//Expected output="666"
Console.WriteLine(UpdateNumericValue(input, 'C', 42));
//Expected output="666ABC42ABC555"
Try it yourself
I have an easier to understand solution:
static string GetNumericValue(string input, char c)
{
int indexStartOfValue = input.IndexOf(c) + 1;
int valueLength = 0;
while(Char.IsDigit(input[indexStartOfValue + valueLength]) || input[indexStartOfValue + valueLength] == '.')
valueLength ++;
return input.Substring(indexStartOfValue, valueLength);
}
static string UpdateNumericValue(string input, char c, double newVal)
{
var numericValue = GetNumericValue(input, c);
return input.Replace(c + numericValue, c + newVal.ToString());
}

Display the the total amount of the same vowel

I am trying to display the total number of the same vowels when I input a word. For example : cheesecake.
Total vowels are 5 (e,e,e,a,e) and the total number of the same vowels (which is 'e') is 4.
The code I did,is still showing the number of the same vowels to 5.
Is there something wrong on my code?
static void Main()
{
Console.Write("Enter a word or phrase : ");
string input = Console.ReadLine();
char[] listOfVowels = new char[] { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
int vowel = 0;
int sameVowel = 0;
for (int i = 0; i < input.Length; i++)
{
if (listOfVowels.Contains(input[i]))
{
Console.WriteLine(input[i]);
vowel++;
if(input[i] == input[i])
{
sameVowel++;
}
}
}
Console.WriteLine($"The total number of vowel are : {vowel}");
Console.WriteLine($"The total of the same number of vowel are : {sameVowel}");
}
The total number of vowel are : 5
The total of the same number of vowel are : 5
You can try this code, create a list to store vowel, and use linq to count same vowel
static void Main(string[] args)
{
Console.Write("Enter a word or phrase : ");
string input = Console.ReadLine();
char[] listOfVowels = new char[] { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
int vowel = 0;
int sameVowel = 0;
List<char> vowers = new List<char>();
for (int i = 0; i < input.Length; i++)
{
if (listOfVowels.Contains(input[i]))
{
Console.WriteLine(input[i]);
vowel++;
vowers.Add(input[i]);
//if(vowers.Contains(input[i]))
//{
// sameVowel++;
//}
}
}
sameVowel = vowers.GroupBy(_ => _).Where(_ => _.Count() > 1).Sum(_ => _.Count());
Console.WriteLine(string.Format("The total number of vowel are : {0}", vowel));
Console.WriteLine(string.Format("The total of the same number of vowel are : {0}", sameVowel));
Console.ReadLine();
}
Following the pillars of OOP and the Single Responsibility Principle, you could encapsulate this logic into a class that will handle this logic for you
Class
public class VowelStatistics
{
private readonly string word;
public VowelStatistics(string word)
{
this.word = word;
}
public IEnumerable<char> Vowels => word.Where(c => "aeiouAEIOU".Contains(c));
public int VowelCount => Vowels.Count();
public char MostFrequentVowel => Vowels
.GroupBy(c => c)
.OrderByDescending(g => g.Count())
.Select(g => g.Key)
.First();
public int MostFrequentVowelCount => Vowels
.GroupBy(c => c)
.Max(g => g.Count());
// Adding this as per #Everyone's comment, which will give you vowel groupings by frequency.
public IEnumerable<IGrouping<char, char>> VowelsByFrequency => Vowels
.GroupBy(c => c)
.OrderByDescending(g => g.Count());
}
Usage
VowelStatistics vs = new VowelStatistics("cheesecake");
Results
vs.Vowels = { 'e', 'e', 'e', 'a', 'e' }
vs.VowelCount = 5
vs.MostFrequentVowel = 'e'
vs.MostFrequentVowelCount = 4
Your code can be simplified:
static void Main()
{
Console.Write("Enter a word or phrase : ");
string input = Console.ReadLine()/*"cheesecake"*/;
char[] listOfVowels = new char[] { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
int vowel = 0;
vowel = input.Count(z => listOfVowels.Contains(z));
var sameVowelPair = input.Where(c => listOfVowels.Contains(c)).GroupBy(c => c).ToDictionary(s1 => s1.Key, s1=> s1.Count()).OrderByDescending(w => w.Value).FirstOrDefault();
Console.WriteLine($"The total number of vowel are : {vowel}");
Console.WriteLine($"The total of the same number of vowel are : {sameVowelPair.Value}");
}
Outputs:
The total number of vowel are : 5
The total of the same number of vowel are : 4
Take a look at this (no LINQ involved):
static (int, char, int) vowelStats(string str)
{
// VOWEL ONLY DICTIONARY
Dictionary<char, int> counts = new Dictionary<char, int>()
{
{'a', 0} , { 'e', 0} , { 'i', 0} , { 'o', 0} , { 'u', 0}
};
int vowels = 0;
char high = '\0';
foreach(char c in str)
{
char c1 = Char.ToLower(c); // convert letter to lowercase first
// if dictionary has the character, then it must be a vowel
if (counts.ContainsKey(c1))
{
counts[c1]++; // vowel itself count
vowels++; // total vowel count
if (!counts.ContainsKey(high)) high = c1; // will only be true once
if(vowels - counts[c1] < vowels - counts[high]) // update current most frequent
high = c1;
}
}
if(!counts.ContainsKey(high)) // if no vowels found, high will be '\0'
return (0, '\0', 0);
return (vowels, high, counts[high]);
}
static void Main(string[] args)
{
Console.Write("Enter a word or phrase : ");
string input = Console.ReadLine();
int vowels, mostFrequentVowelCount;
char mostFrequenctVowel;
(vowels, mostFrequenctVowel, mostFrequentVowelCount) = vowelStats(input);
Console.WriteLine("Total number of vowels: {0}", vowels);
Console.WriteLine("Most frequent vowel: {0}", mostFrequenctVowel);
Console.WriteLine("Most frequent vowel count: {0}", mostFrequentVowelCount);
}
Output:
Enter a word or phrase : cheesecake
Total number of vowels: 5
Most frequent vowel: e
Most frequent vowel count: 4
Notes:
1) I assumed what you meant by "same vowel" is "the most frequent vowel".
2) The code will only work (as is) in .Net Framework 4.7 or higher (tuple functions) OR .Net Core 2 or higher.
3) Time complexity: O(N) where N is the number of characters in the string.
4) Space complexity: O(C) where C is a constant representing the number of vowels and their corresponding integers in the Dictionary, plus the few other variables.
5) In case of two vowels having been the most frequent, this function will pick the one that was encountered first. That is, in case of "woohee" it will be 'o', and in case of "weehoo" it will be 'e'.
6) I updated the code so it does not care about uppercase/lowercase. If it encounters a vowel regardless of its case, it will update one and only one counter.
7) This does not use any LINQ and should be simple enough for basic C#. The reason I used no LINQ is because of its added complexity and overhead to performance.
This is nice and simple for me:
string input = "cheesecake";
var query =
from v in "aeiouAEIOU"
join c in input on v equals c
group c by c into gcs
orderby gcs.Count() descending
select gcs;
Console.WriteLine($"Vowels: {String.Join(", ", query.SelectMany(c => c))}");
Console.WriteLine($"Most Frequent Vowel: {query.First().Key}");
Console.WriteLine($"Most Frequent Vowel Count: {query.First().Count()}");
That gives:
Vowels: e, e, e, e, a
Most Frequent Vowel: e
Most Frequent Vowel Count: 4
Performance testing code:
static (int, char, int) vowelStatsPlain(string str)
{
// VOWEL ONLY DICTIONARY
Dictionary<char, int> counts = new Dictionary<char, int>()
{
{'a', 0} , { 'e', 0} , { 'i', 0} , { 'o', 0} , { 'u', 0}
};
int vowels = 0;
char high = '\0';
foreach (char c in str)
{
char c1 = Char.ToLower(c); // convert letter to lowercase first
// if dictionary has the character, then it must be a vowel
if (counts.ContainsKey(c1))
{
counts[c1]++; // vowel itself count
vowels++; // total vowel count
if (!counts.ContainsKey(high)) high = c1; // will only be true once
if (vowels - counts[c1] < vowels - counts[high]) // update current most frequent
high = c1;
}
}
if (!counts.ContainsKey(high)) // if no vowels found, high will be '\0'
return (0, '\0', 0);
return (vowels, high, counts[high]);
}
static (int, char, int) vowelStatsLinq(string str)
{
var query =
(
from v in "aeiouAEIOU"
join c in str on v equals c
group c by c into gcs
orderby gcs.Count() descending
select gcs
).ToArray();
var first = query.First();
return (query.SelectMany(c => c).Count(), first.Key, first.Count());
}
static void Main(string[] args)
{
string input = "The information contained in this email is confidential and for the addressee only; If you are not the intended recipient of this email, please reply and let us know that an incorrect address may have been used. If you do not wish to be communicated with by email, please respond so that we may remove your address from our records. Your co-operation is appreciated.";
Func<TimeSpan> callPlain = () =>
{
var sw = Stopwatch.StartNew();
(int vowels, char mostFrequenctVowel, int mostFrequentVowelCount) = vowelStatsPlain(input);
sw.Stop();
return sw.Elapsed;
};
Func<TimeSpan> callLinq = () =>
{
var sw = Stopwatch.StartNew();
(int vowels, char mostFrequenctVowel, int mostFrequentVowelCount) = vowelStatsLinq(input);
sw.Stop();
return sw.Elapsed;
};
var trials = Enumerable.Range(0, 1000000).Select(x => new { plain = callPlain(), linq = callLinq() }).ToArray();
Console.WriteLine(trials.Skip(2).Average(x => x.plain.TotalMilliseconds));
Console.WriteLine(trials.Skip(2).Average(x => x.linq.TotalMilliseconds));
Console.WriteLine(trials.Skip(2).Average(x => x.linq.TotalMilliseconds) / trials.Skip(2).Average(x => x.plain.TotalMilliseconds));
}

Generating every possible combination between two alphanumeric string ranges

I am working with SAP Idocs, which have segments which can contain cost centre reference ranges. The ranges are given as start and end values as strings. To store those values in my DB I need to generate all possible combinations existing between these values.
The strings are alphanumeric, say start: D98C1 and end: D9AZ3. The individual char sequence is first numeric from 0 to 9 and then alphabetic from A to Z. The expansion needs to generate all possible combinations between start and end, like say start: A1 to end: CA would comprise the values A1 to A9, AA to AZ, B0 to B9, BA to BZ, C0 to C9 and CA.
I am completely stuck on this and would really appreciate some pointers as to how this can be implemented.
EDIT:
As a person, I would start with finding the parts between the start and end strings which differ. I can do that, that's easy. So for the example above, that would be D9. Then I would go through the variable part of the start string one char at a time and vary all chars from the end of the string, going through all possible chars until I reach the corresponding char in the end string.
I'm just stuck implementing that.
I started out with something like this:
readonly static char[] values = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToArray();
static void Main(string[] args)
{
string from = "D3A0";
string to = "D3AC";
string root = new string(from.TakeWhile((c, i) => to.Length >= i && to[i] == c).ToArray());
string from1 = from.Substring(root.Length);
string to1 = to.Substring(root.Length);
var output = new List<string>();
for (int i = from1.Length - 1; i == 0; i--)
{
char startChar = from1[i];
char endChar = to1[i];
var remainingValues = values.SkipWhile(v => v != startChar)
.TakeWhile(v => v != endChar)
.ToList();
foreach (char v in remainingValues)
{
string currentValue = from1.Remove(i) + v;
output.Add(currentValue);
}
if (output.Contains(to1))
{
break;
}
}
foreach (var s in output.Select(o => root + o))
{
Console.WriteLine(s);
}
}
But it does not provide all combinations.
What you are looking for is called base36. Because it's a number that's represented in a 36 letter alphabet. As with any other representation of a number, you convert all representations to numbers, do your calculations and then convert them back for display:
using System;
using System.Linq;
namespace ConsoleApp11
{
public static class Base36
{
private const string Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static string ConvertToBase36(this int value)
{
string result = string.Empty;
while (value > 0)
{
result = Digits[value % Digits.Length] + result;
value /= Digits.Length;
}
return result;
}
public static int ConvertFromBase36(this string value)
{
return value.Reverse().Select((character, index) => (int)Math.Pow(Digits.Length, index) * Digits.IndexOf(character)).Sum();
}
}
class Program
{
static void Main()
{
var start = "D3A0";
var end = "D3AC";
var startNumber = start.ConvertFromBase36();
var endNumber = end.ConvertFromBase36();
while (startNumber < endNumber)
{
Console.WriteLine(startNumber.ConvertToBase36());
startNumber++;
}
Console.ReadLine();
}
}
}
How about something like this:
public static string Next(string current)
{
if (current.EndsWith("Z"))
return Next(current.Substring(0, current.Length - 1)) + "0";
if (current.EndsWith("9"))
return current.Substring(0, current.Length - 1) + "A";
return current.Substring(0, current.Length - 1) + (char) (current[current.Length-1] + 1);
}
and then call it like this
var value = "A1";
while (value != "CB")
{
Console.WriteLine(value);
value = Next(value);
}
Maybe something like this:
private static string values = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void Main()
{
string from = "Y5";
string to = "ZZ";
var counter = from;
var output = new List<string>();
while(counter != to) {
counter = Increment(counter);
output.Add(counter);
}
Console.WriteLine(string.Join(Environment.NewLine, output));
}
private static string Increment(string counter){
if(counter.Length < 1) {
counter = values[0] + counter;
}
var lastChar = counter[counter.Length - 1];
var lastCharIndex = values.IndexOf(lastChar);
if(lastCharIndex == -1)
{
throw new InvalidOperationException("Sequence contains an invalid character: " + lastChar);
}
var nextCharIndex = values.IndexOf(lastChar) + 1;
if(nextCharIndex >= values.Length)
{
return Increment(counter.Substring(0, counter.Length - 1)) + values[0];
}
return counter.Substring(0, counter.Length - 1) + values[nextCharIndex];
}
Should work with any combination / order of values.
I knocked up the following - as a first effort - values gets set to available character options. This is how humans would do it. Its not efficient, its not glorious, but it does the job.
private static readonly char[] values = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
private static void Main(string[] args)
{
Console.Write("Start: ");
//String start = Console.ReadLine();
String start = "D98C1";
Console.Write(" End: ");
String end = "D9AZ3";
//String end = Console.ReadLine();
int i1 = Array.IndexOf(values, start[0]);
int i2 = Array.IndexOf(values, start[1]);
int i3 = Array.IndexOf(values, start[2]);
int i4 = Array.IndexOf(values, start[3]);
int i5 = Array.IndexOf(values, start[4]);
while (String.Format("{0}{1}{2}{3}{4}", values[i1], values[i2], values[i3], values[i4], values[i5]) != end)
{
i5++;
if (i5 == values.Length)
{
i5 = 0;
i4++;
if (i4 == values.Length)
{
i4 = 0;
i3++;
if (i3 == values.Length)
{
i3 = 0;
i2++;
if (i2 == values.Length)
{
i2 = 0;
i1++;
if (i1 == values.Length)
{
break;
}
}
}
}
}
Console.WriteLine(String.Format("{0}{1}{2}{3}{4}", values[i1], values[i2], values[i3], values[i4], values[i5]));
}
}

Ubbi Dubbi c# program code

Ubbi Dubbi is a program where before the first vowel in a word, the letters “ub” are inserted. On my code, it doesn't do it before the first vowel it does the second vowel. If I put "hello" the output is "hellubo", when it should be "hubello". Sorry if my english is bad, i'm still learning.
Console.Write("Enter word: ");
string word = Console.ReadLine();
var loc = word.IndexOfAny(new char[] {'a', 'e', 'i', 'o', 'u'});
int aloc = word.IndexOf('a');
int eloc = word.IndexOf('e');
int iloc = word.IndexOf('i');
int oloc = word.IndexOf('o');
int uloc = word.IndexOf('u');
if (aloc!= -1 && aloc > loc)
{
loc = aloc;
}
if (eloc!= -1 && eloc > loc)
{
loc = eloc;
}
if (iloc!= -1 && iloc > loc)
{
loc = iloc;
}
if (oloc!= -1 && oloc > loc)
{
loc = oloc;
}
if (uloc!= -1 && uloc > loc)
{
loc = uloc;
}
string word1 = word.Insert(loc, "ub");
Console.WriteLine(word1);
After calling of IndexOfAny all work is done. So you can skip most of your code. But you should insert a check, if there is any vowel at all:
Console.Write("Enter word: ");
string word = Console.ReadLine();
var loc = word.IndexOfAny(new char[] { 'a', 'e', 'i', 'o', 'u' });
string word1 = loc >= 0 ? word.Insert(loc, "ub") : word;
Console.WriteLine(word1);
In your code an 'e' is found, so loc = eloc is executed. But there also 'o' is found and loc = oloc is executed AFTER the 'e'-check. So the final value of loc is that one of oloc.
You can achieve it easily by below API.
private static string processWord(string word)
{
// Vowels array
char[] vowels = new char[] { 'a', 'e', 'i', 'o', 'u' };
//Find the index of your first vowel in your 'word'
int index = word.IndexOfAny(vowels);
//Insert 'ub' at above location
word = word.Insert(index, "ub");
//Return the word
return word;
}
or
private static string processWord(string word)
{
return word.Insert(word.IndexOfAny(new char[] { 'a', 'e', 'i', 'o', 'u' }), "ub");
}
Chose any method whichever easy for you to understand

Categories