General questions to regex, conditions and if-statement [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I had a beginning question to read in a two digit number and give it back splittet into its numbers but I soon saw, that the code I created was not really handy, when wrong inputs where done.
So I did a research about if-statemants, .length feature, regex method and comperative operators. What came back was my rudimental first script for input a two digit number, prove if it is 2 digits long, prove if it is a number and give it back. Now I have some questions to You specialists (it is a console application btw.):
Was it the right way to use regex with the IsMatch method, or would be another method saver and cleaner (maybe also another variant of regex)
Is it possible to shorten the code, Iam not so far atm, maybe there are classes or objects to use, to make the code clearer.
Was it the right way to use conditional "and" instead of regular "and", in the if statements?
Are the if statements possible to be shorten, I read about conditional expressions, but I was not sure how far I could nest them (my reference: https://learn.microsoft.com/de-de/dotnet/csharp/language-reference/operators/conditional-operator). Maybe some of You can give me an example on my script.
Is the new operator on regex the right way to implement it, or is there another way to implement regex?
The script works, but maybe there are better and handier solutions.
using System;
using System.Text.RegularExpressions;
namespace TwoDigitSplit
{
class FromTrexToRegex
{
static void Main(string[] args)
{
int digit, digit1, digit2;
string entry;
// Search for one or more decimal numbers with Regex
Regex regex = new Regex("[0-9]+");
// Read in a two-digit number
Console.WriteLine("Enter a two-digit number:");
entry = Console.ReadLine();
// Check for length longer than two-digit and also check if it is numbers
if (entry.Length>2 && regex.IsMatch(entry))
{
Console.WriteLine("The number is longer than two-digit, please try again!");
}
// Check for length smaller than two-digit and also check if it is numbers
else if (entry.Length<2 && regex.IsMatch(entry))
{
Console.WriteLine("The number is shorter than two-digit, please try again!");
}
// Check for integer numbers and if the number is between 10 inklusiv and 100 exklusiv
else if(Int32.TryParse(entry, out digit) && digit >= 10 && digit <100)
{
// Evaluate the number and write it
digit1= digit / 10;
digit2 = digit % 10;
Console.WriteLine("The number has on the first place {0} and on the second place {1}", digit1, digit2);
}
// If no number has been plottet
else
{
Console.WriteLine("You did not enter a number!");
}
}
}
}
There are no error results atm. I could see, I only had some questions about the methods, classes and operators.

Answers
regex = new Regex(...) ... regex.IsMatch(...) is possible, but I suggest static Regex.IsMatch as more readable here
Yes, some conditions are redundant
I suggest separated regex condition (testing for value) and length (testing for length)
Ternary operator ? : must return a value, in you case you want to call a method - Console.WriteLine; stick to if
regex = new Regex(...) is possible, but I don't think it's good in the context. You want to test just once: Regex.IsMatch(...) is more readable
Code:
Console.WriteLine("Enter a two-digit number:");
// Trim: let us be nice and tolerate leading and trailing spaces
// (esp. in case user put it with copy-pasting)
entry = Console.ReadLine().Trim();
// Just check the length
if (entry.Length > 2)
{
Console.WriteLine("The number is longer than two-digit, please try again!");
}
// Check for length smaller than two-digit
else if (entry.Length < 2)
{
Console.WriteLine("The number is shorter than two-digit, please try again!");
}
// The length is correct, time to check the value
else if (!Regex.IsMatch(entry, "^[0-9]{2}$")) // <- just a static method
{
Console.WriteLine("The input is not 2 digit number, please try again!")
}
// The entry is valid, let's ptint the result out
else
{
// You don't have to parse and do arithmetic
// if you want to convert char to corresponding digit: '7' -> 7
int digit1 = entry[0] - '0';
int digit2 = entry[1] - '0';
// String interpolation is often more readable than formatting
Console.WriteLine(
$"The number has on the first place {digit1} and on the second place {digit2}");
}

Related

How to multiple all digits of x number? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm doing a counting program and i need to multiple all digits of x number by it self.
for example: number 123456789;
1*2*3*4*5*6*7*8*9=362,880
A good solution is provided in the comments, but it isn't very easy to follow if you are trying to figure out what you are actually doing. The following code is a bit more verbose, but shows you what is actually happening each step of the way:
using System;
class MainClass {
public static void Main () {
int myNumber = 123456789; //store original number
int newNumber = (int)Math.Abs(myNumber); //changes the number to positive if it is negative to prevent string formatting errors.
int product = 1; //store product start point
string myString = newNumber.ToString(); //convert number to string
foreach(char number in myString){ //loop through string
string numberString = number.ToString(); //convert chars to strings to ensure proper output
int oneDigit = Convert.ToInt32(numberString); //convert strings to integers
product = product*oneDigit; //multiply each integer by the product and set that as the new product
}
if(myNumber < 0){product = -product;}
//if the number is negative, the result will be negative, since it is a negative followed by a bunch of positives.
//If you want your result to reflect that, add the above line to account for negative numbers.
Console.WriteLine(product); //display product
}
}
Output>>> 362880 //The output that was printed.
So we start by converting our number into a string so we can iterate through it. Then we have a foreach loop that goes through each character in the string, converts it into an integer, and multiplies it by the product of the previous numbers. Each time a new multiplication is performed, the product is updated, until, when you reach the end of the number, you have the product of all digits. This is a good project to become familiar with looping. I would recommend playing around with variations of it such as multiplying each number by the original number, multiplying together only multiples of 3, only multiplying numbers less than 5, or only multiplying the first 5 numbers to get a better handle on what's happening in a loop.

How to write a toString method without using other class libraries [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I want to write my own toString method since I am not allowed to use any class libraries.
So I took a look into the source code of the toString method, but it uses a lot of other libraries. I want to convert an Integer into a String, but I am not sure how i can address the numbers one by one.
If I could do that, I could continue by casting the Integers into a Char and in the end add up all the Chars for a String.
Can someone help?
Here's a similar approach to the other answers.
The important points:
We calculate the last digit of a number by finding its remainder when it's divided by 10 (i.e. lastDigit = number % 10;)
To throw away the last digit of a number, simply divide it by 10.
When finding digits that way, they will of course be returned in reverse order (least significant digit first) so you have to reverse the digits to get the correct answer. One way to do this is to store from the end to the beginning of a char array.
Negative numbers have to be handled specially. The easiest way is to note that the number is negative so that a - sign can be added when appropriate; then, negate the number to make it positive. However, note that you can't negate int.MinValue, so that has to be handled specially.
You can convert from a numeric digit to its char equivalent by adding it to the char '0' and casting the result back to char.
Here's an approach that uses those points:
public static string MyToString(int number)
{
if (number == int.MinValue)
return "-2147483648"; // Special case.
char[] digits = new char[64]; // Support at most 64 digits.
int last = digits.Length;
bool isNegative = number < 0;
if (isNegative)
number = -number;
do
{
digits[--last] = (char) ('0' + number % 10);
number /= 10;
}
while (number != 0);
if (isNegative)
digits[--last] = '-';
return new string(digits, last, digits.Length-last);
}
I think the main part you were asking about is how to get the digits of a number one-by-one, which is answered by the do/while loop above.
[EDIT] Addressed the points raised in the comments below.
I don't understand why you're not allowed to use any libraries. But if you need to do the conversion entirely by hand, you could do it something like this
private static string IntToString(int i)
{
string[] digits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
string sign = (i < 0 ? "-" : "");
var absI = (i < 0 ? -i : i);
string result = "";
while (absI != 0)
{
int digit = absI % 10;
result = digits[digit] + result;
absI = (absI - digit) / 10;
}
return sign + result;
}
The code above doesn't work properly for zero. If you need that, it's very simple to add.
For example you can split your number into individual characters:
// Note that this is just for example and for positive numbers only.
IEnumerable<char> ToChar(int num)
{
while (num > 0)
{
// adding '0' to number will return char for that number
char ch = (char)(num % 10 + '0');
num /= 10;
yield return ch;
}
}
then create new string based on that:
string ToString(int num)
{
// ToChar will return char collection in reverse order,
// so you will need to reverse collection before using.
// Well in your situation you will be probably needed to
// to write Reverse method by yourself, so this is just for
// working example
var chArray = ToChar(num).Reverse().ToArray();
string str = new string(chArray);
return str;
}
and usage:
int i = 554;
string str = ToString(i);
References: DotNetFiddle Example (with simplified ToChar() method)

Determine a numeric range that may contain alpha and numeric characters

I am not even sure how to phrase this question so I apologize in advance. I have a form used by our QA. it requires input of serial numbers - a lot of them (sometimes hundreds). I have two text boxes on the form for lower and upper numbers in the range (doesn't have to be this way but it is my best guess). I know how to to do this if it were just integers (see code below) but that is not the only format.Examples of the format could include a date code ("170508/1234") or could include alpha characters (ABC1234). there is a wide variety of formats but in every case, I want to find the range from the last set of numbers (typically last four digits - Like "170508/1234 170508/1235... and ABC1234 ABC1235 ... not to exclude 1234 1235 ....).
Thank you in advance
private void btnSN_Click(object sender, EventArgs e)
{
int from = Convert.ToInt32(txtSnStart.Text.Trim());
int to = Convert.ToInt32(txtSnEnd.Text.Trim());
for (int i = from; i <= to; i++)
{
txtSN.Text += i.ToString() +" ";
}
You can make use of RexEx for this, the RegEx expression below should match any number of digits at the end.:
(\d+)$
Here is the modified code:
// find the group of digits at end of entered text
var fromMatch = Regex.Match(txtSnStart.Text.Trim(), #"(\d+)$");
int from = Convert.ToInt32(fromMatch.Groups[1].Value);
// strip the matched digit group from entered text to get the prefix
string prefix = txtSnStart.Text.Trim().SubString(0, txtSnStart.Text.Trim().LastIndexOf(from.ToString()));
var toMatch = Regex.Match(txtSnEnd.Text.Trim(), #"(\d+)$");
int to = Convert.ToInt32(toMatch.Groups[1].Value);
for (int i = from; i <= to; i++)
{
// combine the prefix and range value
txtSN.Text += string.Format("{0}{1} ", prefix, i.ToString());
}
This problem becomes easier if you break it into smaller pieces.
This will become especially important once it becomes apparent that one small part of the problem might become more complex.
The inputs are a prefix, a number to begin the range, and a number to end the range. Given that, here's a class with a function to return those strings:
public class StringRangeCreator
{
public IEnumerable<string> CreateStringRange(
string prefix, int rangeStart, int rangeEnd)
{
if (rangeStart > rangeEnd) throw new ArgumentException(
$"{nameof(rangeStart)} cannot be greater than {nameof(rangeEnd)}");
return Enumerable.Range(rangeStart, (rangeEnd-rangeStart) + 1)
.Select(n => prefix + n);
}
}
Enumerable.Range creates a range of numbers. The Select takes that range and returns a set of strings consisting of the prefix concatenated with the number in the range.
And a unit test to make sure it works:
[TestClass]
public class DetermineRangeFromLastFourCharacters
{
[TestMethod]
public void ReturnsExpectedRangeOfStrings()
{
var result = new StringRangeCreator().CreateStringRange("abc", 1, 10).ToList();
Assert.AreEqual(10, result.Count);
Assert.AreEqual("abc1", result[0]);
Assert.AreEqual("abc10", result[9]);
}
}
But if these are serial numbers then you maybe you don't want ABC8, ABC9, ABC10. You might want ABC08, ABC09, ABC10. All the same length.
So here's the modified class. I'm guessing a little at what the expected behavior might be. It lets you specify an optional minimum number of digits so that you can pad accordingly:
public class StringRangeCreator
{
public IEnumerable<string> CreateStringRange(
string prefix, int rangeStart, int rangeEnd, int minimumDigits = 1)
{
if (rangeStart > rangeEnd) throw new ArgumentException(
$"{nameof(rangeStart)} cannot be greater than {nameof(rangeEnd)}");
return Enumerable.Range(rangeStart, (rangeEnd-rangeStart) + 1)
.Select(n => prefix + n.ToString("0").PadLeft(minimumDigits, '0'));
}
}
And another unit test:
[TestMethod]
public void PadsNumbersAccordingToParameter()
{
var result = new StringRangeCreator().CreateStringRange("abc", 999, 1001, 3).ToList();
Assert.AreEqual(3, result.Count);
Assert.AreEqual("abc999", result[0]);
Assert.AreEqual("abc1001", result[2]);
}
Some other scenarios you might want to account for are negative numbers or extremely large ranges.
Now that the problem of creating the result set is separated into a class with simple inputs and outputs that you can test, what remains is to take the input from the form and break it down into these inputs. That might include making sure that both strings have the same prefixes and making sure that the last parts of the strings are numbers.
But the whole thing will be a little simpler once it's not all in one big method. That also makes it easier to change when you realize something different about how you want it to work. Validating your input can be one step, and then getting the results can be another.
The unit tests help because you don't want to have to debug the whole thing to see if it works. Enumerable.Range didn't work the way I thought it did, so I had to fix a bug. It was easy to find and fix with the unit tests. It would have been harder if I had to run a whole app and then step through it in the debugger.

How to convert int to List<int> [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I want an solution to convert an input int say 010 to list of int {0,1,0}.
Below is code I tried, works until 0 is encountered.
Int num = 010;
List<int> listOfInt = new List<int>();
While(num > 0)
listOfInt.Add(num%10);
num / = 10;
I just want to split entered int and convert it to list of int. LINQ is fine if that could be efficient!
As others already mentioned 010 is identical to 10 when having parsed as int. However you could have your number as string coming from a console-input for example.
string myNumber = "010";
This can be split on every character quite easy using LINQ:
var intList = myNumber.Select(x => Convert.ToInt32(x.ToString())).ToList();
As every character is internally an int where '0' equals 49 you have to convert every single character to a string before which is done by using ToString.
Console.WriteLine("Enter a number:")
var input = Console.ReadLine();
List<int> result = input.Select(c => int.Parse(c.ToString())).ToList();
There is no difference between 010 and 10 either in computer arithmetic or real life. Zero is zero.
If you want to convert the number to a specific string format and extract the characters, perform the same steps as the statement:
10.ToString("000").Select(c=>c-48).ToList();
The result is a list with the numbers 0,1,0.
The expression c-48 takes advantage of the fact that characters are essentially ints, and digits start from 0 upwards. So 48 is 0, 1 is 49 etc.
If the input is a string, eg "10" you'll have to pad it with 0s up to the desired length:
"10".PadLeft(3,'0').Select(c=>c-48).ToList()
The result will be 0,1,0 again.
If, after all, you only want to retrieve characters from a paddes string, you only need padding, as a String is an IEnumerable. You can copy the characters to an array with String.ToCharArray() or to a List as before:
"10".PadLeft(3,'0').ToList()
string num = "010";
List<int> listOfInt = new List<int>();
foreach(char item in num)
{
listOfInt.Add(Convert.ToInt32(item.ToString()));
}

Regular expression to match numbers between 1-5000 [duplicate]

This question already has answers here:
Using regular expressions to validate a numeric range
(11 answers)
Closed 2 years ago.
I would like to use a regex for a textbox that allows only numbers between 1-5000
I've tried the following but it wont work:
#"/^(?:1|5000|-[1-9]\d?)$/
You can use ^(?:[1-9]|\d{2,3}|[1-4]\d{3}|5000)$. But you'd better to parse to Int then do simple maths.
With some parsing beforehand, you can make the regex very simple:
string s = textBox1.Text;
string r = "";
int n = 0;
if (int.TryParse(s, out n) && (n>=1 && n<=5000))
{
r = "y";
}
if (Regex.IsMatch(r, "y")) {
// input was valid
MessageBox.Show("OK");
}
Try ...
^(?:[1-4][0-9]{1,3}|[1-9][0-9]{0,2}|5000)$
You can do something like the following:
^(([1-4][0-9]{0,3})|([1-9][0-9]{0,2})|(5000))$
The first two groups will match anything in the range of 1 - 4999. You add the |5000 at the end to make it match the range 1 - 5000. The three cases here are:
The number is exactly 5000
The number is between 1 and 3 digits. In this case, it can't possibly be more than 5000. However, the first number must be 1 - 9 so that you can't get something like "009" or "000."
The number is 4 digits, in which case it must be between 1000 - 4999
With that said, I think it would probably be simpler to just parse the int and see if it's in range.
You can try something like this (0-366)
^(0?[0-9]?[0-9]|[1-2][0-9][0-9]|3[0-5][0-9]|36[0-6])$

Categories