String Get/Update Numeric Value After Specific Character - c#

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());
}

Related

How to swap first and last letters in each word?

I have a practice session on C#, and I want to know how can I swap first and last characters in each word of a sentence and lower case them. I have created a string array that represents each word, and in an inner for loop, I am iterating each character in each word. There is my code.
using System;
namespace ConsoleApp11
{
class Program
{
static void Main(string[] args)
{
string text = "Hello world";
string[] words = text.Split(" ");
string output = "";
for(int i = 0; i < words.Length; i++)
{
for(int j = 0; j < words[i].Length; j++)
{
if (char.IsUpper(words[i][j]))
{
output += char.ToLower(words[i][j]);
}
else
{
output += words[i][j];
}
}
output += " ";
}
Console.WriteLine(output);
}
}
}
Because It is sunday :-), here is the complete code (my explanations were to difficult):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string output = "ABCD EFGH IJKL";
string[] outputs = output.Split(' ');
char[] chars;
string first,last;
string flower,llower;
string result = string.Empty;
for (int i = 0; i < outputs.Length; i++)
{
chars = outputs[i].ToCharArray();
first = new string(chars[0], 1);
last = new string(chars[chars.Length - 1], 1);
flower = first.ToLower();
llower = last.ToLower();
chars[chars.Length - 1] = flower.ToCharArray()[0];
chars[0] = llower.ToCharArray()[0];
result += new string(chars);
result += " ";
}
Console.WriteLine(output);
Console.WriteLine(result);
Console.ReadLine();
}
}
}
Result: dBCa hFGe lJKi
How do I lowercase and reverse the first and last characters in each word.
Solution using a regular expresion
We could use the Split() method of String or Regex, to split on non-word characters, but then we wouldn't be able to output the correct characters between each word, unless we only split on a single character.
using System;
using System.Text.RegularExpressions;
namespace CS_Regex {
class Program {
static void Main(string[] args) {
// Match words using a regular experession
string match_word = #"(\w+)";
string match_non_word = #"([^\w]*)";
string pattern = match_non_word + match_word + match_non_word;
Regex rx = new Regex(pattern, RegexOptions.Compiled);
// Do the match on example data
string data = "Hello world";
MatchCollection matches = rx.Matches(data);
// Output the matches
foreach (Match match in matches) {
// Get the text before and after the word
string non_word_before = match.Groups[1].ToString();
string non_word_after = match.Groups[3].ToString();
// Get the matched word
string word = match.Groups[2].ToString();
// Lower case the first and last characters and swap them
string firstchar = (word.Length > 0) ? $"{char.ToLower(word[0])}" : "";
string lastchar = (word.Length > 1) ? $"{char.ToLower(word[word.Length - 1])}" : "";
string middle = (word.Length > 2) ? word.Substring(1, word.Length - 2) : "";
string newword = lastchar + middle + firstchar;
// Output the new word
Console.Write(non_word_before + newword + non_word_after);
}
} // Main
} // class
} // namespace
Output from the proposed solution
oellh dorlw
Links
Regular Expression Language - Quick Reference
Regex Class
Regex.Match Method
one idea is to convert each string into an array of chars then, for each array of caracters, get the first and last caracter and convert those caratcter into string (of one caracter) in order to use the lower function. Then replace the first and last letters with the lower caracters by inverting the 0 index with the last index, in order to swap.
Example for first letter (NO swap just for explaination):
string output = "ABCD";
char[] chars = output.ToCharArray();
string firt = new string(chars[0],1);
string lower = firt.ToLower();
string result = output.Replace(chars[0].ToString(), lower.ToString());
For the swap of the first letter to the last
Here is a complete code for first letter: result is "BCDa". For the last letter, it is the same idea
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string output = "ABCD";
char[] chars = output.ToCharArray();
string firt = new string(chars[0],1);
string lower = firt.ToLower();
chars[chars.Length-1] = lower.ToCharArray()[0];
string result = new string(chars);
Console.WriteLine(output);
Console.WriteLine(result);
Console.ReadLine();
}
}
}

Extract number from string with C# Regex [duplicate]

I have a requirement to find and extract a number contained within a string.
For example, from these strings:
string test = "1 test"
string test1 = " 1 test"
string test2 = "test 99"
How can I do this?
\d+ is the regex for an integer number. So
//System.Text.RegularExpressions.Regex
resultString = Regex.Match(subjectString, #"\d+").Value;
returns a string containing the first occurrence of a number in subjectString.
Int32.Parse(resultString) will then give you the number.
Here's how I cleanse phone numbers to get the digits only:
string numericPhone = new String(phone.Where(Char.IsDigit).ToArray());
go through the string and use Char.IsDigit
string a = "str123";
string b = string.Empty;
int val;
for (int i=0; i< a.Length; i++)
{
if (Char.IsDigit(a[i]))
b += a[i];
}
if (b.Length>0)
val = int.Parse(b);
use regular expression ...
Regex re = new Regex(#"\d+");
Match m = re.Match("test 66");
if (m.Success)
{
Console.WriteLine(string.Format("RegEx found " + m.Value + " at position " + m.Index.ToString()));
}
else
{
Console.WriteLine("You didn't enter a string containing a number!");
}
What I use to get Phone Numbers without any punctuation...
var phone = "(787) 763-6511";
string.Join("", phone.ToCharArray().Where(Char.IsDigit));
// result: 7877636511
Regex.Split can extract numbers from strings. You get all the numbers that are found in a string.
string input = "There are 4 numbers in this string: 40, 30, and 10.";
// Split on one or more non-digit characters.
string[] numbers = Regex.Split(input, #"\D+");
foreach (string value in numbers)
{
if (!string.IsNullOrEmpty(value))
{
int i = int.Parse(value);
Console.WriteLine("Number: {0}", i);
}
}
Output:
Number: 4
Number: 40
Number: 30
Number: 10
if the number has a decimal points, you can use below
using System;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
//Your code goes here
Console.WriteLine(Regex.Match("anything 876.8 anything", #"\d+\.*\d*").Value);
Console.WriteLine(Regex.Match("anything 876 anything", #"\d+\.*\d*").Value);
Console.WriteLine(Regex.Match("$876435", #"\d+\.*\d*").Value);
Console.WriteLine(Regex.Match("$876.435", #"\d+\.*\d*").Value);
}
}
}
results :
"anything 876.8 anything" ==> 876.8
"anything 876 anything" ==> 876
"$876435" ==> 876435
"$876.435" ==> 876.435
Sample : https://dotnetfiddle.net/IrtqVt
Here's a Linq version:
string s = "123iuow45ss";
var getNumbers = (from t in s
where char.IsDigit(t)
select t).ToArray();
Console.WriteLine(new string(getNumbers));
Another simple solution using Regex
You should need to use this
using System.Text.RegularExpressions;
and the code is
string var = "Hello3453232wor705Ld";
string mystr = Regex.Replace(var, #"\d", "");
string mynumber = Regex.Replace(var, #"\D", "");
Console.WriteLine(mystr);
Console.WriteLine(mynumber);
You can also try this
string.Join(null,System.Text.RegularExpressions.Regex.Split(expr, "[^\\d]"));
Here is another Linq approach which extracts the first number out of a string.
string input = "123 foo 456";
int result = 0;
bool success = int.TryParse(new string(input
.SkipWhile(x => !char.IsDigit(x))
.TakeWhile(x => char.IsDigit(x))
.ToArray()), out result);
Examples:
string input = "123 foo 456"; // 123
string input = "foo 456"; // 456
string input = "123 foo"; // 123
Just use a RegEx to match the string, then convert:
Match match = Regex.Match(test , #"(\d+)");
if (match.Success) {
return int.Parse(match.Groups[1].Value);
}
string input = "Hello 20, I am 30 and he is 40";
var numbers = Regex.Matches(input, #"\d+").OfType<Match>().Select(m => int.Parse(m.Value)).ToArray();
You can do this using String property like below:
return new String(input.Where(Char.IsDigit).ToArray());
which gives only number from string.
For those who want decimal number from a string with Regex in TWO line:
decimal result = 0;
decimal.TryParse(Regex.Match(s, #"\d+").Value, out result);
Same thing applys to float, long, etc...
var match=Regex.Match(#"a99b",#"\d+");
if(match.Success)
{
int val;
if(int.TryParse(match.Value,out val))
{
//val is set
}
}
The question doesn't explicitly state that you just want the characters 0 to 9 but it wouldn't be a stretch to believe that is true from your example set and comments. So here is the code that does that.
string digitsOnly = String.Empty;
foreach (char c in s)
{
// Do not use IsDigit as it will include more than the characters 0 through to 9
if (c >= '0' && c <= '9') digitsOnly += c;
}
Why you don't want to use Char.IsDigit() - Numbers include characters such as fractions, subscripts, superscripts, Roman numerals, currency numerators, encircled numbers, and script-specific digits.
Here is another simple solution using Linq which extracts only the numeric values from a string.
var numbers = string.Concat(stringInput.Where(char.IsNumber));
Example:
var numbers = string.Concat("(787) 763-6511".Where(char.IsNumber));
Gives: "7877636511"
var outputString = String.Join("", inputString.Where(Char.IsDigit));
Get all numbers in the string.
So if you use for examaple '1 plus 2' it will get '12'.
Extension method to get all positive numbers contained in a string:
public static List<long> Numbers(this string str)
{
var nums = new List<long>();
var start = -1;
for (int i = 0; i < str.Length; i++)
{
if (start < 0 && Char.IsDigit(str[i]))
{
start = i;
}
else if (start >= 0 && !Char.IsDigit(str[i]))
{
nums.Add(long.Parse(str.Substring(start, i - start)));
start = -1;
}
}
if (start >= 0)
nums.Add(long.Parse(str.Substring(start, str.Length - start)));
return nums;
}
If you want negative numbers as well simply modify this code to handle the minus sign (-)
Given this input:
"I was born in 1989, 27 years ago from now (2016)"
The resulting numbers list will be:
[1989, 27, 2016]
An interesting approach is provided here by Ahmad Mageed, uses Regex and StringBuilder to extract the integers in the order in which they appear in the string.
An example using Regex.Split based on the post by Ahmad Mageed is as follows:
var dateText = "MARCH-14-Tue";
string splitPattern = #"[^\d]";
string[] result = Regex.Split(dateText, splitPattern);
var finalresult = string.Join("", result.Where(e => !String.IsNullOrEmpty(e)));
int DayDateInt = 0;
int.TryParse(finalresult, out DayDateInt);
I have used this one-liner to pull all numbers from any string.
var phoneNumber = "(555)123-4567";
var numsOnly = string.Join("", new Regex("[0-9]").Matches(phoneNumber)); // 5551234567
string verificationCode ="dmdsnjds5344gfgk65585";
string code = "";
Regex r1 = new Regex("\\d+");
Match m1 = r1.Match(verificationCode);
while (m1.Success)
{
code += m1.Value;
m1 = m1.NextMatch();
}
Did the reverse of one of the answers to this question:
How to remove numbers from string using Regex.Replace?
// Pull out only the numbers from the string using LINQ
var numbersFromString = new String(input.Where(x => x >= '0' && x <= '9').ToArray());
var numericVal = Int32.Parse(numbersFromString);
Here is my Algorithm
//Fast, C Language friendly
public static int GetNumber(string Text)
{
int val = 0;
for(int i = 0; i < Text.Length; i++)
{
char c = Text[i];
if (c >= '0' && c <= '9')
{
val *= 10;
//(ASCII code reference)
val += c - 48;
}
}
return val;
}
static string GetdigitFromString(string str)
{
char[] refArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
char[] inputArray = str.ToCharArray();
string ext = string.Empty;
foreach (char item in inputArray)
{
if (refArray.Contains(item))
{
ext += item.ToString();
}
}
return ext;
}
here is my solution
string var = "Hello345wor705Ld";
string alpha = string.Empty;
string numer = string.Empty;
foreach (char str in var)
{
if (char.IsDigit(str))
numer += str.ToString();
else
alpha += str.ToString();
}
Console.WriteLine("String is: " + alpha);
Console.WriteLine("Numeric character is: " + numer);
Console.Read();
You will have to use Regex as \d+
\d matches digits in the given string.
string s = "kg g L000145.50\r\n";
char theCharacter = '.';
var getNumbers = (from t in s
where char.IsDigit(t) || t.Equals(theCharacter)
select t).ToArray();
var _str = string.Empty;
foreach (var item in getNumbers)
{
_str += item.ToString();
}
double _dou = Convert.ToDouble(_str);
MessageBox.Show(_dou.ToString("#,##0.00"));
Using #tim-pietzcker answer from above, the following will work for PowerShell.
PS C:\> $str = '1 test'
PS C:\> [regex]::match($str,'\d+').value
1

Better solution to write out cases

My program counts vowels and consonants from an entered string of text. Is there a way to make my cases more simplified and look less like a cluster? Just wondering if there is a better way to write them out.
Since you have one method which checks if char is letter, you could check if current char is vowel or consonant using Contains method.
With this method, you can find out the counts for both vowels and consonants using a ternary operator.
if(char.IsLetter(ch)){
"aeiouAEIOU".Contains(ch) ? vowelCount++ : consonantCount++;
}
Try use regex
var s = "Test, One two three";
Regex r = new Regex("[a-zA-Z]");
MatchCollection m = r.Matches(s);
Regex rv = new Regex("[aeiouAEIOU]");
MatchCollection mv = rv.Matches(s);
var vowels = mv.Count;
var consonants = m.Count - mv.Count;
You might want to punch me in the face but here you go with bitmask
string str = "Test. One two three.";
// zyxwvutsrqponmlkjihgfedcba ZYXWVUTSRQPONMLKJIHGFEDCBA
long bitmask = 0b0000010000010000010001000100000000000100000100000100010001;
int vowels = 0, consonants = 0;
foreach (var ch in str)
{
if(char.IsLetter(ch))
{
int shift = ch - 'A';
if (((bitmask >> shift) & 1) == 1) vowels++;
else consonants++;
}
}
Console.WriteLine("Vowels: " + vowels);
Console.WriteLine("Consonants: " + consonants);
or you could use this magic number for bitmask 4575140898685201
Here is the code snippet which gives you the desired output.
string text = "This is a Demo Content";
text = text = Regex.Replace(text, #"[^a-zA-Z]+", "");
char[] vowels = new char[] { 'a', 'e', 'i', 'o', 'u','A','E','I','O','U' };
var vowelsCount = text.Count(x => vowels.Contains(x));
var consonantCount = text.Count(x => !vowels.Contains(x));

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]));
}
}

C# Count Vowels

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();
}

Categories