开发者

Increment an index that uses numbers and characters (aka Base36 numbers)

开发者 https://www.devze.com 2023-02-02 11:22 出处:网络
I have a string based code that can be either two or three characters in length and I am looking for some help in creating a function that will increment it.

I have a string based code that can be either two or three characters in length and I am looking for some help in creating a function that will increment it.

Each 'digi开发者_如何学Ct' of the code has a value of 0 to 9 and A to Z.

some examples:

the first code in the sequence is 000

009 - next code is - 00A

00D - next code is - 00E

AAZ - next code is - AB0

the last code is ZZZ.

Hope this makes some sense.


Thanks for the advice guys.

This is what I independently came up with.

    private static String Increment(String s)
    {
        String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        char lastChar = s[s.Length - 1];
        string fragment = s.Substring(0, s.Length - 1);

        if (chars.IndexOf(lastChar) < 35)
        {
            lastChar = chars[chars.IndexOf(lastChar) + 1];

            return fragment + lastChar;
        }

        return Increment(fragment) + '0';
    }

I don't know if it is better/worse but seems to work. If anyone can suggest improvements then that is great.


Maintain the counter as an int and increment this. Convert the int to your character representation by modding and dividing by 36 iterativly. Map the modded range (0-35) to 0-Z.

Example

Updated with functions to go in either direction:

internal class Program
{
    const int Base = 36;

    public static void Main()
    {
        Console.WriteLine(ToInt("0AA"));
        Console.WriteLine(ToString(370));
    }

    private static string ToString(int counter)
    {
        List<char> chars = new List<char>();

        do
        {
            int c = (counter % Base);

            char ascii = (char)(c + (c < 10 ? 48 : 55));

            chars.Add(ascii);
        }
        while ((counter /= Base) != 0);

        chars.Reverse();

        string charCounter = new string(chars.ToArray()).PadLeft(3, '0');

        return charCounter;
    }

    private static int ToInt(string charCounter)
    {
        var chars = charCounter.ToCharArray();

        int counter = 0;

        for (int i = (chars.Length - 1), j = 0; i >= 0; i--, j++)
        {
            int chr = chars[i];

            int value = (chr - (chr > 57 ? 55 : 48)) * (int)Math.Pow(Base, j);

            counter += value;
        }

        return counter;
    }

For more variants of conversion code see Quickest way to convert a base 10 number to any base in .NET?.


Does this do what you need?

public class LetterCounter
{
    private static readonly string[] _charactersByIndex = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };

    public string GetStr(int i)
    {
        if (i < _charactersByIndex.Length)
            return _charactersByIndex[i];

        int x = i / (_charactersByIndex.Length - 1) - 1;
        string a = _charactersByIndex[x];
        string b = GetStr(i - (_charactersByIndex.Length - 1));
        return a + b;
    }
}

}


Based on @Martin answer, I found some error when two ZZ comes, this makes exception in code

private static String Increment(String s,bool IsFromRecursion=false)
{
    String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    //Added this condition
    if (IsFromRecursion && string.IsNullOrEmpty(number))
    {
         return "1";
    }
    //Added this condition

    char lastChar = s[s.Length - 1];
    string fragment = s.Substring(0, s.Length - 1);

    if (chars.IndexOf(lastChar) < 35)
    {
        lastChar = chars[chars.IndexOf(lastChar) + 1];

        return fragment + lastChar;
    }

    return Increment(fragment,true) + '0';
}

When we call this method we pass first parameter only.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号