简体   繁体   English

C#代码问题:修订号和字母

[英]C# Code Problem: Revision Numbers and Letters

I'm trying to write a function that takes a revision number (int) and turns it into a revision name (string). 我正在尝试编写一个带有修订号(int)的函数,并将其转换为修订名称(字符串)。 The formula should produce outputs similar to this: 该公式应产生类似于此的输出:

Number  Name
1       A
2       B
3       C
...     ...
25      Y
26      Z
27      AA
28      AB
29      AC
...     ...
51      AY
52      AZ
53      BA
54      BB
55      BC
...     ...

This seems simple, but I think it might involve recursion and I'm terrible at that. 这看起来很简单,但我认为它可能涉及递归,我很可怕。 Any suggestions? 有什么建议么?

I think this is the same as working out the Excel column name from a column number: 我认为这与从列号中计算Excel列名称相同:

private string GetExcelColumnName(int columnNumber)
{
    int dividend = columnNumber;
    string columnName = String.Empty;
    int modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;
        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
        dividend = (int)((dividend - modulo) / 26);
    } 

    return columnName;
}

I think you basically need a transformation of a number in 10x numerical system to a number in 26x numerical system. 我认为你基本上需要将10x数值系统中的数字转换为26x数值系统中的数字。

For example: 例如:

53 = 5*10^1 + 3*10^0 = [5][3] 53 = 5 * 10 ^ 1 + 3 * 10 ^ 0 = [5] [3]

53 = B*26^1 + A*26^0 = [B][A] 53 = B * 26 ^ 1 + A * 26 ^ 0 = [B] [A]


int value10 = 53;
int base10 = 10;

string value26 = "";
int base26 = 26;

int input = value10;
while (true)
{
    int mod = input / base26;
    if (mod > 0)
        value26 += Map26SymbolByValue10 (mod); // Will map 2 to 'B'
    else
        value26 += Map26SymbolByValue10 (input); // Will map 1 to 'A'

    int rest = input - mod * base26;
    if (input < base26) break;
    input = rest;
}

I really hope this isn't homework... (untested solution): 我真的希望这不是作业......(未经测试的解决方案):

if(value == 1)
  return "A";
StringBuilder result = new StringBuilder();
value--;
while(value > 0)
{
  result.Insert(0, 'A' + (value % 26));
  value /= 26;
}

Recursive version based on tanascius' original answer (also untested): 基于tanascius原始答案(也未经测试)的递归版本:

string ConvertToChar(int value)
{
  char low = 'A' + (value - 1) % 26;
  if(value > 26)
    return ConvertToChar((value - 1) / 26 + 1) + low.ToString();
  else
    return low.ToString();
}

Tested solution: 测试解决方案:

private static string VersionName(int versionNum)
{
    StringBuilder sb = new StringBuilder();
    while (versionNum > 0)
    {
        versionNum--;
        sb.Insert(0, (char)('A' + (versionNum % 26)));
        versionNum /= 26;
    }
    return sb.ToString();
}

I wouldn't bother using recursion for this. 我不打算使用递归来解决这个问题。 Looping with a StringBuilder is more efficient than concatenating strings with each recursion, although you'd probably need a crazy number of revisions to notice the difference (4 letters is enough for over 400,000 revisions). 使用StringBuilder进行循环比使用每次递归连接字符串更有效,尽管您可能需要一些疯狂的修订来注意差异(4个字母足以进行超过400,000个修订)。

You can use the modulo operator and division to get your code. 您可以使用模运算符和除法来获取代码。
Like 55 / 26 == 2 (that is B) and 55 % 26 = 3 (that is C). 像55/26 == 2(即B)和55%26 = 3(即C)。 It works for two characters. 它适用于两个字符。 When you have an unknown count of characters, you have to start looping: 当你有一个未知的字符数时,你必须开始循环:

[look at Aaron's solution, mine was wrong] [看看Aaron的解决方案,我的错了]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM