Improving code string processing - c#

I have this string:
var string1 = numericUpDown2.Text; // 1
always want to contain 4 numbers like 0001 or for "11" = 0011.
I used this code to make it:
private string Corection4(string variable)
{
var stringlen = variable.Length;
if (stringlen < 2)
{
string corectvariable = "000" + variable;
return corectvariable;
}
if (stringlen < 3)
{
string corectvariable = "00" + variable;
return corectvariable;
}
if (stringlen < 4)
{
string corectvariable = "0" + variable;
return corectvariable;
}
else
{
string corectvariable = variable;
return corectvariable;
}
}
Now i need some help to improve this code

You can make it easy by ToString() method. For example:
var correctVariable = variable.ToString("D4");
It would add extra zeros to your string.
If you are working on strings, parse it first to int value:
var correctVariable = string.Format("{0:D4}", int.Parse(variable));

You can use String.Format()
int number = 11;
//D4 = pad with 0000
string outputValue = String.Format("{0:D4}", number);

Related

Is there any possible way to check which Split() element is used?

I have this code:
string expresie = Console.ReadLine();
char[] separatori = {'+', '-'};
string[] elementeExpresie = expresie.Split(separatori);
int elem0 = int.Parse(elementeExpresie[0]);
int elem1 = int.Parse(elementeExpresie[1]);
int elem2 = int.Parse(elementeExpresie[2]);
/////////////////////////////////////////////////////////////////////////////////////////
int operatie1 = 0;
if (separatori[0] == '+')
{
operatie1 = elem0+elem1;
}
else if (separatori[0] == '-')
{
operatie1 = elem0-elem1;
}
int operatie2 = 0;
if(separatori[1] == '+')
{
operatie2 = operatie1+elem2;
}
else if(separatori[1] == '-')
{
operatie2 = operatie1-elem2;
}
Console.WriteLine(operatie2);
I have to code a program similar to a calculator, where the user inserts an arithmetic expression in the console, and at the end, it has to show the results of the calculation. The second part of the code doesn't work, because I need to check which char[] element is used; the "+" or the "-". And that's actually my question: Is there any possible way to check which Split() element is used?
Exemple: string mathExpression = "10 + 11 - 5"
Console output: 16
PS: It's for a school homework and I need to use the .split method.
Replace your operators with padded operators, and split on the pad character.
For example
var pad = "\0";
var input = "1+2";
var operators = new string[] { "+", "-" };
foreach (var operator in operators)
{
input = input.Replace(operator, pad + operator + pad);
}
var tokens = input.Split( new string[] { pad } , StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(tokens[0]); // Outputs "1"
Console.WriteLine(tokens[1]); // Outputs "+"
Console.WriteLine(tokens[2]); // Outputs "2"
One idea is to split on whitespace so you have a collection of operands and operators. Then you can do something like below:
string expression = Console.ReadLine();
string[] expParts = expression.Split();
int operand1 = int.Parse(expParts[0]);
string operator1 = expParts[1];
int operand2 = int.Parse(expParts[2]);
string operator2 = expParts[3];
int operand3 = int.Parse(expParts[4]);
int result = operand1;
if (operator1 == "+")
{
result += operand2;
}
else if (operator1 == "-")
{
result -= operand2;
}
if (operator2 == "+")
{
result += operand3;
}
else if (operator2 == "-")
{
result -= operand3;
}
Console.WriteLine(result);
The drawback here is that it requires a precise string format ("10 + 11 - 5"). If someone entered "10+11-5", it wouldn't work.

c# regular expression getting specific string from string[CLOSE]

help i want to get the specific string from my string x="Glass 1 1000"; i want to get the string "Glass" only and save it to my string type.
int[] quanvalue = new int[2];
int x1 = 0;
string type = "";
string x="Glass 1 1000";
string[] numbers = Regex.Split(x, #"\D+");
foreach (string value in numbers)
{
if (!string.IsNullOrEmpty(value))
{
int ib = int.Parse(value);
quanvalue[x1] = ib;
MessageBox.Show(quanvalue[0].ToString() + " " + quanvalue[1].ToString());
x1++;
}
else
{
// i want to get string from here
}
string sub = x.Substring(0, 5);
You can use a substring function to fetch the first 5 characters from x.
And save it in x itself

C#: Increment only the last number of a String

I have strings that look like this:
1.23.4.34
12.4.67
127.3.2.21.3
1.1.1.9
This is supposed to be a collection of numbers, separated by '.' symbols, similar to an ip address. I need to increment only the last digit/digits.
Expected Output:
1.23.4.35
12.4.68
127.3.2.21.4
1.1.1.10
Basically, increment whatever the number that is after the last '.' symbol.
I tried this:
char last = numberString[numberString.Length - 1];
int number = Convert.ToInt32(last);
number = number + 1;
If I go with the above code, I just need to replace the characters after the last '.' symbol with the new number. How do I get this done, good folks? :)
It seems to me that one method would be to:
split the string on . to get an array of components.
turn the final component into an integer.
increment that integer.
turn it back into a string.
recombine the components with . characters.
See, for example, the following program:
using System;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
String original = "1.23.4.34";
String[] components = original.Split('.');
int value = Int32.Parse(components[components.Length - 1]) + 1;
components[components.Length - 1] = value.ToString();
String newstring = String.Join(".",components);
Console.WriteLine(newstring);
}
}
}
which outputs the "next highest" value of:
1.23.4.35
You can use string.LastIndexOf().
string input = "127.3.2.21.4";
int lastIndex = input.LastIndexOf('.');
string lastNumber = input.Substring(lastIndex + 1);
string increment = (int.Parse(lastNumber) + 1).ToString();
string result = string.Concat(input.Substring(0, lastIndex + 1), increment);
You need to extract more than just the last character. What if the last character is a 9 and then you add 1 to it? Then you need to correctly add one to the preceding character as well. For example, the string 5.29 should be processed to become 5.30 and not simply 5.210 or 5.20.
So I suggest you split the string into its number sections. Parse the last section into an integer. Increment it and then create the string again. I leave it as an exercise for the poster to actually write the few lines of code. Good practice!
Something like this:
var ip = "1.23.4.34";
var last = int.Parse(ip.Split(".".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries).Last());
last = last + 1;
ip = string.Format("{0}.{1}",ip.Remove(ip.LastIndexOf(".")) , last);
If you are dealing with IP, there will be some extra code in case of .034, which should be 035 instead of 35. But that logic is not that complicated.
It's simple as this, use Split() and Join() String methods
String test = "1.23.4.34"; // test string
String[] splits = test.Split('.'); // split by .
splits[splits.Length - 1] = (int.Parse(splits[splits.Length - 1])+1).ToString(); // Increment last integer (Note : Assume all are integers)
String answ = String.Join(".",splits); // Use string join to make the string from string array. uses . separator
Console.WriteLine(answ); // Answer : 1.23.4.35
Using a bit of Linq
int[] int_arr = numberString.Split('.').Select(num => Convert.ToInt32(num)).ToArray();
int_arr[int_arr.Length - 1]++;
numberString = "";
for(int i = 0; i < int_arr.Length; i++) {
if( i == int_arr.Length - 1) {
numberString += int_arr[i].ToString();
}
else {
numberString += (int_arr[i].ToString() + ".");
}
}
Note: on phone so can't test.
My Solution is:
private static string calcNextCode(string value, int index)
{
if (value is null) return "1";
if (value.Length == index + 1) return value + "1";
int lastNum;
int myIndex = value.Length - ++index;
char myValue = value[myIndex];
if (int.TryParse(myValue.ToString(), NumberStyles.Integer, null, out lastNum))
{
var aStringBuilder = new StringBuilder(value);
if (lastNum == 9)
{
lastNum = 0;
aStringBuilder.Remove(myIndex, 1);
aStringBuilder.Insert(myIndex, lastNum);
return calcNextCode(aStringBuilder.ToString(), index++);
}
else
{
lastNum++;
}
aStringBuilder.Remove(myIndex, 1);
aStringBuilder.Insert(myIndex, lastNum);
return aStringBuilder.ToString();
}
return calcNextCode(value, index++);
}

