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]));
}
}
Related
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());
}
I'm new to programming C#, and I've learned almost all of my information from:
http://unity3d.com/learn/tutorials/modules/beginner/scripting, youtube, this site, and many programming tutorial sites found through google.
In my monobehavior code within Unity, I am ultimately trying to make a base 12 calculator.
To do so, I need 12 numerals, I wrote a string array to represent them:
private string[] numerals = {"0","1","2","3","4","5","6","7","8","9","X","E"};
public string thisNum;
my Start and calcNum functions:
void Start ()
{
thisNum = numerals[10];
calcNum ();
}
void calcNum ()
{
print(thisNum);
}
This is great, I can type: print (thisNum);, and get back X.
But, how do I get: print (thisNum + thisNum) to return 18?
I know it's not an integer, therefore it can not add 2 strings to get a sum, you instead get: XX.
So then, how do I represent X as this many:
o o o, o o o, o o o, o
and not just the letter X. I reset this project about 6 times now.
I was thinking of for-loops or if (X) than 10, but, I always end up using base 10 to represent numbers, which is kind of lame.
I just need a little push to get going in the right direction, and would really appreciate the help,
thank you.
This might help.
Start with an array of characters rather than strings.
var numerals = new []
{
'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'X', 'E',
};
Create a couple of dictionaries to return the base 10 value of each numerals and to perform the reverse look-up.
var nis =
numerals
.Select((n, i) => new { n, i })
.ToArray();
var n2i = nis.ToDictionary(_ => _.n, _ => _.i);
var i2n = nis.ToDictionary(_ => _.i, _ => _.n);
Then to convert between base 10 and base 12 you need a couple of helper functions.
Func<int, IEnumerable<char>> getReversedNumerals = null;
getReversedNumerals = n =>
{
IEnumerable<char> results =
new [] { i2n[n % 12], };
var n2 = n / 12;
if (n2 > 0)
{
results = results.Concat(getReversedNumerals(n2));
}
return results;
};
Func<IEnumerable<char>, int, int> processReversedNumerals = null;
processReversedNumerals = (cs, x) =>
cs.Any()
? x * n2i[cs.First()]
+ processReversedNumerals(cs.Skip(1), x * 12)
: 0;
Now you can define the conversion functions in terms of the helpers.
Func<int, string> convertToBase12 =
n => new String(getReversedNumerals(n).Reverse().ToArray());
Func<string, int> convertToBase10 =
t => processReversedNumerals(t.ToCharArray().Reverse(), 1);
And finally you can perform conversions:
var b10 = convertToBase10("3EX2"); //6890
var b12 = convertToBase12(6890); //3EX2
It depends on how you're taking in, and storing the values.
Assuming you're storing them as their base 12 string, you'll need conversion methods back and forth between the integer base10 value it represents, and the string value that you're using to represent it.
public String Base12Value(int base10)
{
String retVal = "";
while (base10 > 0)
{
//Grab the mod of the value, store the remainder as we build up.
retVal = (base10 % 12).ToString() + retVal;
//remove the remainder, divide by 12
base10 = (base10 - (base10 % 12)/12);
}
return retVal;
}
public int Base10Value(String base12)
{
int retVal = 0;
for (int i = 1; i <= base12.Length; i++)
{
int tmpVal = 0;
char chr = base12[base12.Length-i];
//Grab out the special chars;
if (chr == 'X')
{
tmpVal = 10;
} else if (chr == 'E')
{
tmpVal = 11;
}
else
{
tmpVal = int.Parse(chr.ToString());
}
//Times it by the location base.
retVal += tmpVal * (10 ^ (i - 1));
}
return retVal;
}
So you can then do things like
print(Base12Value(Base10Value(thisNum) + Base10Value(thisNum)));
which is a tad clunky, but gets the job done.
Oh, even though some already put it, here is mine since I worked on it.
using System;
using System.Text;
using System.Collections.Generic;
public class Base12
{
public static void Main()
{
Base12 X = new Base12(10);
Base12 X2 = new Base12(10);
Base12 XX = X + X2;
Console.WriteLine(XX); // outputs 18
}
public int DecimalValue { get; set; }
public readonly char[] Notation = new char[] {'0', '1' , '2' , '3', '4', '5' , '6', '7', '8', '9', 'X', 'E'};
public Base12(int x)
{
DecimalValue = x;
}
public override string ToString()
{
List<char> base12string = new List<char>();
int copy = DecimalValue;
while(copy > 0)
{
int result = copy % 12;
base12string.Add(Notation[result]);
copy = copy / 12;
}
StringBuilder str = new StringBuilder();
for(int i = base12string.Count - 1; i >= 0; i--)
{
str.Append(base12string[i]);
}
return str.ToString();
}
public static Base12 operator+(Base12 x, Base12 y)
{
return new Base12(x.DecimalValue + y.DecimalValue);
}
// Overload other operators at your wish
}
Here's my implementation of your problem. I have to say, this is one fun project!
I didnt want to use any decimal values, because I thought that was cheating. I only used decimals as de index for the list.
using System;
using System.Collections.Generic;
using System.Linq;
class Base12
{
static IList<char> values = new List<char>{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'X', 'E' };
public string Value { get; set; }
public Base12(string value)
{
this.Value = value;
}
public static Base12 operator +(Base12 x, Base12 y)
{
var xparts = x.Value.ToArray();
var yparts = y.Value.ToArray();
int remember = 0;
string result = string.Empty;
for (int i = 0; i < Math.Max(yparts.Length, xparts.Length) ;i++)
{
int index = remember;
if (i < xparts.Length)
{
index += values.IndexOf(xparts[xparts.Length - i - 1]);
}
if (i < yparts.Length)
{
index += values.IndexOf(yparts[yparts.Length - i - 1]);
}
if (index > 11)
{
index -= 12;
remember = 1;
}
else
{
remember = 0;
}
result = values[index] + result;
}
if (remember > 0)
{
result = values[remember] + result;
}
return new Base12(result);
}
public static implicit operator Base12(string x)
{
return new Base12(x);
}
public override string ToString()
{
return this.Value;
}
}
And here is how you might use it:
Base12 x = "X";
Base12 y = "X";
Base12 z = x + y;
Debug.Print(z.ToString());
// returns 18
Base12 x = "X12X";
Base12 y = "X3";
Base12 z = x + y;
Debug.Print(z.ToString());
// returns X211
I want a method that receives as input two char arrays, and an integer d which represents a max of differences between chars in both arrays and return true or false depending on if arrays are similar differing at most with d chars
so for example
Having
char[] a1 = { 's', 't', 'a', 'f', 'f' };
char[] a2 = { 's', 't', 'a', 'c', 'k' };
and having d=2 would return true because those arrays are almost similar
I was thinking on making a for loop and comparing each char and having a counter of maxDiference and if the counter exceeds return false like:
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace auxros
{
class Program
{
static void Main(string[] args)
{
char[] a1 = { 's', 't', 'a', 'f', 'f' };
char[] a2 = { 's', 't', 'a', 'c', 'k' };
bool areDifferent = CharMismatches(a1, a2, 1);
System.Console.WriteLine("The arrays are diferent at most by one char? " + areDifferent);
areDifferent = CharMismatches(a1, a2, 2);
System.Console.WriteLine("The arrays are diferent at most by two chars? " + areDifferent);
areDifferent = CharMismatches(a1, a2, 3);
System.Console.WriteLine("The arrays are diferent at most by three chars? " + areDifferent);
}
static bool CharMismatches(char[] a1, char[] a2, int d) {
int mismatches = 0;
for (int i = 0; i < a1.Length; i++)
{
if (!a1[i].Equals(a2[i]))
{
mismatches++;
}
if (mismatches == d)
{
return true;
}
}
if (mismatches <= d)
{
return false;
}
return true;
}
}
}
Is there a more efficient way to do this?
Why not have CharMismatches return the number d (up to a max)?
static int CharMismatches(char[] a1, char[] a2, int max)
{
int mismatches = 0;
for (int i = 0; i < a1.Length; i++)
{
if (!a1[i].Equals(a2[i]))
if (++mismatches == max)
return mismatches
}
return mismatches;
}
That way, you'll only need to run it once:
int max = 3;
int mismatches = CharMismatches(a1, a2, max);
System.Console.WriteLine(string.Format(
"The arrays are different at {1} by {0} char",
mismatches,
mismatches == max ? "least" : "most"
));
To check for mismatches in the entire array.
public class CharCount
{
public char Char { get; set; }
public int FirstArrayCount { get; set; }
public int SecondArrayCount { get; set; }
}
private static int CharMismatches(char[] a1, char[] a2)
{
var charCountList = new List<CharCount>();
charCountList.AddRange(a1.GroupBy(a => a).Select(a => new CharCount { Char = a.Key, FirstArrayCount = a.Count() }).ToList());
charCountList.AddRange(a2.GroupBy(a => a).Select(a => new CharCount { Char = a.Key, SecondArrayCount = a.Count() }).ToList());
var totalCharCountList= charCountList.GroupBy(a => a.Char).ToDictionary(a => a.Key, b => new CharCount
{
Char = b.Key,
FirstArrayCount = b.Sum(c => c.FirstArrayCount),
SecondArrayCount = b.Sum(c => c.SecondArrayCount)
});
var totalMisMatches= totalCharCountList.Count(a => a.Value.FirstArrayCount == 0 || a.Value.SecondArrayCount==0);
return totalMisMatches;
}
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();
}
I have a string as input and have to break the string in two substrings. If the left substring equals the right substring then do some logic.
How can I do this?
Sample:
public bool getStatus(string myString)
{
}
Example: myString = "ankYkna", so if we break it into two substring it would be:
left-part = "ank",
right-part = "ank" (after reversal).
Just for fun:
return myString.SequenceEqual(myString.Reverse());
public static bool getStatus(string myString)
{
string first = myString.Substring(0, myString.Length / 2);
char[] arr = myString.ToCharArray();
Array.Reverse(arr);
string temp = new string(arr);
string second = temp.Substring(0, temp.Length / 2);
return first.Equals(second);
}
int length = myString.Length;
for (int i = 0; i < length / 2; i++)
{
if (myString[i] != myString[length - i - 1])
return false;
}
return true;
Using LINQ and off course far from the best solution
var original = "ankYkna";
var reversed = new string(original.Reverse().ToArray());
var palindrom = original == reversed;
A single line of code using Linq
public static bool IsPalindrome(string str)
{
return str.SequenceEqual(str.Reverse());
}
public static bool IsPalindrome(string value)
{
int i = 0;
int j = value.Length - 1;
while (true)
{
if (i > j)
{
return true;
}
char a = value[i];
char b = value[j];
if (char.ToLower(a) != char.ToLower(b))
{
return false;
}
i++;
j--;
}
}
//This c# method will check for even and odd lengh palindrome string
public static bool IsPalenDrome(string palendromeString)
{
bool isPalenDrome = false;
try
{
int halfLength = palendromeString.Length / 2;
string leftHalfString = palendromeString.Substring(0,halfLength);
char[] reversedArray = palendromeString.ToCharArray();
Array.Reverse(reversedArray);
string reversedString = new string(reversedArray);
string rightHalfStringReversed = reversedString.Substring(0, halfLength);
isPalenDrome = leftHalfString == rightHalfStringReversed ? true : false;
}
catch (Exception ex)
{
throw ex;
}
return isPalenDrome;
}
In C# :
public bool EhPalindromo(string text)
{
var reverseText = string.Join("", text.ToLower().Reverse());
return reverseText == text;
}
This is a short and efficient way of checking palindrome.
bool checkPalindrome(string inputString) {
int length = inputString.Length;
for(int i = 0; i < length/2; i++){
if(inputString[i] != inputString[length-1-i]){
return false;
}
}
return true;
}
This way is both concise in appearance & processes very quickly.
Func<string, bool> IsPalindrome = s => s.Reverse().Equals(s);
public static bool IsPalindrome(string word)
{
//first reverse the string
string reversedString = new string(word.Reverse().ToArray());
return string.Compare(word, reversedString) == 0 ? true : false;
}
Out of all the solutions, below can also be tried:
public static bool IsPalindrome(string s)
{
return s == new string(s.Reverse().ToArray());
}
String extension method, easy to use:
public static bool IsPalindrome(this string str)
{
str = new Regex("[^a-zA-Z]").Replace(str, "").ToLower();
return !str.Where((t, i) => t != str[str.Length - i - 1]).Any();
}
private void CheckIfPalindrome(string str)
{
//place string in array of chars
char[] array = str.ToCharArray();
int length = array.Length -1 ;
Boolean palindrome =true;
for (int i = 0; i <= length; i++)//go through the array
{
if (array[i] != array[length])//compare if the char in the same positions are the same eg "tattarrattat" will compare array[0]=t with array[11] =t if are not the same stop the for loop
{
MessageBox.Show("not");
palindrome = false;
break;
}
else //if they are the same make length smaller by one and do the same
{
length--;
}
}
if (palindrome) MessageBox.Show("Palindrome");
}
use this way from dotnetperls
using System;
class Program
{
/// <summary>
/// Determines whether the string is a palindrome.
/// </summary>
public static bool IsPalindrome(string value)
{
int min = 0;
int max = value.Length - 1;
while (true)
{
if (min > max)
{
return true;
}
char a = value[min];
char b = value[max];
// Scan forward for a while invalid.
while (!char.IsLetterOrDigit(a))
{
min++;
if (min > max)
{
return true;
}
a = value[min];
}
// Scan backward for b while invalid.
while (!char.IsLetterOrDigit(b))
{
max--;
if (min > max)
{
return true;
}
b = value[max];
}
if (char.ToLower(a) != char.ToLower(b))
{
return false;
}
min++;
max--;
}
}
static void Main()
{
string[] array =
{
"A man, a plan, a canal: Panama.",
"A Toyota. Race fast, safe car. A Toyota.",
"Cigar? Toss it in a can. It is so tragic.",
"Dammit, I'm mad!",
"Delia saw I was ailed.",
"Desserts, I stressed!",
"Draw, O coward!",
"Lepers repel.",
"Live not on evil.",
"Lonely Tylenol.",
"Murder for a jar of red rum.",
"Never odd or even.",
"No lemon, no melon.",
"Senile felines.",
"So many dynamos!",
"Step on no pets.",
"Was it a car or a cat I saw?",
"Dot Net Perls is not a palindrome.",
"Why are you reading this?",
"This article is not useful.",
"...",
"...Test"
};
foreach (string value in array)
{
Console.WriteLine("{0} = {1}", value, IsPalindrome(value));
}
}
}
If you just need to detect a palindrome, you can do it with a regex, as explained here. Probably not the most efficient approach, though...
That is non-trivial, there is no built in method to do that for you, you'll have to write your own. You will need to consider what rules you would like to check, like you implicitly stated you accepted reversing of one string. Also, you missed out the middle character, is this only if odd length?
So you will have something like:
if(myString.length % 2 = 0)
{
//even
string a = myString.substring(0, myString.length / 2);
string b = myString.substring(myString.length / 2 + 1, myString.lenght/2);
if(a == b)
return true;
//Rule 1: reverse
if(a == b.reverse()) //can't remember if this is a method, if not you'll have to write that too
return true;
etc, also doing whatever you want for odd strings
This C# method will check for even and odd length palindrome string (Recursive Approach):
public static bool IsPalindromeResursive(int rightIndex, int leftIndex, char[] inputString)
{
if (rightIndex == leftIndex || rightIndex < leftIndex)
return true;
if (inputString[rightIndex] == inputString[leftIndex])
return IsPalindromeResursive(--rightIndex, ++leftIndex, inputString);
else
return false;
}
public Boolean IsPalindrome(string value)
{
var one = value.ToList<char>();
var two = one.Reverse<char>().ToList();
return one.Equals(two);
}
class Program
{
static void Main(string[] args)
{
string s, revs = "";
Console.WriteLine(" Enter string");
s = Console.ReadLine();
for (int i = s.Length - 1; i >= 0; i--) //String Reverse
{
Console.WriteLine(i);
revs += s[i].ToString();
}
if (revs == s) // Checking whether string is palindrome or not
{
Console.WriteLine("String is Palindrome");
}
else
{
Console.WriteLine("String is not Palindrome");
}
Console.ReadKey();
}
}
public bool IsPalindroom(string input)
{
input = input.ToLower();
var loops = input.Length / 2;
var higherBoundIdx = input.Length - 1;
for (var lowerBoundIdx = 0; lowerBoundIdx < loops; lowerBoundIdx++, higherBoundIdx--)
{
if (input[lowerBoundIdx] != input[higherBoundIdx])
return false;
}
return true;
}
Here is an absolutely simple way to do this,
Receive the word as input into a method.
Assign a temp variable to the original value.
Loop through the initial word, and add the last character to the reversal that you are constructing until the inital word has no more characters.
Now use the spare you created to hold the original value to compare to the constructed copy.
This is a nice way as u don't have to cast ints and doubles. U can just pass them to the method in their string representation by using the ToString() method.
public static bool IsPalindrome(string word)
{
string spare = word;
string reversal = null;
while (word.Length > 0)
{
reversal = string.Concat(reversal, word.LastOrDefault());
word = word.Remove(word.Length - 1);
}
return spare.Equals(reversal);
}
So from your main method,
For even and odd length strings u just pass the whole string into the method.
Since a palindrome also includes numbers, words, sentences, and any combinations of these, and should ignore punctuation and case, (See Wikipedia Article)
I propose this solution:
public class Palindrome
{
static IList<int> Allowed = new List<int> {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'1', '2', '3', '4', '5', '6', '7', '8', '9',
'0'
};
private static int[] GetJustAllowed(string text)
{
List<int> characters = new List<int>();
foreach (var c in text)
characters.Add(c | 0x20);
return characters.Where(c => Allowed.Contains(c)).ToArray();
}
public static bool IsPalindrome(string text)
{
if(text == null || text.Length == 1)
return true;
int[] chars = GetJustAllowed(text);
var length = chars.Length;
while (length > 0)
if (chars[chars.Length - length] != chars[--length])
return false;
return true;
}
public static bool IsPalindrome(int number)
{
return IsPalindrome(number.ToString());
}
public static bool IsPalindrome(double number)
{
return IsPalindrome(number.ToString());
}
public static bool IsPalindrome(decimal number)
{
return IsPalindrome(number.ToString());
}
}
static void Main(string[] args)
{
string str, rev="";
Console.Write("Enter string");
str = Console.ReadLine();
for (int i = str.Length - 1; i >= 0; i--)
{
rev = rev + str[i];
}
if (rev == str)
Console.Write("Entered string is pallindrome");
else
Console.Write("Entered string is not pallindrome");
Console.ReadKey();
}
string test = "Malayalam";
char[] palindrome = test.ToCharArray();
char[] reversestring = new char[palindrome.Count()];
for (int i = palindrome.Count() - 1; i >= 0; i--)
{
reversestring[palindrome.Count() - 1 - i] = palindrome[i];
}
string materializedString = new string(reversestring);
if (materializedString.ToLower() == test.ToLower())
{
Console.Write("Palindrome!");
}
else
{
Console.Write("Not a Palindrome!");
}
Console.Read();
public static bool palindrome(string t)
{
int i = t.Length;
for (int j = 0; j < i / 2; j++)
{
if (t[j] == t[i - j-1])
{
continue;
}
else
{
return false;
break;
}
}
return true;
}
public bool Solution(string content)
{
int length = content.Length;
int half = length/2;
int isOddLength = length%2;
// Counter for checking the string from the middle
int j = (isOddLength==0) ? half:half+1;
for(int i=half-1;i>=0;i--)
{
if(content[i] != content[j])
{
return false;
}
j++;
}
return true;
}
public bool MojTestPalindrome (string word)
{
bool yes = false;
char[]test1 = word.ToArray();
char[] test2 = test1.Reverse().ToArray();
for (int i=0; i< test2.Length; i++)
{
if (test1[i] != test2[test2.Length - 1 - i])
{
yes = false;
break;
}
else {
yes = true;
}
}
if (yes == true)
{
return true;
}
else
return false;
}
public static bool IsPalindrome(string str)
{
int i = 0;
int a = 0;
char[] chr = str.ToCharArray();
foreach (char cr in chr)
{
Array.Reverse(chr);
if (chr[i] == cr)
{
if (a == str.Length)
{
return true;
}
a++;
i++;
}
else
{
return false;
}
}
return true;
}
The various provided answers are wrong for numerous reasons, primarily from misunderstanding what a palindrome is. The majority only properly identify a subset of palindromes.
From Merriam-Webster
A word, verse, or sentence (such as "Able was I ere I saw Elba")
And from Wordnik
A word, phrase, verse, or sentence that reads the same backward or forward. For example: A man, a plan, a canal, Panama!
Consider non-trivial palindromes such as "Malayalam" (it's a proper language, so naming rules apply, and it should be capitalized), or palindromic sentences such as "Was it a car or a cat I saw?" or "No 'X' in Nixon".
These are recognized palindromes in any literature.
I'm lifting the thorough solution from a library providing this kind of stuff that I'm the primary author of, so the solution works for both String and ReadOnlySpan<Char> because that's a requirement I've imposed on the library. The solution for purely String will be easy to determine from this, however.
public static Boolean IsPalindrome(this String #string) =>
!(#string is null) && #string.AsSpan().IsPalindrome();
public static Boolean IsPalindrome(this ReadOnlySpan<Char> span) {
// First we need to build the string without any punctuation or whitespace or any other
// unrelated-to-reading characters.
StringBuilder builder = new StringBuilder(span.Length);
foreach (Char s in span) {
if (!(s.IsControl()
|| s.IsPunctuation()
|| s.IsSeparator()
|| s.IsWhiteSpace()) {
_ = builder.Append(s);
}
}
String prepped = builder.ToString();
String reversed = prepped.Reverse().Join();
// Now actually check it's a palindrome
return String.Equals(prepped, reversed, StringComparison.CurrentCultureIgnoreCase);
}
You're going to want variants of this that accept a CultureInfo parameter as well, when you're testing a specific language rather than your own language, by instead calling .ToUpper(cultureInfo) on prepped.
And here's proof from the projects unit tests that it works.