2

I have a requirement for a custom number system in C# which goes as following:

A - 1
B - 2
...
Z - 26
AA - 27
AB - 28

I've made a function that converts from arbitrary strings to numbers like this:

    private const int Min = 'A';
    private const int Max = 'Z';
    private const int Base = Max - Min + 1;

    private static int GetCharValue(char c)
    {
        if (c < Min || c > Max)
            throw new ArgumentOutOfRangeException(nameof(c), c, $"Character needs to be between '{Min}' and '{Max}', was '{c}'.");

        return c - Min + 1;
    }

    public static int GetStringValue(string s)
    {
        char[] chars = s.ToCharArray();
        int[] values = new int[chars.Length];
        for (var i = 0; i < chars.Length; i++)
        {
            values[i] = GetCharValue(chars[i]);
        }

        int position = 1;
        int value = 0;
        for (var i = values.Length - 1; i >= 0; i--)
        {
            value += position * values[i];
            position *= Base;
        }

        return value;
    }

I've tested it to be working for up to AAA (not rigorously, just skimming over the output of printing them all). However, I can't for the life of me figure out how to write the reverse function. In other words, I need 1 to return A, 26 to return Z and 27 to return AA. The "problem" is that this number system has no 0, so it doesn't easily convert to any base. For instance, if A was 0, then AA would also be 0, but it's not. So how do I solve this?

17
  • 2
    ...Or AAA is 703? Commented Jul 25, 2017 at 12:40
  • it seems like you're trying to create a base_n number system... but i don't think AA should represent what you think it does Commented Jul 25, 2017 at 12:41
  • The "problem" is that your numeric system does have a zero, but it isn't consistent. It's some weird not really positional system. In AA, the first A is one, while the second A is zero. Should AAA mean 011, 010, 100, 101, 110...? What's the actual requirement, just some vague expectation from a customer that doesn't really know what he wants? Or are you trying to replicate Excel's coordinate system? Commented Jul 25, 2017 at 12:41
  • 1
    @DavidG: int result = source.Aggregate(0, (s, a) => s * 26 + a - 'A' + 1); where source = "AAA"; Commented Jul 25, 2017 at 12:41
  • 1
    Is this correct? ideone.com/vqHqBu Commented Jul 25, 2017 at 13:02

1 Answer 1

0

you can simply generate it like this....

    public static IEnumerable<string> generate()
    {
        long n = -1;
        while (true) yield return toBase26(++n);
    }

    public static string toBase26(long i)
    {
        if (i == 0) return ""; i--;
        return toBase26(i / 26) + (char)('A' + i % 26);
    }



    public static void BuildQuery()
    {
        IEnumerable<string> lstExcelCols = generate();
        try
        {

            string s = lstExcelCols.ElementAtOrDefault(1) ;
        }
        catch (Exception exc)
        {

        }


    }
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.