Better solution to write out cases - c#

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

Related

C# Count the words in a string

How do I do this with basic string functions and loop? I want to count the words in a string. My problem is that it only works when the user do not use multiple spaces.
Here is my code:
string phrase;
int word = 1;
Console.Write("Enter a phrase: ");
phrase = Console.ReadLine();
for (int i = 0; i<phrase.Length; i++)
{
if (name[i] == ' ')
{
word++;
}
}
Console.WriteLine(word);
One approach is to use a regular expression to "condense" all consecutive spaces into a single instance. Then the job is simple.
var str = "aaa bb cccc d e";
var regex = new Regex(#"\s+");
Console.WriteLine(regex.Replace(str, " ")?.Split(' ')?.Count());
If you can use LINQ, i suggest this approach:
string[] source = phrase.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries);
var matchQuery = from word in source
select word;
int wordCount = matchQuery.Count();
Console.WriteLine(wordCount);
I would create an array with string data type. Then I would use Split method when reading the data. This would split the entire text anytime you see a defined character (character is a one letter or character). In your case the defined character would be empty space; that is ' '. So my formula would be something like:
string phrase;
string[] seperated; // this is where you would split the full name
int word = 1;
Console.Write("Enter a phrase: ");
phrase = Console.ReadLine();
seperated=phrase.Split(' ');
for (int i = 0; i<seperated.Length; i++)
{
Console.WriteLine(seperated[i]); // this would print each word one by one
}
Once capture the full name split in seperated array, than you can use the seperated name, last name etc the way you want. seperated[0]= would be the first word, seperated[1] would be the second word... if the name consists of total 5 words than the last word could be reached by seperated[4].
Instead of the for loop you could use Split() and Linq:
var splitPhrase = phrase.Split(' ');
var wordCount = splitPhrase.Count(x=>x != "");
or use StringSplitOptions, as per comment:
var words = phrase.Split(' ', StringSplitOptions.RemoveEmptyEntrie);
var wordCount = words.Count();
You can use regex pattern:
\S matches anything but a whitespace
string str = "Test words test"
MatchCollection collection = Regex.Matches(str, #"[\S]+");
int numberOfWords = collection.Count;
First of all, we have to define word. If word is
Any non empty sequence of letters
we can use a simple regular expression pattern: \p{L}+
Code:
using System.Text.RegularExpressions;
...
int word = Regex.Matches(phrase, #"\p{L}+").Count;
Edit: in case you don't want regular expressions you can implement FSM - Finite State Machine:
int word = 0;
bool inWord = false;
foreach (var c in phrase)
if (char.IsLetter(c)) {
if (!inWord) // we count beginnings of each word
word += 1;
inWord = true;
}
else
inWord = false;
Here we have two states: - inWord == true, false - which are if character is within some word or not. Having these states we can count all the words beginnings.
You can achieve this by using the following function.It only returns the no. of words in the given sentence.
public int totalWords(string sentence) {
int wordCount = 0;
for (int i = 0; i < sentence.Length - 1; i++)
{
if (sentence[i] == ' ' && Char.IsLetter(sentence[i + 1]) && (i > 0))
{
wordCount++;
}
}
wordCount++;
return wordCount;
}
Assuming your words are separated by a space you can just Split the string and get the length of the resulting array:
string[] words = phrase.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
int numberOfWords = words.Length;

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

Determine which character was used in String.Split()

If I am using String.Split() how can I find out which character caused the split? For instance, when "Apple|Car" splits, I want to know that it did so via the pipe character and not a comma or hyphen.
When I see the "Car" item, I'd want to know it was split from "Apple" with a pipe, and split from "Plane" with a comma.
var splitChars = new Char [] {'|', ',', '-'};
string item1 = "Apple|Car,Plane-Truck";
var mySplit = item1.Split(splitChars);
string myMessage = "Apple|Car,Plane-Truck";
//Break apart string
var splits = myMessage.Split(new Char[] { '|', ',', '-' });
int accumulated_length = 0;
foreach (string piece in splits)
{
accumulated_length += piece.Length + 1;
if (accumulated_length <= myMessage.Length)
{
Console.WriteLine("{0} was split at {1}", piece, myMessage[accumulated_length - 1]);
}
else
{
Console.WriteLine("{0} was the last one", piece);
}
}
It will split on all of them in the example you've given. but in general, you would just see which of the defined split characters are contained in the string:
var sourceString = "Apple|Car,Plane-Truck";
var allSplitChars = new[] {'|', ',', '-', '.', '!', '?'};
// Find only the characters that are contained in the source string
List<char> charsUsedToSplit = allSplitChars.Where(sourceString.Contains).ToList();
Any characters in the list will be used for the split.. can you clarify what you're actually trying to do? in your example the tokens after the split will be "Apple", "Car", "Plane", "Truck" so each of your characters will be used to split..
If you're trying to determine which character caused the split for each token, then perhaps you might implement the split yourself and keep track:
List<Tuple<String, Char>> Splitter(string msg, char[] chars) {
var offset = 0;
var splitChars = new HashSet<char>(chars);
var splits = new List<Tuple<String, Char>>();
for(var idx = 0; idx < msg.Length; idx++) {
if (splitChars.Contains(msg[idx])) {
var split = Tuple.Create(msg.Substring(offset, idx - offset), msg[idx]);
splits.Add(split);
offset = idx + 1;
}
}
return splits;
}
string myMessage = "Apple|Car,Plane-Truck";
var splits = Splitter(myMessage, new [] {'|', ',', '-'});
foreach (string piece in splits)
{
Console.WriteLine("word: {0}, split by: {1}", piece.Item1, piece.Item2);
}

C# replace different characters in a string

Everyone knows how to replace a character in a string with:
string text = "Hello World!";
text = text.Replace("H","J");
but what I need is to replace multiple characters in a string
something like:
string text = textBox1.Text;
text = text.Replace("a","b")
text = text.Replace("b","a")
now the result is aa , but if the user types ab I want the result to be ba
There's multiple ways to do this.
Using a loop
char[] temp = input.ToCharArray();
for (int index = 0; index < temp.Length; index++)
switch (temp[index])
{
case 'a':
temp[index] = 'b';
break;
case 'b':
temp[index] = 'a';
break;
}
string output = new string(temp);
This will simply copy the string to a character array, fix each character by itself, then convert the array back into a string. No risk of getting any of the characters confused with any of the others.
Using a regular expression
You can exploit this overload of Regex.Replace:
public static string Replace(
string input,
string pattern,
MatchEvaluator evaluator
)
This takes a delegate that will be called for each match, and return the final result. The delegate is responsible for returning what each match should be replaced with.
string output = Regex.Replace(input, ".", ma =>
{
if (ma.Value == "a")
return "b";
if (ma.Value == "b")
return "a";
return ma.Value;
});
For your particular requirement I would suggest you to use like the following:
string input = "abcba";
string outPut=String.Join("",input.ToCharArray()
.Select(x=> x=='a'? x='b':
(x=='b'?x='a':x))
.ToArray());
The output string will be bacab for this particular input
Do not call String.Replace multiple times for the same string! It creates a new string every time (also it has to cycle through the whole string every time) causing memory pressure and processor time waste if used a lot.
What you could do:
Create a new char array with the same length as the input string. Iterate over all chars of the input strings. For every char, check whether it should be replaced. If it should be replaced, write the replacement into the char array you created earlier, otherwise write the original char into that array. Then create a new string using that char array.
string inputString = "aabbccdd";
char[] chars = new char[inputString.Length];
for (int i = 0; i < inputString.Length; i++)
{
if (inputString[i] == 'a')
{
chars[i] = 'b';
}
else if (inputString[i] == 'b')
{
chars[i] = 'a';
}
else
{
chars[i] = inputString[i];
}
}
string outputString = new string(chars);
Consider using a switch when intending to replace a lot of different characters.
Use should use StringBuilder when you are concatenating many strings in a loop like this, so I suggest the following solution:
StringBuilder sb = new StringBuilder(text.Length);
foreach(char c in text)
{
sb.Append(c == 'a' ? 'b' : 'a');
}
var result = sb.ToString();

Replace consecutive characters with same single character

I was just wondering if there is a simple way of doing this. i.e. Replacing the occurrence of consecutive characters with the same character.
For eg: - if my string is "something likeeeee tttthhiiissss" then my final output should be "something like this".
The string can contain special characters too including space.
Can you guys suggest some simple way for doing this.
This should do it:
var regex = new Regex("(.)\\1+");
var str = "something likeeeee!! tttthhiiissss";
Console.WriteLine(regex.Replace(str, "$1")); // something like! this
The regex will match any character (.) and \\1+ will match whatever was captured in the first group.
string myString = "something likeeeee tttthhiiissss";
char prevChar = '';
StringBuilder sb = new StringBuilder();
foreach (char chr in myString)
{
if (chr != prevChar) {
sb.Append(chr);
prevChar = chr;
}
}
How about:
s = new string(s
.Select((x, i) => new { x, i })
.Where(x => x.i == s.Length - 1 || s[x.i + 1] != x.x)
.Select(x => x.x)
.ToArray());
In english, we are creating a new string based on a char[] array. We construct that char[] array by applying a few LINQ operators:
Select: Capture the index i along with the current character x.
Filter out charaters that are not the same as the subsequent character
Select the character x.x back out of the anonymous type x.
Convert back to a char[] array so we can pass to constructor of string.
Console.WriteLine("Enter any string");
string str1, result="", str = Console.ReadLine();
char [] array= str.ToCharArray();
int i=0;
for (i = 0; i < str.Length;i++ )
{
if ((i != (str.Length - 1)))
{ if (array[i] == array[i + 1])
{
str1 = str.Trim(array[i]);
}
else
{
result += array[i];
}
}
else
{
result += array[i];
}
}
Console.WriteLine(result);
In this code the program ;
will read the string as entered from user
2.Convert the string in char Array using string.ToChar()
The loop will run for each character in string
each character stored in that particular position in array will be compared to the character stored in position one greater than that . And if the characters are found same the character stored in that particular array would be trimmed using .ToTrim()
For last character the loop will show error of index out of bound as it would be the last position value of the array. That's why I used * if ((i != (str.Length - 1)))*
6.The characters left after trimming are stored in result in concatenated form .
word = "something likeeeee tttthhiiissss"
re.sub(r"(.)\1+", r"\1",word)

Categories