I have to write algotithm in C# where input is:
3 2
aj
oj
ck
25
73
and the output:
aj ck
DOES NOT EXIST
The first line in iput is two numbers, the first one is number of words. And the second one is number of numbers for which we will be searching for words. Each character is represented by number like this below:
2 (abc)
3 (def)
4 (ghi)
5 (jkl)
6 (mno)
7 (pqrs)
8 (tuv)
9 (wxyz)
For example for number 25, there are 9 two-char-words: aj, ak, al, bj, bk, bl, cj, ck, cl.
For number 438, there are 27 three-char-words, etc.
So far I have this code, but something is not working properly, and I have no idea what is it that is not working.
int n;
int k;
string input;
List<string> dict = new List<string>();
List<string> res = new List<string>();
n = int.Parse(Console.ReadLine());
k = int.Parse(Console.ReadLine());
for (int i = 0; i < n; i++)
{
input = Console.ReadLine();
dict.Add(input);
}
dict.Sort();
for (int i = 0; i < k; i++)
{
input = Console.ReadLine();
res = new List<string>(dict);
int inputLength = input.Length;
for (int j = 0; j < inputLength; ++j)
{
switch (input[j])
{
case '2':
res = new List<string>(filter(res, i, 'a', 'b', 'c'));
break;
case '3':
res = new List<string>(filter(res, i, 'd', 'e', 'f'));
break;
case '4':
break;
case '5':
res = new List<string>(filter(res, i, 'j', 'k', 'l'));
break;
case '6':
res = new List<string>(filter(res, i, 'm', 'n', 'o'));
break;
case '7':
res = new List<string>(filterWithFour(res, i, 'p', 'q', 'r', 's'));
break;
case '8':
res = new List<string>(filter(res, i, 't', 'u', 'v'));
break;
case '9':
res = new List<string>(filterWithFour(res, i, 'w', 'x', 'y', 'z'));
break;
}
}
if (res.Any())
foreach (var item in res.ToList())
Console.WriteLine(item);
else
Console.WriteLine("DOES NOT EXIST");
}
static List<string> filterWithFour(List<string> resGiven, int pos, char a, char b, char c, char d)
{
List<string> res = new List<string>();
foreach (var item in resGiven.ToList())
{
if (item.Length > pos)
if (item[pos] == a || item[pos] == b || item[pos] == c || item[pos] == d)
res.Add(item);
}
return res;
}
static List<string> filter(List<string> resGiven, int pos, char a, char b, char c)
{
List<string> res = new List<string>();
foreach (var item in resGiven.ToList())
{
if (item.Length > pos)
if (item[pos] == a || item[pos] == b || item[pos] == c)
res.Add(item);
}
return res;
}
Thank you for any help, because I stuck on this one, and I can't go through it.
In order to do what you want, I would replace the numbers with Regex pattern as such:
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq; // so you can use .Where on List
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
int n;
int k;
string input;
List<string> dict = new List<string>();
n = int.Parse(Console.ReadLine());
k = int.Parse(Console.ReadLine());
for (int i = 0; i < n; i++)
{
input = Console.ReadLine();
dict.Add(input);
}
dict.Sort();
for (int i = 0; i < k; i++)
{
input = Console.ReadLine();
// get the full pattern for the whole number
string patternToSearch = "";
foreach(var c in input)
{
patternToSearch += GetPattern(c);
}
Console.WriteLine(patternToSearch);
// find the words that matches the pattern
var filteredDict = dict.Where(w => Regex.Match(w, patternToSearch).Success);
if(!filteredDict.Any())
Console.WriteLine("DOES NOT EXIST");
else
Console.WriteLine(string.Join(" ", filteredDict));
}
}
// returns the regex pattern for one number
static string GetPattern(char c)
{
switch(c)
{
case '2': return "[abc]";
case '3': return "[def]";
case '4': return "[ghi]";
case '5': return "[jkl]";
case '6': return "[mno]";
case '7': return "[pqrs]";
case '8': return "[tuv]";
case '9': return "[wxyz]";
default: return "";
}
}
}
With input:
3
2
aj
oj
ck
25
73
It outputs:
[abc][jkl]
aj ck
[pqrs][def]
DOES NOT EXIST
Related
I need to check a char array and convert every char to a random number value into a int array;
I have managed to do this but with a lot of code.
Is there anyway I can write less code?
for (int i = 0; i < 8; i++)
{
if (oddF[i] == '0')
{
oddFlValue[i] = 1;
continue;
}
else if (oddF[i] == '1')
{
oddFValue[i] = 0;
continue;
}
else if (oddFiscal[i] == '8')
{
oddFiscalValue[i] = 19;
continue;
}
else if (oddF[i] == '9')
{
oddFValue[i] = 21;
continue;
}
else if ((oddF[i] == 'a') || (oddF[i] == 'A'))
{
oddFValue[i] = 1;
continue;
}
else if ((oddF[i] == 'b') || (oddF[i] == 'B'))
{
oddFValue[i] = 0;
continue;
}
This is just a sample as I need to check for every number and letter type.
Thanks!
I think the easiest way to do this would be to use a Dictionary<char, int>, and get its value. Something like this:
Dictionary<char, int> MyCombinations = new Dictionary<char, int>{
{'0', 1},
{'5', 15},
/*etc etc etc*/
};
And then use it like:
for (int i = 0; i < 8; i++)
{
oddFValue[i] = MyCombinations[oddFiscal[i]];
}
class Program
{
static void Main(string[] args)
{
char[] oddF = new char[8]{'0','1','8','A','b','9','a','B'};
int[] oddFValue = new int[8];
Dictionary<char, int> table = new Dictionary<char, int>(){
{ '0', 1 },
{ '1', 0 },
{ '8', 19 },
{ '9', 21 },
{ 'a', 1 },
{ 'A', 1 },
{ 'b', 0 },
{ 'B', 0 }
};
for (int i = 0; i < 8; i++)
{
oddFValue[i] = table[oddF[i]]; // Lookup which function should be called, and call it.
}
}
}
How about:
public int? ConvertCharToInt(char c)
{
switch (c)
{
case '0': return 1;
case '1': return 0;
case '8': return 19;
case '9': return 21;
case 'a':
case 'A': return 1;
case 'b':
case 'B': return 0;
// ...
default: return null;
}
}
And then:
for (int i = 0; i < 8; i++)
{
int? number = ConvertCharToInt(oddF[i]);
if (number.HasValue)
oddFValue[i] = number.Value;
else
// Character cannot be converted to int value
}
In this code I am attempting to write requires that I make a small menu, and for A to take 5 integers, and B to display them, C and D are // out because I don't have to code those sections yet, but for some reason I can't get the integers to input right, and for them to be displayed with B. My main question is how can I get 5 user inputs inside of loadarray and then use that array in displayarray?
static void Main(string[] args)
{
char choice;
int[] Num = new interger[5];
do
{
Console.Clear();
Choice = Menu();
switch (choice)
{
case 'A':
case 'a':
lArray(Num);
Console.ReadLine();
break;
case 'B':
case 'b':
dArray(Num);
Console.ReadLine();
break;
case 'C':
case 'c':
// Console.WriteLine("Sum: {0}", cSum(Num));
Console.ReadLine();
break;
case 'D':
case 'd':
// Console.WriteLine("Average: {0}", cAverage(Num));
Console.ReadLine();
break;
case 'Z':
case 'z':
break;
default:
Console.WriteLine("Invalid number!");
break;
}
}
while (choice != 'Z' && choice != 'z');
}
static char Menu()
{
char Input;
string[] strOptions = new string[] {
"A. Add num",
"B. Display num",
"C. Output sum ",
"D. Output average",
"z. Exit"
};
Console.WriteLine("What would you like to do?");
foreach(string strValue in strOptions)
{
Console.WriteLine(strValue);
}
do
{
Console.Write("Please select from A to Z: ");
Input = Console.ReadKey().KeyChar;
Console.WriteLine();
}
while ((Input < 'A' || Input > 'Z') && (Input < 'a' || Input > 'z'));
return Input;
}
static int lArray(int[] array)
{
int[] newArray = new int[5];
for (int i = 0; i < newArray.Length; i++)
{
newArray[i] = Convert.ToInt32(Console.ReadLine());
}
}
static int dArray(int[] array)
{
return loadArray;
}
}
}
}
The code below attempts to calculate the gematrical value of a string:
for (int i = 0; i < str.Length; i++){
switch(str[i].ToString()){
case "A":
gemValue += 1;
break;
case "a":
gemValue += 1;
break;
case "B":
gemValue += 2;
break;
case "b":
gemValue += 2;
break;
// other characters to follow
default:
gemValue += 0;
break;
}
}
Console.WriteLine("The gematrical value of the word or phrase is " +
gemValue);
Console.ReadKey();
Could there be a way to simplify the code and logic without using a dictionary (or any sort of array for that matter)?
Creating a list of ints like:
int A, a = 1;
int B, b = 2;
...
is no better than plugging all cases into switch. I thought about playing foul and just grabbing the ascii value for each char but that is also to be avoided in this exercise.
Any ideas?
string sample = "abc";
int sum = (from c in sample select char.IsLetter(c) ? char.IsUpper(c) ? c - 'A' + 1 : c - 'a' + 1 : 0).Sum();
Console.WriteLine("The gematrical value of the word or phrase is {0}", sum);
You can
string str = "Hello";
int gemValue = 0;
for (int i = 0; i < str.Length; i++)
{
char ch = str[i];
if (ch >= 'A' && ch <= 'Z')
{
gemValue += ch - 'A' + 1;
}
else if (ch >= 'a' && ch <= 'z')
{
gemValue += ch - 'a' + 1;
}
}
because in the end, chars are numbers with a range 0-65535, where A = 65, B = 66, ..., Z = 90, a = 97, b = 98, ... z = 122.
Note that the world is a big and funny place, full of marvelous languages that don't simply use A-Za-z.
string str = "Hèållo"; // Doesn't work with æ, ø
int gemValue = 0;
string str2 = string.Concat(
str.Normalize(NormalizationForm.FormD)
.Where(x => CharUnicodeInfo.GetUnicodeCategory(x) != UnicodeCategory.NonSpacingMark));
for (int i = 0; i < str.Length; i++)
{
char ch = str2[i];
if (ch >= 'A' && ch <= 'Z')
{
gemValue += ch - 'A' + 1;
}
else if (ch >= 'a' && ch <= 'z')
{
gemValue += ch - 'a' + 1;
}
else if (char.IsLetter(ch))
{
throw new NotSupportedException(string.Format("{0} contains non A-Z letters", str));
}
}
This will at least try to solve the problem for some letters, like àèéìòù (and many others), converting them to aeeiou and will throw a NotSupportedException if you try to pass letters that it doesn't recognize (like æ, ø, arabic, japanese, chinese, ...). Note that it will ignore non-letters, like spaces, commas, dots, ...
You can create dictionary of lowercase char values, and then project each char to value in simple LINQ query:
var str = "aBb";
var letterValues = new Dictionary<char, int> {
{'a', 1},
{'b', 2}
};
int gemValue = str.Select(Char.ToLower)
.Sum(ch => letterValues.Contains(ch) ? letterValues[ch] : 0);
Or for better performance you can use TryGetValue method to avoid double lookup of chars which contained in dictionary:
int gemValue = 0;
foreach (var ch in str.Select(Char.ToLower))
{
int value;
if (letterValues.TryGetValue(ch, out value))
gemValue += value;
}
This should work:
int minLetter = (int) 'A' - 1;
int sum = "Hello World".Sum(c => (int)Char.ToUpper(c) - minLetter);
Tested successfully with:
var coll = new[] { "a", "A", "aA", "AA", "abc", "ABC", "AbC", "123", "hello World" };
foreach (string str in coll)
{
int sum = str.Sum(c => (int)Char.ToUpper(c) - minLetter);
Console.WriteLine(sum);
}
However, as commented by vc74, if the value associated to a letter does not depend on its position in the alphabet a dictionary is the best way to map each letter to its value.
Are there any classes/functions available to be used for easy JSON escaping? I'd rather not have to write my own.
I use System.Web.HttpUtility.JavaScriptStringEncode
string quoted = HttpUtility.JavaScriptStringEncode(input);
For those using the very popular Json.Net project from Newtonsoft the task is trivial:
using Newtonsoft.Json;
....
var s = JsonConvert.ToString(#"a\b");
Console.WriteLine(s);
....
This code prints:
"a\\b"
That is, the resulting string value contains the quotes as well as the escaped backslash.
Building on the answer by Dejan, what you can do is import System.Web.Helpers .NET Framework assembly, then use the following function:
static string EscapeForJson(string s) {
string quoted = System.Web.Helpers.Json.Encode(s);
return quoted.Substring(1, quoted.Length - 2);
}
The Substring call is required, since Encode automatically surrounds strings with double quotes.
Yep, just add the following function to your Utils class or something:
public static string cleanForJSON(string s)
{
if (s == null || s.Length == 0) {
return "";
}
char c = '\0';
int i;
int len = s.Length;
StringBuilder sb = new StringBuilder(len + 4);
String t;
for (i = 0; i < len; i += 1) {
c = s[i];
switch (c) {
case '\\':
case '"':
sb.Append('\\');
sb.Append(c);
break;
case '/':
sb.Append('\\');
sb.Append(c);
break;
case '\b':
sb.Append("\\b");
break;
case '\t':
sb.Append("\\t");
break;
case '\n':
sb.Append("\\n");
break;
case '\f':
sb.Append("\\f");
break;
case '\r':
sb.Append("\\r");
break;
default:
if (c < ' ') {
t = "000" + String.Format("X", c);
sb.Append("\\u" + t.Substring(t.Length - 4));
} else {
sb.Append(c);
}
break;
}
}
return sb.ToString();
}
I have used following code to escape the string value for json.
You need to add your '"' to the output of the following code:
public static string EscapeStringValue(string value)
{
const char BACK_SLASH = '\\';
const char SLASH = '/';
const char DBL_QUOTE = '"';
var output = new StringBuilder(value.Length);
foreach (char c in value)
{
switch (c)
{
case SLASH:
output.AppendFormat("{0}{1}", BACK_SLASH, SLASH);
break;
case BACK_SLASH:
output.AppendFormat("{0}{0}", BACK_SLASH);
break;
case DBL_QUOTE:
output.AppendFormat("{0}{1}",BACK_SLASH,DBL_QUOTE);
break;
default:
output.Append(c);
break;
}
}
return output.ToString();
}
In .Net Core 3+ and .Net 5+:
string escapedJsonString = JsonEncodedText.Encode(jsonString);
The methods offered here are faulty.
Why venture that far when you could just use System.Web.HttpUtility.JavaScriptEncode ?
If you're on a lower framework, you can just copy paste it from mono
Courtesy of the mono-project #
https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs
public static string JavaScriptStringEncode(string value, bool addDoubleQuotes)
{
if (string.IsNullOrEmpty(value))
return addDoubleQuotes ? "\"\"" : string.Empty;
int len = value.Length;
bool needEncode = false;
char c;
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92)
{
needEncode = true;
break;
}
}
if (!needEncode)
return addDoubleQuotes ? "\"" + value + "\"" : value;
var sb = new System.Text.StringBuilder();
if (addDoubleQuotes)
sb.Append('"');
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
sb.AppendFormat("\\u{0:x4}", (int)c);
else switch ((int)c)
{
case 8:
sb.Append("\\b");
break;
case 9:
sb.Append("\\t");
break;
case 10:
sb.Append("\\n");
break;
case 12:
sb.Append("\\f");
break;
case 13:
sb.Append("\\r");
break;
case 34:
sb.Append("\\\"");
break;
case 92:
sb.Append("\\\\");
break;
default:
sb.Append(c);
break;
}
}
if (addDoubleQuotes)
sb.Append('"');
return sb.ToString();
}
This can be compacted into
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
public class SimpleJSON
{
private static bool NeedEscape(string src, int i)
{
char c = src[i];
return c < 32 || c == '"' || c == '\\'
// Broken lead surrogate
|| (c >= '\uD800' && c <= '\uDBFF' &&
(i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF'))
// Broken tail surrogate
|| (c >= '\uDC00' && c <= '\uDFFF' &&
(i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF'))
// To produce valid JavaScript
|| c == '\u2028' || c == '\u2029'
// Escape "</" for <script> tags
|| (c == '/' && i > 0 && src[i - 1] == '<');
}
public static string EscapeString(string src)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int start = 0;
for (int i = 0; i < src.Length; i++)
if (NeedEscape(src, i))
{
sb.Append(src, start, i - start);
switch (src[i])
{
case '\b': sb.Append("\\b"); break;
case '\f': sb.Append("\\f"); break;
case '\n': sb.Append("\\n"); break;
case '\r': sb.Append("\\r"); break;
case '\t': sb.Append("\\t"); break;
case '\"': sb.Append("\\\""); break;
case '\\': sb.Append("\\\\"); break;
case '/': sb.Append("\\/"); break;
default:
sb.Append("\\u");
sb.Append(((int)src[i]).ToString("x04"));
break;
}
start = i + 1;
}
sb.Append(src, start, src.Length - start);
return sb.ToString();
}
}
I ran speed tests on some of these answers for a long string and a short string. Clive Paterson's code won by a good bit, presumably because the others are taking into account serialization options. Here are my results:
Apple Banana
System.Web.HttpUtility.JavaScriptStringEncode: 140ms
System.Web.Helpers.Json.Encode: 326ms
Newtonsoft.Json.JsonConvert.ToString: 230ms
Clive Paterson: 108ms
\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\"things\to\escape\some\long\path\with\lots"\of\things\to\escape
System.Web.HttpUtility.JavaScriptStringEncode: 2849ms
System.Web.Helpers.Json.Encode: 3300ms
Newtonsoft.Json.JsonConvert.ToString: 2827ms
Clive Paterson: 1173ms
And here is the test code:
public static void Main(string[] args)
{
var testStr1 = "Apple Banana";
var testStr2 = #"\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\""things\to\escape\some\long\path\with\lots""\of\things\to\escape";
foreach (var testStr in new[] { testStr1, testStr2 })
{
var results = new Dictionary<string,List<long>>();
for (var n = 0; n < 10; n++)
{
var count = 1000 * 1000;
var sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = System.Web.HttpUtility.JavaScriptStringEncode(testStr);
}
var t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.HttpUtility.JavaScriptStringEncode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = System.Web.Helpers.Json.Encode(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.Helpers.Json.Encode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = Newtonsoft.Json.JsonConvert.ToString(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Newtonsoft.Json.JsonConvert.ToString").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = cleanForJSON(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Clive Paterson").Add(t);
}
Console.WriteLine(testStr);
foreach (var result in results)
{
Console.WriteLine(result.Key + ": " + Math.Round(result.Value.Skip(1).Average()) + "ms");
}
Console.WriteLine();
}
Console.ReadLine();
}
I would also recommend using the JSON.NET library mentioned, but if you have to escape unicode characters (e.g. \uXXXX format) in the resulting JSON string, you may have to do it yourself. Take a look at Converting Unicode strings to escaped ascii string for an example.
I nice one-liner, used JsonConvert as others have but added substring to remove the added quotes and backslash.
var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length - 2);
What about System.Web.Helpers.Json.Encode(...) (see http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111).aspx)?
String.Format("X", c);
That just outputs: X
Try this instead:
string t = ((int)c).ToString("X");
sb.Append("\\u" + t.PadLeft(4, '0'));
There's a Json library at Codeplex
I chose to use System.Web.Script.Serialization.JavaScriptSerializer.
I have a small static helper class defined as follows:
internal static partial class Serialization
{
static JavaScriptSerializer serializer;
static Serialization()
{
serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
}
public static string ToJSON<T>(T obj)
{
return serializer.Serialize(obj);
}
public static T FromJSON<T>(string data)
{
if (Common.IsEmpty(data))
return default(T);
else
return serializer.Deserialize<T>(data);
}
}
To serialize anything I just call Serialization.ToJSON(itemToSerialize)
To deserialize I just call Serialization.FromJSON<T>(jsonValueOfTypeT)
I tried to design a program which counts the vowels in a sentence.
In my code, I used a foreach statement with the if/else if statement. I would like to convert these line of code using the switch statement
but I'm not really sure where to go. Do I need to add a new method? I would appreciate your help.
This is what I tried so far: I checked this one is very wrong. The case 1 for example needs to have a constant. I'm not sure what constant shall I use here.
foreach (char v in yourSentence)
{
switch (v)
{
case 1:
(v==ch1);
counta++;
j++;
break;
case 2:
(v==ch2);
counte++;
j++;
break;
case 3:
(v==ch3);
counti++;
j++;
break;
case 4:
(v==ch4);
counto++;
j++;
break;
case 5:
(v==ch3);
counti++;
j++;
break;
}
}
Another question: I tried to change the color of the display text in the listBox. Is that possible to have different colors? What I also tried here is the first 5 (listBox1.Items.Add) are violet. And the sum of the (listBox1.Items.Add) is blue. But it seems that it didn't change. Did I miss something here?
private void btnCount_Click(object sender, EventArgs e)
{
string yourSentence;
yourSentence = textBoxVowels.Text.ToLower().Trim();
char ch1 = 'a';
char ch2 = 'e';
char ch3 = 'i';
char ch4 = 'o';
char ch5 = 'u';
int counta = 0;
int counte = 0;
int counti = 0;
int counto = 0;
int countu = 0;
int j = counta + counte + counti + counto + countu;
foreach (char v in yourSentence)
{
if (v == ch1) { counta++; j++; }
else if (v == ch2) { counte++; j++; }
else if (v == ch3) { counti++; j++; }
else if (v == ch4) { counto++; j++; }
else if (v == ch5) { countu++; j++; }
}
listBox1.Items.Add("There are " + counta.ToString().Trim() + " a's in the sentence");
listBox1.Items.Add("There are " + counte.ToString().Trim() + " e's in the sentence");
listBox1.Items.Add("There are " + counti.ToString().Trim() + " i's in the sentence");
listBox1.Items.Add("There are " + counto.ToString().Trim() + " o's in the sentence");
listBox1.Items.Add("There are " + countu.ToString().Trim() + " u's in the sentence");
listBox1.Font = new Font("Arial", 12, FontStyle.Bold);
listBox1.ForeColor = Color.Violet;
listBox1.Items.Add("There are " + j.ToString().Trim() + " vowels in the sentence");
listBox1.ForeColor = Color.Blue;
}
private void btnClear_Click(object sender, EventArgs e)
{
textBoxVowels.Text = null;
listBox1.Items.Clear();
}
Or just simplify the whole problem by using a bit of LINQ. :)
public static int CountVowels(this string value)
{
const string vowels = "aeiou";
return value.Count(chr => vowels.Contains(char.ToLower(chr)));
}
The Count extension method is particularly well suited to this task. Also, notice the use of a string of all vowels to check each character - much simpler than a switch statement.
Note: It seems I missed the fact that you want to count each vowel individually. In this case, the LINQ becomes a bit more complicated (at least if you want to do it efficiently), but I shall leave that as an exercise for you. Regardless, a switch statement is probably a good way to learn the basics of C#.
Since you're probably curious about the switch statement anyway, the following code uses the correct syntax:
foreach (var chr in sentence)
{
switch (chr)
{
case 'a':
...
break;
case 'e':
...
break;
case 'i':
...
break;
case 'o':
...
case 'u':
...
break;
}
}
I think you misunderstood how 'switch/case' works. Just change them to this:
case 'a':
counta++;
j++;
break;
Case needs a constant value that should be compared to the current character.
Here's a more advanced solution:
public static Dictionary<char, int> CountLetters(string value, string letters)
{
var counts = letters.ToDictionary(c => c.ToString(), c => 0, StringComparer.OrdinalIgnoreCase);
var groups = from c in value
let s = c.ToString()
where counts.ContainsKey(s)
group s by s;
foreach(var g in groups)
counts[g.Key] = g.Count();
return counts;
}
Which you could use like this:
var letterCounts = CountLetters(yourSentence, "aeiou");
int countA = letterCounts["a"];
int countE = letterCounts["e"];
int countI = letterCounts["i"];
int countO = letterCounts["o"];
int countU = letterCounts["u"];
int total = countA + countE + countI + countO + countU;
Update: Just realized that a StringComparer won't work for char keys. Switching to string key - not as efficient as char, but easier than writing a case-insensitive char comparer. I prefer the comparer approach to doing some sort of ToLower/ToUpper on everything dictionary-related.
Please also check the other answers to your questions for many helpful tips. I'm just rewriting your first piece of example code from your question to probably let it do what you mean:
foreach (char v in yourSentence)
{
switch (v)
{
case 'a': counta++; j++; break;
case 'e': counte++; j++; break;
case 'i': counti++; j++; break;
case 'o': counto++; j++; break;
case 'u': countu++; j++; break;
}
}
You seem to want to increase one of the { counta, counte, counti, counto, countu } variables for the five specific vowels using the switch (right?) and also increase the j variable for each of the vowels.
Having given this answer, I would personally do something different altogether. Like the LINQ example given by Noldorin. Or something like this, as perhaps suggested by cherryalpha:
// create dictionary
var counts = new Dictionary<char,int>();
// initialize it for the vowels
foreach (char v in "aeiuo")
{
counts.Add(v, 0);
}
// count all characters in sentence
foreach (char v in yourSentence) {
if ( counts.ContainsKey(v) ) {
// increase count for known characters
counts[v]++;
} else {
// add new count for characters not seen previously
counts.Add(v,1);
}
}
// calculate your total number of vowels
j = counts['a'] + counts['e'] + counts['i'] + counts['o'] + counts['u'];
Quick warning, just in case: You would need a using System.Collection.Generic at the top of your source file that contains this code to make sure the generic Dictionary is known by its short name.
(And be aware that this code will not only give you vowel counts, but counts for all the other characters in yourSentence as well.)
const string VOWELS = "aeiou";
var str = "Lorem ipsum dolor sit amet";
var q = from ch in str
where VOWELS.Contains(ch)
group ch by ch into g
select g;
var dict = q.ToDictionary(_ => _.Key, _ => _.Count());
I faced a similar kind of problem in an interview. But I had to show my result in a level control instead of listbox control ... so i solved this problem like this:
protected void Button1_Click(object sender, EventArgs e)
{
string EnterString;
EnterString = TextBox1.Text;
char ch1 = 'a';
char ch2 = 'e';
char ch3 = 'i';
char ch4 = 'o';
char ch5 = 'u';
int counta = 0;
int counte = 0;
int counti = 0;
int counto = 0;
int countu = 0;
char ch6 = 'A';
char ch7 = 'E';
char ch8 = 'I';
char ch9 = 'O';
char ch10 = 'U';
int countA = 0;
int countE = 0;
int countI = 0;
int countO = 0;
int countU = 0;
int j = counta + counte + counti + counto + countu + countA + countE + countI + countO + countU;
foreach (char v in EnterString)
{
if (v == ch1) { counta++; j++; }
else if (v == ch2) { counte++; j++; }
else if (v == ch3) { counti++; j++; }
else if (v == ch4) { counto++; j++; }
else if (v == ch5) { countu++; j++; }
}
foreach (char v in EnterString)
{
if (v == ch6) { countA++; j++; }
else if (v == ch7) { countE++; j++; }
else if (v == ch8) { countI++; j++; }
else if (v == ch9) { countO++; j++; }
else if (v == ch10) { countU++; j++; }
}
Label1.Text = j.ToString();
}