2009-05-29 37 views
5

我想创建一个函数,当索引通过时,它会给我字母表位置。它会像excel显示它的列一样。 A ... Z,AA,AB ....我写了下面的函数来得到Z的结果。它看起来像Incrementing字母

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

任何递归函数都可以转换为等价的迭代函数。我发现它总是容易的递归首先想到:

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; 
} 

即使如此,听乔尔。

0

递归是一种可能性 - 如果index > 26,你在此调用处理index % 26,并串连到index/26递归调用。但是,迭代通常更加快速,并且不难安排诸如此类的简单情况。伪代码:

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

或类似的。

+0

这没有什么错你的伪代码的,但是要知道,你应该使用StringBuilder类,如果你将要追加到一个字符串在一个循环,以节省对象分配是很重要的:HTTP:/ /msdn.microsoft.com/en-us/library/system.text.stringbuilder(loband).aspx – 2009-05-29 02:30:06

+0

这是错误的,因为它不是基本的26系统。如果A为0,则A等于AA(0 == 00)。如果A是1,从Z到AA将会像从9到11. – 2009-05-29 02:31:28

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

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

我的C#是可怕和坚定的。将其解释为伪代码 - 它几乎肯定不会编译,但可能会让您开始。

-1

我不想在C#中回答这个问题,但我会告诉你在Haskell中这是多么容易。

alphas :: [String] 
alphas = [x ++ [c] | x <- ([]:alphas), c <- ['A'..'Z']] 

Prelude> take 100 alphas 
["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T", 
"U","V","W","X","Y","Z","AA","AB","AC","AD","AE","AF","AG","AH","AI","AJ","AK", 
"AL","AM","AN","AO","AP","AQ","AR","AS","AT","AU","AV","AW","AX","AY","AZ","BA", 
"BB","BC","BD","BE","BF","BG","BH","BI","BJ","BK","BL","BM","BN","BO","BP","BQ", 
"BR","BS","BT","BU","BV","BW","BX","BY","BZ","CA","CB","CC","CD","CE","CF","CG", 
"CH","CI","CJ","CK","CL","CM","CN","CO","CP","CQ","CR","CS","CT","CU","CV"]