checking each char in string is outputted in wrong order? - c#

im trying to split a string into a chars(which i have semi done) and use each char to compare it to my dictionary full of random strings, and then add that chars value in the dictionary to a finished string. the problem is what its outputting- the chars are not in order.
ex: USER INPUT: "hello"---
ex: CONSOLE: "e"-"l"-"l"-"o"-"h"
thats what happens mostly. any answer as to how i can get it to spell it correctly in the console?
Code:
private void complete_text_Click(object sender, RoutedEventArgs e)
{
end_result = input_box.Text.ToString();
string end_translated_result = "";
for (int i = 0; i < ZENOX_LANGUAGE.Keys.Count; i ++)
{
foreach (char iq in end_result.ToCharArray())
{
if (iq.ToString().ToLower() == ZENOX_LANGUAGE.Keys.ElementAt(i).ToString().ToLower())
{
Console.WriteLine(iq);
end_translated_result += ZENOX_LANGUAGE.Values.ElementAt(i) + " ";
//Console.WriteLine("sender: " + sender.ToString() + " c: " + end_result[iq].ToString().ToLower() + " s:" + ZENOX_LANGUAGE.Keys.ElementAt(i));
Console.WriteLine("end translated result: " + end_result);
}
}
}
}

As it stands, the order of keys in your dictionary will influence the order that output appears, because you're doing:
foreach(var k in dictionary.Keys)
foreach(char c in someString)
if(c == k)
Console.Write(c)
And dictionary keys have no defined order.
Swapping the loops over will mean (as long as the dictionary has the key you're looking for, as it's a condition that leads to printing the char) that the output will appear in order of chars in the string..
..but I can't actually work out why you enumerate the keys and then run a loop looking for the character. I'd just loop over the string and use the char to index the dictionary if I was building some sort of translator map:
var map = new Dictionary<char, char>() {
{ 'h', 'Z' },
{ 'e', 'Y' },
{ 'l', 'X' },
{ 'o', 'W' }
};
var toTrans = "hello";
foreach(char c in toTrans)
Console.Write(map[c]);
This will print "ZYXXW" for an input of "hello";
If you're mapping chars to strings, with case insensitivity it's as simple as:
var map = new Dictionary<char, string>() {
{ 'h', "Z0" },
{ 'e', "Y0" },
{ 'l', "X0" },
{ 'o', "W0" }
};
var toTrans = "HelLO";
foreach(char c in toTrans)
Console.Write(map[Char.ToLower(c)]);
This will print "Z0Y0X0X0W0"

Related

A c# project! should i use String arrays? (is that even a thing?!)

