5

我正在尝试创建一个函数,该函数将在传递索引时为我提供字母位置。它将与 excel 如何显示它的列相同。A...Z, AA,AB.... 我写了下面的函数来得到 Z 的结果。它看起来像

static string GetColumnName(int index)
{
    const int alphabetsCount = 26;
    if (index <= alphabetsCount)
    {
        int code = (index - 1) + (int)'A';
        return char.ConvertFromUtf32(code);
    }
    return string.Empty;
}

这工作正常,直到'Z'。如果我通过 1 则返回“A”,如果通过 2 则返回“B”,依此类推。但是,当我将 27 传递给这个函数时,我无法弄清楚我将如何获得 AA。我想我需要一种递归方法来找到它。

对这个问题的任何投入都会很棒!

编辑

这是 Tordek 建议的。但是他的代码会在 52、78 等数字上失败。为此添加了解决方法,这是最终的工作代码。

static string GetColumnName(int index)
{
    const int alphabetsCount = 26;

    if (index > alphabetsCount)
    {
        int mod = index % alphabetsCount;
        int columnIndex = index / alphabetsCount;

        // if mod is 0 (clearly divisible) we reached end of one combination. Something like AZ
        if (mod == 0)
        {
            // reducing column index as index / alphabetsCount will give the next value and we will miss one column.
            columnIndex -= 1;
            // passing 0 to the function will return character '@' which is invalid
            // mod should be the alphabets count. So it takes the last char in the alphabet.
            mod = alphabetsCount;
        }
        return GetColumnName(columnIndex) + GetColumnName(mod);
    }
    else
    {
        int code = (index - 1) + (int)'A';
        return char.ConvertFromUtf32(code);
    }
}
4

4 回答 4

4

任何递归函数都可以转换为等效的迭代函数。我发现首先递归思考总是很容易:

static string GetColumnName(int index)
{
    const int alphabetsCount = 26;

    if (index > alphabetsCount) {
        return GetColumnName(index / alphabetsCount) + GetColumnName(index % alphabetsCount);
    } else {
        int code = (index - 1) + (int)'A';
        return char.ConvertFromUtf32(code);
    }
}

可以简单地转换为:

static string GetColumnName(int index)
{
    const int alphabetsCount = 26;
    string result = string.Empty;

    while (index > 0) {
        result = char.ConvertFromUtf32(64 + (index % alphabetsCount)) + result;
        index /= alphabetsCount;
    }

    return result;
}

即便如此,听乔尔的话。

于 2009-05-29T02:33:24.970 回答
4

请参阅此问题:
将列索引转换为 Excel 列名

或者这个:
如何将列号(例如 127)转换为 excel 列(例如 AA)

虽然第一个链接在顶部有一个正确的答案,而第二个链接有几个不正确的答案。

于 2009-05-29T02:26:15.610 回答
0

递归是一种可能性——如果index > 26index % 26在此调用中处理并将其连接到递归调用上index / 26。然而,迭代通常更快,并且不难安排像这样的简单情况。在伪代码中:

string result = <convert `index % 26`>
while index > 26:
  index = index / 26
  result = <convert `index % 26`> + result
return result

之类的。

于 2009-05-29T02:20:48.723 回答
0
静态字符串 GetColumnName(int index)
{
    常量 int 字母计数 = 26;
    字符串结果 = '';

    如果(索引 >= 字母计数)
    {
        结果 += GetColumnName(index-alphabetsCount)
    }
    返回(字符串)(64 + 索引);
}

我的 C# 很糟糕而且很生锈。将此解释为伪代码 - 它几乎肯定不会编译,但可能会让您入门。

于 2009-05-29T02:24:39.683 回答