How to make the next step of the line. FROM#

The question is complex, but I will explain it in detail.

The goal is to create a function that returns the next "step" of a 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 now, its pretty easy, but given that the input string IS can contain more than 1 character, and the function should behave as follows.

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

etc.

This does not necessarily extend the base class String.

I tried to process it with ASCII character values, but was stuck with strings containing 2 characters.

I would really appreciate it if someone could provide the full function code.

Thanks in advance.

EDIT * I'm sorry, I forgot to mention earlier that the function "reshapes" 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 wish I had mentioned this before, after reading a few answers, I realized that the problem was in the question.

Without this, the function will always call the character "a" n times after the end of the step.

+6
string c # char ascii
source share
10 answers

NOTE: This answer is incorrect , because after โ€œZโ€ you should follow โ€œaaโ€ (see comments below)

Here is an algorithm that might work:

each "string" represents a number for a given base (here: twice the number of letters in the alphabet).

Thus, the next step can be calculated by playing the โ€œnumberโ€ line back to 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 comes down to parsing a string as a number to a given base and reformatting it. Quick googling offers this page: http://everything2.com/title/convert+any+number+to+decimal

How to implement this?

  • letters search table with the corresponding number: a = 1, b = 2, c = 3, ... Y = ?, Z = 0
  • for parsing a string, reading characters in reverse order, finding numbers and adding them:
    • "ab" โ†’ 2 * BASE ^ 0 + 1 * BASE ^ 1
    • with BASE the number of "digits" (2 numbers of letters in the alphabet, is it 48?)

EDIT: This link looks even more promising: http://www.citidel.org/bitstream/10117/20/12/convexp.html

+11
source share

Quite a selection, here's mine: -

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

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"); 
+5
source share
 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)); } } 
+3
source share

Divide the input line into columns and process each, from right to left, as if it were basic arithmetic. Apply any code that you have that works with one column for each column. When you get Z, you โ€œincrementโ€ the next left column using the same algorithm. If there is no next left column, insert "a".

0
source share

You need to consider A) the fact that uppercase letters have a lower decimal value in the Ascii table than in lower case. B) The table is not continuous. AZaz are characters between 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 will probably need an in-place check to make sure that the input string contains only A-Za-z characters


Edit Aligned code and added new overload to remove redundant bytes [] โ†’ string โ†’ byte [] conversion

Proof of http://geekcubed.org/random/strIncr.png

0
source share

Sorry, the question is partially posed. I edited the question so that it met the requirements, without editing, the function would ultimately have to n increase each word n โ€‹โ€‹times step by step from lower case a to upper case z without "re-parsing".

Please consider reading the question again, including the edited part.

0
source share

Here is what I came up with. I do not rely on the ASCII int conversion and prefer to use an array of characters. This should do exactly what you are 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); } 
0
source share

This is a special case of the number system. It has a base of 52. If you write parser and output logic, you can do any arithmetic, obviously +1 (++) here. The numbers "a" are "z" and "A" are "Z", where "a" is zero and "Z" is 51

So, you need to write a parser that takes a string and builds int or long from it. This function is called StringToInt () and is implemented directly (converting char to number (0..51) is multiplied by 52 and takes the next char)

And you need the reverse function IntToString, which is also implemented in a straightforward manner (mod int with 52 and convert the result to a digit, divide int by 52 and repeat this until int becomes zero)

Using these functions, you can do such things: IntToString (StringToInt ("ZZ") +1) // Will be "aaa"

0
source share

This is very similar to how Excel columns work if they are unlimited. You can change 52 to reference characters. Length for easy 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; } } 
0
source share

LetterToNum should be a function that maps "a" to 0 and "Z" to 51. NumToLetter opposite.

 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 
-one
source share

All Articles