I'm new to programming (C#).
The application is a 'words generator'.
What I'm looking for is a for loop that can generate all possible words with the characters in a given array of characters.
The details:
I have a List<char> = { A,a,6,w,# } (The length may vary)
I want to generate all possible words (for example: 4 letters length ) with this character set. This options should generate 5 characters & 4 letters = 5*5*5*5 = 625 words.
All generated words should be every possible combination of the given letters only
NOTE:
Some might tell me that i should use a solution called (Permutations of a String/Integer)
this method seems to be fine if the required words length is same as given characters length, but in my case i might give the application 100 characters, But i want it to generate all possible words -> 4 letters length (Example: MaRk, M#rK,m4rK...)
You could use an IEnumerable<String> method:
public IEnumerable<String> GenerateStrings (IEnumerable<char> characters, int length) {
if(length > 0) {
foreach(char c in characters) {
foreach(String suffix in GenerateStrings(characters,length-1)) {
yield return c+suffix;
}
}
} else {
yield return string.Empty;
}
}
Result with csharp (interactive C# shell):
csharp> Foo.GenerateStrings(new char[] {'A','a','6','w','#'},3)
{ "AAA", "AAa", "AA6", "AAw", "AA#", "AaA", "Aaa", "Aa6", "Aaw", "Aa#", "A6A", "A6a", "A66", "A6w", "A6#", "AwA", "Awa", "Aw6", "Aww", "Aw#", "A#A", "A#a", "A#6", "A#w", "A##", "aAA", "aAa", "aA6", "aAw", "aA#", "aaA", "aaa", "aa6", "aaw", "aa#", "a6A", "a6a", "a66", "a6w", "a6#", "awA", "awa", "aw6", "aww", "aw#", "a#A", "a#a", "a#6", "a#w", "a##", "6AA", "6Aa", "6A6", "6Aw", "6A#", "6aA", "6aa", "6a6", "6aw", "6a#", "66A", "66a", "666", "66w", "66#", "6wA", "6wa", "6w6", "6ww", "6w#", "6#A", "6#a", "6#6", "6#w", "6##", "wAA", "wAa", "wA6", "wAw", "wA#", "waA", "waa", "wa6", "waw", "wa#", "w6A", "w6a", "w66", "w6w", "w6#", "wwA", "wwa", "ww6", "www", "ww#", "w#A", "w#a", "w#6", "w#w", "w##", "#AA", "#Aa", "#A6", "#Aw", "#A#", "#aA", "#aa", "#a6", "#aw", "#a#", "#6A", "#6a", "#66", "#6w", "#6#", "#wA", "#wa", "#w6", "#ww", "#w#", "##A", "##a", "##6", "##w", "###" }
The advantage of using a method with a yield statement is that it is lazy: if you only need five such strings, not all possible strings will be generated first...
Willem Van Onsem, thanks! This was exactly what i've been looking for. But my problem sounds little different. I have to generate all possible strings without repetition of chars from source array. And here is your code, that i modified to do so:
public static IEnumerable<string> GenerateStrings(IEnumerable<char> characters, int length, int count)
{
if (length > 0)
{
foreach (char c in characters)
{
char[] charactersDec = new char[characters.Count()];
Array.Copy(characters.ToArray(), charactersDec, characters.Count());
int index = Array.IndexOf(charactersDec, c);
charactersDec = charactersDec.Where((val, idx) => idx != index).ToArray();
foreach (string suffix in GenerateStrings(charactersDec, length - 1, count++))
{
yield return c + suffix;
}
}
}
else
{
yield return string.Empty;
}
}
I remove current char from array and passed this array to recursive call.
output for a, b, c, d will be:
ab
ba
ac
ca
ad
da
bc
cb
bd
db
cd
dc
please, sorry my english.
Related
I need to check if a string contains only numbers(integers and decimal) with a space in between them.
Eg: 1 2 4.5 72 (this is acceptable);
1 7..5 3.2.1 (this is unacceptable)
You can use Double.TryParse() to verify if a string is a valid number, assuming integers and floats/doubles in this case. You will have to split the strings by whitespace beforehand using String.Split() to check each number individually. You can also utilize Enumerable.All<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) from LINQ to check if all the strings satisfy a condition.
List<string> strings = new List<string> { "1 2 4.5 72", "1 7..5 3.2.1" };
foreach (string item in strings)
{
if (item.Split (new[] { " " }, StringSplitOptions.RemoveEmptyEntries).All (str => double.TryParse (str, out _)))
{
Console.WriteLine ($"{item} has only valid numbers.");
}
else
{
Console.WriteLine ($"{item} does have invalid numbers.");
}
}
// 1 2 4.5 72 has only valid numbers.
// 1 7..5 3.2.1 does have invalid numbers.
you can use split space first then check every split element numberic yes or not by decimal.TryParse + LINQ Any.
void Main()
{
Console.WriteLine( Check("1 2 4.5 72") ); //true
Console.WriteLine( Check("1 7..5 3.2.1") ); //false
}
bool Check(string text)
{
return text.Split(' ').Any(_ => decimal.TryParse(_, out var num) == false) == false;
}
I'm new to C# so expect some mistakes ahead. Any help / guidance would be greatly appreciated.
I want to limit the accepted inputs for a string to just:
a-z
A-Z
hyphen
Period
If the character is a letter, a hyphen, or period, it's to be accepted. Anything else will return an error.
The code I have so far is
string foo = "Hello!";
foreach (char c in foo)
{
/* Is there a similar way
To do this in C# as
I am basing the following
Off of my Python 3 knowledge
*/
if (c.IsLetter == true) // *Q: Can I cut out the == true part ?*
{
// Do what I want with letters
}
else if (c.IsDigit == true)
{
// Do what I want with numbers
}
else if (c.Isletter == "-") // Hyphen | If there's an 'or', include period as well
{
// Do what I want with symbols
}
}
I know that's a pretty poor set of code.
I had a thought whilst writing this:
Is it possible to create a list of the allowed characters and check the variable against that?
Something like:
foreach (char c in foo)
{
if (c != list)
{
// Unaccepted message here
}
else if (c == list)
{
// Accepted
}
}
Thanks in advance!
Easily accomplished with a Regex:
using System.Text.RegularExpressions;
var isOk = Regex.IsMatch(foo, #"^[A-Za-z0-9\-\.]+$");
Rundown:
match from the start
| set of possible matches
| |
|+-------------+
|| |any number of matches is ok
|| ||match until the end of the string
|| |||
vv vvv
^[A-Za-z0-9\-\.]+$
^ ^ ^ ^ ^
| | | | |
| | | | match dot
| | | match hyphen
| | match 0 to 9
| match a-z (lowercase)
match A-Z (uppercase)
You can do this in a single line with regular expressions:
Regex.IsMatch(myInput, #"^[a-zA-Z0-9\.\-]*$")
^ -> match start of input
[a-zA-Z0-9\.\-] -> match any of a-z , A-Z , 0-9, . or -
* -> 0 or more times (you may prefer + which is 1 or more times)
$ -> match the end of input
You can use Regex.IsMatch function and specify your regular expression.
Or define manually chars what you need. Something like this:
string foo = "Hello!";
char[] availableSymbols = {'-', ',', '!'};
char[] availableLetters = {'A', 'a', 'H'}; //etc.
char[] availableNumbers = {'1', '2', '3'}; //etc
foreach (char c in foo)
{
if (availableLetters.Contains(c))
{
// Do what I want with letters
}
else if (availableNumbers.Contains(c))
{
// Do what I want with numbers
}
else if (availableSymbols.Contains(c))
{
// Do what I want with symbols
}
}
Possible solution
You can use the CharUnicodeInfo.GetUnicodeCategory(char) method. It returns the UnicodeCategory of a character. The following unicode categories might be what you're look for:
UnicodeCategory.DecimalDigitNumber
UnicodeCategory.LowercaseLetter and UnicodeCategory.UppercaseLetter
An example:
string foo = "Hello!";
foreach (char c in foo)
{
UnicodeCategory cat = CharUnicodeInfo.GetUnicodeCategory(c);
if (cat == UnicodeCategory.LowercaseLetter || cat == UnicodeCategory.UppercaseLetter)
{
// Do what I want with letters
}
else if (cat == UnicodeCategory.DecimalDigitNumber)
{
// Do what I want with numbers
}
else if (c == '-' || c == '.')
{
// Do what I want with symbols
}
}
Answers to your other questions
Can I cut out the == true part?:
Yes, you can cut the == true part, it is not required in C#
If there's an 'or', include period as well.:
To create or expressions use the 'barbar' (||) operator as i've done in the above example.
Whenever you have some kind of collection of similar things, an array, a list, a string of characters, whatever, you'll see at the definition of the collection that it implements IEnumerable
public class String : ..., IEnumerable,
here T is a char. It means that you can ask the class: "give me your first T", "give me your next T", "give me your next T" and so on until there are no more elements.
This is the basis for all Linq. Ling has about 40 functions that act upon sequences. And if you need to do something with a sequence of the same kind of items, consider using LINQ.
The functions in LINQ can be found in class Enumerable. One of the function is Contains. You can use it to find out if a sequence contains a character.
char[] allowedChars = "abcdefgh....XYZ.-".ToCharArray();
Now you have a sequence of allowed characters. Suppose you have a character x and want to know if x is allowed:
char x = ...;
bool xIsAllowed = allowedChars.Contains(x);
Now Suppose you don't have one character x, but a complete string and you want only the characters in this string that are allowed:
string str = ...
var allowedInStr = str
.Where(characterInString => allowedChars.Contains(characterInString));
If you are going to do a lot with sequences of things, consider spending some time to familiarize yourself with LINQ:
Linq explained
You can use Regex.IsMatch with "^[a-zA-Z_.]*$" to check for valid characters.
string foo = "Hello!";
if (!Regex.IsMatch(foo, "^[a-zA-Z_\.]*$"))
{
throw new ArgumentException("Exception description here")
}
Other than that you can create a list of chars and use string.Contains method to check if it is ok.
string validChars = "abcABC./";
foreach (char c in foo)
{
if (!validChars.Contains(c))
{
// Throw exception
}
}
Also, you don't need to check for == true/false in if line. Both expressions are equal below
if (boolvariable) { /* do something */ }
if (boolvariable == true) { /* do something */ }
I am working through Joyce Farrell's Visual C#2012 on my own (this is not a homework assignment). I have been stuck on this for the past two days, and have yet to find an answer that I understand. I am looking for a simple program - nothing fancy as I probably haven't read that chapter yet. :-) The problem that I am having is when I am trying to show '' for a non-guessed or incorrectly guessed letter. If I assign '' it looks good for the first letter, but when the user enters a second guess, it changes the second guess to a '?'. Why is that? Any help would be really appreciated. Thank you.
static void Main(string[] args)
{
string[] mysteryWordList = { "green", "snowflake", "tree", "joy", "red", "gift", "frozen", "merry" };
string mysteryWord; // hidden word
char[] mysteryWordArray;
char letterGuessed;
char[] guessWordArray;
Random ranNumberGenerator = new Random(); // generate a random number, at least 0 but < 8
int randomNumber = ranNumberGenerator.Next(0, 8);
mysteryWord = mysteryWordList[randomNumber]; // select a word from list using random number
Console.WriteLine("The Mystery word is: " + mysteryWord); // print word for my validation
mysteryWordArray = mysteryWord.ToArray(); // put mystery word into array to compare against guessWord array
Console.Write("MysterywordArray is: ");
Console.WriteLine(mysteryWordArray);
guessWordArray = new char[mysteryWord.Length]; // assign length to user guess array
// write mystery word in *'s
for (int x = 0; x < mysteryWord.Length; ++x)
Console.Write("*");
//guessWordArray[x] += '%'; adds value and then does not work...
Console.WriteLine();
while (guessWordArray != mysteryWordArray)
{
Console.Write("\nPlease guess a letter: ");
letterGuessed = Convert.ToChar(Console.ReadLine());
for (int x = 0; x < mysteryWord.Length; ++x)// go through each letter in mystery word
{
if (letterGuessed == mysteryWordArray[x]) // if match do this
{
Console.WriteLine("Yes, the letter {0} is in the mystery word!", letterGuessed);
guessWordArray[x] += letterGuessed;
}
if (letterGuessed != mysteryWordArray[x] && guessWordArray[x] == default(char)) // if match do this
guessWordArray[x] += '*';
}
Console.Write("Mystery Word: ");
Console.WriteLine(guessWordArray);
}
}
The command guessWordArray[x] += letterGuessed; is wrong. It dosent add the letter to the array it actualy changes the Xth element in the array. For example if guesswordArray contains { 'a', 'b', 'c' }
guesswordArray[0] += 'a' translates to guessWordArray[2] = 'a' + 'a'. Character addition is done by converting a character to the ascii code then the result is converted to a character. That means 'a'== 97 'a'+'a' == 194' Then 194 is converted back to a weird character from the ascii table.
This two lines :
guessWordArray[x] += letterGuessed;
....
guessWordArray[x] += '*';
should be like this instead :
guessWordArray[x] = letterGuessed;
....
guessWordArray[x] = '*';
By this += operator, you are appending the char from user input to existing char saved in the array. That will produce special character which which won't be displayed well in console (that's why you saw sort of ? char). I think you need to just assign the input char and replace existing char by using = instead of +=
Characters are essentially integers in their most basic form. When you are attempting to add subsequent letters to your array you are using += which is adding characters together. The initial character '*' is ASCII code 42, so what's happening is when you select a new letter ('g' for example in "gift") you are adding 103 to to that 42, and the ASCII character with the value 145 is being stored in the array. That value is unable to be displayed properly by the console. You need to just use the assignment operator since you want to write the new character to the array at the current index.
guessWordArray[x] = letterGuessed;
guessWordArray[x] = '*';
hi i'm trying to extract values from this tagged file
here is the file
0
LINE
5
1C1CBD
330
1C1ADB
100
AcDbEntity
8
0-FD
62
9
370
-2
100
AcDbLine
10
53740.73468153231
20
-190253.3098529756
30
0.0
11
53690.49919802765
21
-190166.2994431953
31
0.0
0
you can see that there is a hexadecimal number below "LINE", is there anyway i can extract it into some list?
like
VALUE = 1C1CBD
NOTE: the file consist more than one of this kind of pattern
and then how can i get the maximum value?
EDIT 1
i see that "5" can be found by using regex "\s\s5" can i use this?
Thank you for your feedback i have been able to complete what i want
here is the code
string[] handle = originalString.Split(new string[] { "\r\n" }, StringSplitOptions.None);
List<string> hexa = new List<string>();
for (var a = 1; a <= handle.Count() - 1; a++)
{
if (Regex.IsMatch(handle[a], #"^\s\s5"))
{
hexa.Add(handle[a + 1]);
}
}
List<int> HexaToInt = new List<int>();
foreach (string valueHexa in hexa)
{
int intHexaValue = int.Parse(valueHexa, System.Globalization.NumberStyles.HexNumber);
HexaToInt.Add(intHexaValue);
}
int maximumHexa = HexaToInt.Max();
string hexValue = maximumHexa.ToString("X");
it is possible afterall to extract the hexadecimal value from the handle group codes
It is totally impossible.
No way to catch characters and extract what you need.
You have to organize the structure of this file better.
I have used the following code but it is returning false though it should return true
string check,zipcode;
zipcode="10001 New York, NY";
check=isalphanumeric(zipcode)
public static Boolean isAlphaNumeric(string strToCheck)
{
Regex rg = new Regex("[^a-zA-Z0-9]");
//if has non AlpahNumeric char, return false, else return true.
return rg.IsMatch(strToCheck) == true ? false : true;
}
Try this one:
public static Boolean isAlphaNumeric(string strToCheck)
{
Regex rg = new Regex(#"^[a-zA-Z0-9\s,]*$");
return rg.IsMatch(strToCheck);
}
It's more undestandable, if you specify in regex, what your string SHOULD contain, and not what it MUST NOT.
In the example above:
^ - means start of the string
[]* - could contain any number of characters between brackets
a-zA-Z0-9 - any alphanumeric characters
\s - any space characters (space/tab/etc.)
, - commas
$ - end of the string
public static bool IsAlphaNumeric(string strToCheck)
{
return strToCheck.All(char.IsLetterOrDigit);
}
10001 New York, NY contains a comma and spaces -- not alphanumeric
You need to adjust your expression to allow commas and spaces.
Also, you will probably want to rename the function so that it is clear to other developers that it is more of a validator than an isAlphaNumeric() function.
I needed a method to see if the string contains any Alpha Numeric, without using Regex...
public static bool ContainsAlphaNumeric(string strToCheck)
{
foreach(char c in strToCheck)
{
if (char.IsLetterOrDigit(c))
{
return true;
}
}
return false;
}
If you want a non-regex ASCII A-z 0-9 check, you cannot use char.IsLetterOrDigit() as that includes other Unicode characters, and is unreliable/unstable with unicode scalar values.
What you can do is check the character code ranges.
48 -> 57 are numerics
65 -> 90 are capital letters
97 -> 122 are lower case letters
The following is a bit more verbose, but it's for ease of understanding rather than for code golf.
public static bool IsAsciiAlphaNumeric(this string str)
{
if (string.IsNullOrEmpty(str))
{
return false;
}
for (int i = 0; i < str.Length; i++)
{
if (str[i] < 48) // Numeric are 48 -> 57
{
return false;
}
if (str[i] > 57 && str[i] < 65) // Capitals are 65 -> 90
{
return false;
}
if (str[i] > 90 && str[i] < 97) // Lowers are 97 -> 122
{
return false;
}
if (str[i] > 122)
{
return false;
}
}
return true;
}
When the ^ is in the [ ] it means everything but these characters.
tring check,zipcode;
zipcode="10001 New York, NY";
check=isalphanumeric(zipcode)
public static Boolean isAlphaNumeric(string strToCheck)
{
Regex rg = new Regex("[^a-zA-Z0-9]");
//if has non AlpahNumeric char, return false, else return true.
return rg.IsMatch(strToCheck) == true ? false : true;
}
this code return always false, because the symbole ^ means that's this string doesn't contains any alphanumeric caractere, you need to delete the this ^
Back in my perl days, I would have used this regular expression:
\w+
which means one or more word character. A word character is basically a-zA-Z0-9 and basically does not care about punctuation or spaces. So if you just want to make sure that there is someting of value in the string, this is what I have used in C#:
public static Boolean isAlphaNumeric(string strToCheck)
{
Regex rg = new Regex(#"\w+");
return rg.IsMatch(strToCheck);
}
Thanks to Chopikadze for the basic structure.
I do think that this one would be faster since instead of checking through the entire string, it would stop at the first instance of a word character and return a true.
Char static methods can be used too
bool IsAlphaNumeric(char charToCheck) => char.IsLetter(charToCheck) || char.IsDigit(charToCheck);