11
\$\begingroup\$

I needed to create a simple method that converts numbers in Base 26 (string) using, as expected, letters from a to z.

But that's not all, this Base 26 needs to be One Based. Which means that there is no representation for zero absolute value and there is a representation for 26 absolute value. Let me show a example:

In Base 26 Zero Based the number 18252 will be represented like:

$$ (18252)_{10} = (BBAA)_{26} $$

where B == 1 and A == 0. But as an One Based I need to get:

$$ (18252)_{10} = (ZYZ)_{26} $$

where Y == 25 and Z == 26.

So I came up with this snippet:

var array = new List<int>();
var div = myNumber;
var getOne = 0;
while (div > 26)
{
 var value = div % 26;
 value -= getOne;
 if (value <= 0)
 {
 value += 26;
 getOne = 1;
 }
 else
 {
 getOne = 0;
 }
 array.Add(value);
 div = div / 26;
}
div -= getOne;
if (div > 0) array.Add(div);
var letters = array.Select(s => (char)('A' + s - 1)).Reverse().ToArray();
return new string(letters);

Now I wonder if there is a better way write this.

asked May 12, 2015 at 15:31
\$\endgroup\$
2
  • 2
    \$\begingroup\$ It looks like you are trying to get an excel column name from a number e.g. 1 => A, 2 => B, ... 26 => Z, 27 => AA, 28 => AB. Is this correct? If so, are you happy with a solution that works as far as 16384 (the max number of columns in an Excel spreadsheet)? \$\endgroup\$ Commented May 12, 2015 at 15:59
  • 1
    \$\begingroup\$ Yes, can be like Excel \$\endgroup\$ Commented May 12, 2015 at 16:13

2 Answers 2

9
\$\begingroup\$

You could slightly simplify the code as follows:

  • Reduce the number of variables.
  • Use the LinkedList<T> (and the AddFirst method) instead of the List<T> to eliminate reversion of array.
    Alternatively you can use the List<T>.Insert method to achieve the same result.

The code:

private static string ToBase26(int myNumber)
{
 var array = new LinkedList<int>();
 while (myNumber > 26)
 {
 int value = myNumber % 26;
 if (value == 0)
 {
 myNumber = myNumber / 26 - 1;
 array.AddFirst(26);
 }
 else
 {
 myNumber /= 26;
 array.AddFirst(value);
 }
 }
 if (myNumber > 0)
 {
 array.AddFirst(myNumber);
 }
 return new string(array.Select(s => (char)('A' + s - 1)).ToArray());
}
answered May 12, 2015 at 16:24
\$\endgroup\$
0
1
\$\begingroup\$

You could reduce the number of variables, and use LinkedList<T> method to eliminate reversion, like this:

private static string ToBase26(int number)
{
 var list = new LinkedList<int>();
 list.AddFirst((number - 1) % 26);
 while ((number = --number / 26 - 1) > 0) list.AddFirst(number % 26);
 return new string(list.Select(s => (char)(s + 65)).ToArray());
}
answered May 13, 2015 at 12:10
\$\endgroup\$
5
  • \$\begingroup\$ This code doesn't even compile. \$\endgroup\$ Commented May 13, 2015 at 12:24
  • \$\begingroup\$ What errors are it throwing? \$\endgroup\$ Commented May 13, 2015 at 12:31
  • \$\begingroup\$ Try it yourself and see. \$\endgroup\$ Commented May 13, 2015 at 12:36
  • \$\begingroup\$ And please perform some tests before posting. For instance, make sure that this code returns ZYZ for 18252. \$\endgroup\$ Commented May 13, 2015 at 12:47
  • \$\begingroup\$ Fixed, and edited. \$\endgroup\$ Commented May 14, 2015 at 10:57

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.