Split numeric and Non-Numeric in a String

If I have a string value like this "1234-", then I need to split till the non-numeric character that is - and add numeric value 1 after the non-numeric char. later I have to update the value to "1234-1". Then the program will check with the last updated value 1234-1 then it will increment by 1 every time and store it for future use. If no non-numeric in a string then the program will increment by 1 with the numeric string.
Below are some examples of String and Output Value
Ex Str1 Output
2014- 2014-1
2014-1 2014-2
AAA AAA1
ABC-ABC ABC-ABC1
12345 12346
1234AA 1234AA1
I have used the below code before.
Code
var SiteFile = (from site in db.SiteFiles where site.Code == "ACQPONUM" select site.Line2).FirstOrDefault(); // Get Input string to generate AUTO number.
int Count = (from Porders in db.Porders where Porders.No.StartsWith(SiteFile) select Porders.No).ToList().Count; // Get the count of matching values in db.
var PONo = (from Porders in db.Porders where Porders.No.StartsWith(SiteFile) select Porders.No).ToList(); // Get list of Matching existing values.
if (Count != 0)
{
if (PONo != null)
{
int Val = (from PONos in PONo let value = Regex.Match(PONos, #"\d+").Value select Convert.ToInt32(value == string.Empty ? "0" : Regex.Match(PONos, #"\d+").Value) + 1).Concat(new[] { 0 }).Max(); // Fiind the maximum value in the matched list nd Increment value by if same type exists in the db.
porder.No = SiteFile + Val.ToString();
}
}
else
{
porder.No = SiteFile + "1";
}
Any help to this will be appreciated.
Maybe something like this:
string s = "123419";
string res = null;
char ch = s[s.Length - 1];
if(char.IsDigit(ch)) // handle numbers
{
res = s.Substring(0,s.Length - 1);
string suffix = null;
// special case
if(ch == '9'){
suffix = "10";
}
else
{
suffix = (++ch).ToString();
}
res += suffix;
}
else
{
res = string.Format("{0}1", s);
}
Try this code:
private string Incrementvalue(string str)
{
string retVal;
if (str.Contains(DELIMITER))
{
string[] parts = str.Split(new char[] { DELIMITER }, 2);
string origSuffix = parts[1];
string newSuffix;
int intSuffix;
if (int.TryParse(origSuffix, out intSuffix))
//Delimiter exists and suffix is already a number: Increment!
newSuffix = (intSuffix + 1).ToString();
else
//Delimiter exists and suffix is NTO number: Add a "1" suffix.
newSuffix = origSuffix + 1;
retVal = parts[0] + DELIMITER + newSuffix;
}
else
{
int temp;
if (int.TryParse(str, out temp))
{
//Delimiter does not exists and the input is a number: Increment last digit!
string newSuffix = (int.Parse(str[str.Length - 1].ToString()) + 1).ToString();
retVal = str.Substring(0, str.Length - 1) + newSuffix;
retVal = str.Substring(0, str.Length - 1) + newSuffix;
}
else
{
//Delimiter does not exists and the input is NOT a number: Add a "1" suffix.
retVal = str + "1";
}
}
return retVal;
}
The code could be written in a much more compact manner, but think this will be more readable and it will work...

How to make next step of a string. C#

The question is complicated but I will explain it in details.
The goal is to make a function which will return next "step" of the given string.
For example
String.Step("a"); // = "b"
String.Step("b"); // = "c"
String.Step("g"); // = "h"
String.Step("z"); // = "A"
String.Step("A"); // = "B"
String.Step("B"); // = "C"
String.Step("G"); // = "H"
Until here its quite easy, But taking in mind that input IS string it can contain more than 1 characters and the function must behave like this.
String.Step("Z"); // = "aa";
String.Step("aa"); // = "ab";
String.Step("ag"); // = "ah";
String.Step("az"); // = "aA";
String.Step("aA"); // = "aB";
String.Step("aZ"); // = "ba";
String.Step("ZZ"); // = "aaa";
and so on...
This doesn't exactly need to extend the base String class.
I tried to work it out by each characters ASCII values but got stuck with strings containing 2 characters.
I would really appreciate if someone can provide full code of the function.
Thanks in advance.
EDIT
*I'm sorry I forgot to mention earlier that the function "reparse" the self generated string when its length reaches n.
continuation of this function will be smth like this. for example n = 3
String.Step("aaa"); // = "aab";
String.Step("aaZ"); // = "aba";
String.Step("aba"); // = "abb";
String.Step("abb"); // = "abc";
String.Step("abZ"); // = "aca";
.....
String.Step("zzZ"); // = "zAa";
String.Step("zAa"); // = "zAb";
........
I'm sorry I didn't mention it earlier, after reading some answers I realised that the problem was in question.
Without this the function will always produce character "a" n times after the end of the step.
NOTE: This answer is incorrect, as "aa" should follow after "Z"... (see comments below)
Here is an algorithm that might work:
each "string" represents a number to a given base (here: twice the count of letters in the alphabet).
The next step can thus be computed by parsing the "number"-string back into a int, adding 1 and then formatting it back to the base.
Example:
"a" == 1 -> step("a") == step(1) == 1 + 1 == 2 == "b"
Now your problem is reduced to parsing the string as a number to a given base and reformatting it. A quick googling suggests this page: http://everything2.com/title/convert+any+number+to+decimal
How to implement this?
a lookup table for letters to their corresponding number: a=1, b=2, c=3, ... Y = ?, Z = 0
to parse a string to number, read the characters in reverse order, looking up the numbers and adding them up:
"ab" -> 2*BASE^0 + 1*BASE^1
with BASE being the number of "digits" (2 count of letters in alphabet, is that 48?)
EDIT: This link looks even more promising: http://www.citidel.org/bitstream/10117/20/12/convexp.html
Quite collection of approaches, here is mine:-
The Function:
private static string IncrementString(string s)
{
byte[] vals = System.Text.Encoding.ASCII.GetBytes(s);
for (var i = vals.Length - 1; i >= 0; i--)
{
if (vals[i] < 90)
{
vals[i] += 1;
break;
}
if (vals[i] == 90)
{
if (i != 0)
{
vals[i] = 97;
continue;
}
else
{
return new String('a', vals.Length + 1);
}
}
if (vals[i] < 122)
{
vals[i] += 1;
break;
}
vals[i] = 65;
break;
}
return System.Text.Encoding.ASCII.GetString(vals);
}
The Tests
Console.WriteLine(IncrementString("a") == "b");
Console.WriteLine(IncrementString("z") == "A");
Console.WriteLine(IncrementString("Z") == "aa");
Console.WriteLine(IncrementString("aa") == "ab");
Console.WriteLine(IncrementString("az") == "aA");
Console.WriteLine(IncrementString("aZ") == "ba");
Console.WriteLine(IncrementString("zZ") == "Aa");
Console.WriteLine(IncrementString("Za") == "Zb");
Console.WriteLine(IncrementString("ZZ") == "aaa");
public static class StringStep
{
public static string Next(string str)
{
string result = String.Empty;
int index = str.Length - 1;
bool carry;
do
{
result = Increment(str[index--], out carry) + result;
}
while (carry && index >= 0);
if (index >= 0) result = str.Substring(0, index+1) + result;
if (carry) result = "a" + result;
return result;
}
private static char Increment(char value, out bool carry)
{
carry = false;
if (value >= 'a' && value < 'z' || value >= 'A' && value < 'Z')
{
return (char)((int)value + 1);
}
if (value == 'z') return 'A';
if (value == 'Z')
{
carry = true;
return 'a';
}
throw new Exception(String.Format("Invalid character value: {0}", value));
}
}
Split the input string into columns and process each, right-to-left, like you would if it was basic arithmetic. Apply whatever code you've got that works with a single column to each column. When you get a Z, you 'increment' the next-left column using the same algorithm. If there's no next-left column, stick in an 'a'.
I'm sorry the question is stated partly.
I edited the question so that it meets the requirements, without the edit the function would end up with a n times by step by step increasing each word from lowercase a to uppercase z without "re-parsing" it.
Please consider re-reading the question, including the edited part
This is what I came up with. I'm not relying on ASCII int conversion, and am rather using an array of characters. This should do precisely what you're looking for.
public static string Step(this string s)
{
char[] stepChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
char[] str = s.ToCharArray();
int idx = s.Length - 1;
char lastChar = str[idx];
for (int i=0; i<stepChars.Length; i++)
{
if (stepChars[i] == lastChar)
{
if (i == stepChars.Length - 1)
{
str[idx] = stepChars[0];
if (str.Length > 1)
{
string tmp = Step(new string(str.Take(str.Length - 1).ToArray()));
str = (tmp + str[idx]).ToCharArray();
}
else
str = new char[] { stepChars[0], str[idx] };
}
else
str[idx] = stepChars[i + 1];
break;
}
}
return new string(str);
}
This is a special case of a numeral system. It has the base of 52. If you write some parser and output logic you can do any kind of arithmetics an obviously the +1 (++) here.
The digits are "a"-"z" and "A" to "Z" where "a" is zero and "Z" is 51
So you have to write a parser who takes the string and builds an int or long from it. This function is called StringToInt() and is implemented straight forward (transform char to number (0..51) multiply with 52 and take the next char)
And you need the reverse function IntToString which is also implementet straight forward (modulo the int with 52 and transform result to digit, divide the int by 52 and repeat this until int is null)
With this functions you can do stuff like this:
IntToString( StringToInt("ZZ") +1 ) // Will be "aaa"
You need to account for A) the fact that capital letters have a lower decimal value in the Ascii table than lower case ones. B) The table is not continuous A-Z-a-z - there are characters inbetween Z and a.
public static string stepChar(string str)
{
return stepChar(str, str.Length - 1);
}
public static string stepChar(string str, int charPos)
{
return stepChar(Encoding.ASCII.GetBytes(str), charPos);
}
public static string stepChar(byte[] strBytes, int charPos)
{
//Escape case
if (charPos < 0)
{
//just prepend with a and return
return "a" + Encoding.ASCII.GetString(strBytes);
}
else
{
strBytes[charPos]++;
if (strBytes[charPos] == 91)
{
//Z -> a plus increment previous char
strBytes[charPos] = 97;
return stepChar(strBytes, charPos - 1); }
else
{
if (strBytes[charPos] == 123)
{
//z -> A
strBytes[charPos] = 65;
}
return Encoding.ASCII.GetString(strBytes);
}
}
}
You'll probably want some checking in place to ensure that the input string only contains chars A-Za-z
Edit Tidied up code and added new overload to remove redundant byte[] -> string -> byte[] conversion
Proof http://geekcubed.org/random/strIncr.png
This is a lot like how Excel columns would work if they were unbounded. You could change 52 to reference chars.Length for easier modification.
static class AlphaInt {
private static string chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static string StepNext(string input) {
return IntToAlpha(AlphaToInt(input) + 1);
}
public static string IntToAlpha(int num) {
if(num-- <= 0) return "a";
if(num % 52 == num) return chars.Substring(num, 1);
return IntToAlpha(num / 52) + IntToAlpha(num % 52 + 1);
}
public static int AlphaToInt(string str) {
int num = 0;
for(int i = 0; i < str.Length; i++) {
num += (chars.IndexOf(str.Substring(i, 1)) + 1)
* (int)Math.Pow(52, str.Length - i - 1);
}
return num;
}
}
LetterToNum should be be a Function that maps "a" to 0 and "Z" to 51.
NumToLetter the inverse.
long x = "aazeiZa".Aggregate((x,y) => (x*52) + LetterToNum(y)) + 1;
string s = "";
do { // assertion: x > 0
var c = x % 52;
s = NumToLetter() + s;
x = (x - c) / 52;
} while (x > 0)
// s now should contain the result

Categories

Resources