Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 757
George Avatar asked Sep 04 '09 12:09

George


2 Answers

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

like image 94
Daren Thomas Avatar answered Sep 21 '22 12:09

Daren Thomas


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");
like image 24
AnthonyWJones Avatar answered Sep 21 '22 12:09

AnthonyWJones