I'm working on a program in c# where I'm supposed to tell the user to insert random characters and then divide those random characters into letters and numbers and count how many i have of each.
anyone has any idea how to do so?
thanks!
ps: i'm new to c# and programming alltogether :)
You could use char.IsDigit or char.IsNumber to check if it's a "number"(digit):
string input = Console.ReadLine();
int digitCount = input.Count(char.IsDigit);
int letterCount = input.Length - digitCount;
You need to add using System.Linq to be able to use Enumerable.Count.
Since you now have asked for counting vowels. Vowels are a, e, i, o, u and their uppercase version. So you could use this method:
private static readonly HashSet<char> Vowels = new HashSet<char> { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
public static bool IsVowel(char c) => Vowels.Contains(c);
and this code to count the vowels:
int vowelCount = input.Count(IsVowel);
If you don't just want to count them but show them to the user:
string vowelsInInput = new String(input.Where(IsVowel).ToArray());
string noVowels = new String(input.Where(c => !IsVowel(c)).ToArray());
which also gives you the count(for example vowelsInInput.Length).
Get the input and loop through every character within the string
string testStr = "abc123";
foreach (char c in testStr)
{
Console.WriteLine(c.ToString( ));
}
You can use a dictionary to count the number of times a letter appears.
char letter = //your letter;
var charFrequencies = new Dictionary<char, int>();
if (!charFrequencies.ContainsKey(letter)) {
charFrequencies.Add(letter, 1);
}
else {
charFrequencies[letter]++;
}

Assign new value to a string index

I need to convert the characters a, e, i, o, u in the user input string to the assigned symbols. Below is what I have so far.
School assignment
First prompt the user for the encrypted text string. Validate that this is not left blank. Send this text string into a custom method you will create that will decipher it. Once it is deciphered, return this text string to the main where you will output both the encrypted and decrypted strings.
To decipher the text string you must perform the following character replacements:
# = a
# = e
^ = i
* = o
+ = u
My current code
public static string Decipher (string code)
{
char[] array = code.ToCharArray();
for (int i = 0; i < code.Length; i++)
{
if (code.Contains("#") && code.Contains("#") && code.Contains("^") &&
code.Contains("*") && code.Contains("+"))
{
}
}
Every time you go through this for loop, it will evaluate true if the string contains #, #, ^, * and + anywhere in the string. So if your string is missing any of these symbols, your if statement will evaluate to false and nothing will happen.
Luckily you can simplify this pretty easily. One way you can do this is to convert your string to a char[] array and break your logic into multiple if-else statements, or a single switch statement, for example:
public static string Decipher (string code)
{
char[] codeArray = code.ToCharArray(); // convert your code string to a char[] array
for (int i = 0; i < codeArray.Length; i++)
{
switch (codeArray[i]) // Get the char at position i in the array
{
case '#': // if the character at i is '#'
codeArray[i] = 'a'; // Change the character at i to 'a'
break; // break out of the switch statement - we don't need to evaluate anything else
case '#': // if the character at i is '#'
codeArray[i] = 'e'; // Change the character at i to 'e'
break; // break out of the switch statement - we don't need to evaluate anything else
// repeat for everything else you need to replace!
}
}
return new String(codeArray); // Once you're all done, create a string from your deciphered array and return it
}
There are a bunch of different ways of doing it. Doing string concatenation in a loop (as shown by #Acex) is generally frowned upon; it spins out a lot of "garbage" and can slow things down. The Stringbuilder class is generally a better option. My code uses Stringbuilders (well, the same one over and over - I clear it in between).
Here are several ways of doing the same thing:
const string encoded = "H#ll*, H*w #r# y*+?";
//good old fashioned C-style/brute force:
var buf = new StringBuilder();
foreach (var c in encoded){
switch(c){
case '#':
buf.Append('a');
break;
case '#':
buf.Append('e');
break;
case '^':
buf.Append('i');
break;
case '*':
buf.Append('o');
break;
case '+':
buf.Append('u');
break;
default:
buf.Append(c);
break;
}
}
var result = buf.ToString();
//using a lookup table (easily extensible)
buf.Clear();
var decodeDict = new Dictionary<char, char>{
{'#', 'a'},
{'#', 'e'},
{'^', 'i'},
{'*', 'o'},
{'+', 'u'},
};
foreach (var c in encoded){
if (decodeDict.Keys.Contains(c)){
buf.Append(decodeDict[c]);
} else {
buf.Append(c);
}
}
result = buf.ToString();
//something completely different
//instead of iterating through the string, iterate through the decoding dictionary
buf.Clear();
var working = new StringBuilder(encoded.Length);
working.Append(encoded);
foreach (var pair in decodeDict){
working.Replace(pair.Key, pair.Value);
}
result = working.ToString();
In each case, result holds, well, the result. Put a breakpoint right after each result assignment and see what's happened.
I'm not providing a lot of comments, step through the code, look up the classes and figure out what I'm doing (you are the student, after all).
It's really as simple as doing this:
public static string Decipher(string code)
{
var map = new Dictionary<char, char>()
{
{ '#', 'a' },
{ '#', 'e' },
{ '^', 'i' },
{ '*', 'o' },
{ '+', 'u' },
};
char[] array = code.ToCharArray();
array = array.Select(x => map.ContainsKey(x) ? map[x] : x).ToArray();
return new string(array);
}
Now you can do this:
string cipher = "*+tp+t";
string plain = Decipher(cipher);
Console.WriteLine(cipher);
Console.WriteLine(plain);
This outputs:
*+tp+t
output
For the sake of alternative
And when you will be allowed to use existing methods.
you can write something like this:
private Dictionary<char, char> mapping = new Dictionary<char, char>()
{
{ '#', 'a' },
{ '#', 'e' },
{ '^', 'i' },
{ '*', 'o' },
{ '+', 'u' },
};
private string Decrypt(string encryptedString) =>
string.Concat(encryptedString.Select(s => mapping.ContainsKey(s) ? mapping[s] : s));
And usage:
string result = Decrypt(encryptedString);
References: DotNetFiddle Example

Count Vowel and Consonant C#

Question
Take input of 1 character from user. It can be the vowel or consonant.
After the user gives input so it will ask do you want to input the character again for Yes press Y and for No press N.
When the user says No, you have to show how much vowel and how much consonant use has input.
Please do this question using For loop. I think array must be use. I did this code it counting vowel and consonant and spacing. But I cant take the input multiple times.
My code doesnn't run multiple times. I can only write sentence or a character in a line so it will only count that. But I want to ask the user to enter a character again.
I want my code to run multiple times so the user can give input multiple times as I explain my question.
using System;
public class vowelConsonant
{
public static void Main()
{
int vowels = 0;
int consonant = 0;
int space = 0;
Console.WriteLine("Enter a Sentence or a Character");
string v = Console.ReadLine().ToLower();
for (int i = 0; i < v.Length; i++)
{
if (v[i] == 'a' || v[i] == 'e' || v[i] == 'i' || v[i] == 'o' || v[i] == 'u')
{
vowels++;
}
else if (char.IsWhiteSpace(v[i]))
{
space++;
}
else
{
consonant++;
}
}
Console.WriteLine("Your total number of vowels is: {0}", vowels);
Console.WriteLine("Your total number of constant is: {0}", consonant);
Console.WriteLine("Your total number of space is: {0}", space);
Console.ReadLine();
}
}
Thanks
Just put an infinite loop around the whole thing.
using System;
public class vowelConsonant
{
public static void Main()
{
// Infinite loop.
while (true)
{
int vowels = 0;
int consonant = 0;
int space = 0;
Console.WriteLine("Enter a Sentence or a Character");
string v = Console.ReadLine().ToLower();
for (int i = 0; i < v.Length; i++)
{
if (v[i] == 'a' || v[i] == 'e' || v[i] == 'i' || v[i] == 'o' || v[i] == 'u')
{
vowels++;
}
else if (char.IsWhiteSpace(v[i]))
{
space++;
}
else
{
consonant++;
}
}
Console.WriteLine("Your total number of vowels is: {0}", vowels);
Console.WriteLine("Your total number of constant is: {0}", consonant);
Console.WriteLine("Your total number of space is: {0}", space);
}
}
}
This application to count vowels and consonants letters in a sentence.
This is another solution with less line of codes with understanding idea of using loop and nested loop with char arrays.
Application interface with controls 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 button1_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 simply find the required vowels and consonant counts using Regex.Matches() function.
Below is the working code snippet:
public static void Main()
{
Console.WriteLine("Enter a Sentence or a Character");
string input = Console.ReadLine().ToLower();
string vowels = #"[aeiouAEIOU]+"; //regular expression to match vowels
string consonants = #"[^aeiouAEIOU]+"; //regular expression to match consonants
string space = #"[\S]+";
int vowLength = new Regex(vowels).Matches(input).Count;
int conLength = new Regex(consonants).Matches(input).Count;;
int spLength = new Regex(space).Matches(input).Count;;
Console.WriteLine("Your total number of vowels is: {0}", vowLength);
Console.WriteLine("Your total number of constant is: {0}", conLength);
Console.WriteLine("Your total number of space is: {0}", spLength);
}

Display most used vowel in a string c#

I count the vowels and the consonant in a string. Now I want to display the most used vowel and consonant in this string the code that I have for the counting
private void Button_Click(object sender, RoutedEventArgs e)
{
char[] charArray = new char[] { 'a', 'e', 'i', 'o', 'u' };
string line = testBox.Text.ToLower();
char letter;
int vowels = 0;
int sug = 0;
for (int i = 0; i < line.Length; i++)
{
letter = line[i];
if (charArray.Contains(letter))
vowels++;
if (!charArray.Contains(letter))
sug++;
}
MessageBox.Show("number of vowels is" + vowels.ToString());
MessageBox.Show("number of vowels is" + sug.ToString());
}
Make the vowels and constants lists instead of an int counter then you can manipulate each list at a later stage.
private void Button_Click(object sender, RoutedEventArgs e)
{
char[] charArray = new char[] { 'a', 'e', 'i', 'o', 'u' };
string line = testBox.Text.ToLower();
char letter;
List<char> vowels = new List<char>();
List<char> sug = new List<char>();
for (int i = 0; i < line.Length; i++)
{
letter = line[i];
if (charArray.Contains(letter))
vowels.Add(letter);
if (!charArray.Contains(letter))
sug.Add(letter);
}
MessageBox.Show("number of vowels is" + vowels.Count);
MessageBox.Show("number of vowels is" + sug.Count);
MessageBox.Show("most used vowel: " + vowels.GroupBy(x => x).OrderByDescending(xs => xs.Count()).Select(xs => xs.Key).First());
MessageBox.Show("most used constant: " + sug.GroupBy(x => x).OrderByDescending(xs => xs.Count()).Select(xs => xs.Key).First());
}
Ok here is one way to do it. It may be a little more advanced due to the heavy use of linq and lambadas. It does work, but I would recommend breaking some of the functionality out into functions.
char[] charArray = new char[] { 'a', 'e', 'i', 'o', 'u' };
string line = "bbcccaaaeeiiiioouu";
var vowelCounts = new Dictionary<char, int>();
foreach(var vowel in charArray)
{
vowelCounts.Add(vowel, line.Count(charInString => vowel == charInString));
}
var consonantCounts = new Dictionary<char, int>();
foreach(var consonant in line.Where(charInString => !charArray.Contains(charInString)).Distinct())
{
consonantCounts.Add(consonant, line.Count(charInString => consonant == charInString));
}
KeyValuePair<char, int> mostUsedVowel = vowelCounts.OrderBy(Entry => Entry.Value).FirstOrDefault();
KeyValuePair<char, int> mostUsedConsonant = consonantCounts.OrderBy(Entry => Entry.Value).FirstOrDefault();
string output1 = String.Format("The Vowel '{0}' was used {1} times", mostUsedVowel.Key, mostUsedVowel.Value);
string output2 = String.Format("The Consonant '{0}' was used {1} times", mostUsedConsonant.Key, mostUsedConsonant.Value);
MessageBox.Show(output1);
MessageBox.Show(output2);
As String is an enumerable of characters You can use LINQs GroupBy function to group by characters an then do all kinds of evaluation with the groups:
http://dotnetfiddle.net/dmLkVb
var grouped = line.GroupBy(c=> c);
var vowels = grouped.Where(g => charArray.Contains(g.Key));
var mostUsed = vowels.OrderBy(v => v.Count()).Last();
Console.WriteLine("Distinct characters: {0}:", grouped.Count());
Console.WriteLine("Vowels: {0}:", vowels.Count());
Console.WriteLine("Most used vowel: {0} - {1}:", mostUsed.Key, mostUsed.Count());

Regex - Improve search and add third group

This is kind of improvement of my previous question: c# generate random string based on pattern
I have code as below:
class Generator
{
private static readonly Random R = new Random();
private static readonly char[] L = { 'a', 'b', 'c', 'd', 'e' };
private static readonly char[] U = { 'A', 'B', 'C', 'D', 'E' };
private static readonly char[] S = { '!', '#', '#', '$', '%' };
public static string FromPattern(string pattern)
{
return Regex.Replace(pattern, #"\[([Ccds])(?::([\d]+))?\]", ReplaceSingleMatch);
}
private static string ReplaceSingleMatch(Match m)
{
int length;
if (!int.TryParse(m.Groups[2].Value, out length))
length = 1;
var output = new StringBuilder();
while (output.Length != length)
{
switch (m.Groups[1].Value)
{
case "d"://digits
output.Append(R.Next(0, 9));
break;
case "c"://lowercase char
output.Append(L[R.Next(L.Length)]);
break;
case "C"://uppercase char
output.Append(U[R.Next(U.Length)]);
break;
case "s"://special char
output.Append(S[R.Next(S.Length)]);
break;
}
}
return output.ToString();
}
}
Using above I can write:
Generator.FromPattern("ID: [d:3][c:2]#[C][s:2]")
And I will get sample output like : ID: 263ac#D$!
So when I enter [d] I get single digit, if I enter [d:5] I get 5 digits.
What I would like to add is range, so when I enter [d:2-5] I would get randomly from 2 to 5 random digits.
My biggest problem is regex, rest is easy :)
I need my regex to search below groups:
[d],
[d:3] (it must be number after colon),
[d:2-5] (two numbers separated by dash)
Any suggestion about improvements are welcome!
Awesome tool for regular expressions : http://www.ultrapico.com/Expresso.htm
Here's the expression I came up with (with named capture groups) :
\[(?<type>[Ccds])(:(?<a>[\d]+)(-(?<b>[\d]+))?)?\]

Categories

Resources