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

この質問を参照してください:
列インデックスをExcelの列名に変換します

またはこれ:
列番号(例:127)をExcel列(例:AA)に変換する方法

最初のリンクの一番上に正解があり、2番目のリンクには正しくないものがいくつかありますが。

于 2009-05-29T02:26:15.610 に答える
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 に答える
0

再帰は1つの可能性です-の場合index > 26、この呼び出しで処理しindex % 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)
{{
    const intalphabetsCount = 26;
    文字列の結果='';

    if(index> =alphabetsCount)
    {{
        結果+=GetColumnName(index-alphabetsCount)
    }
    return(string)(64 + index);
}

私のC#は恐ろしくて錆びています。これを擬似コードとして解釈します-ほぼ確実にコンパイルされませんが、開始できる場合があります。

于 2009-05-29T02:24:39.683 に答える