十进制和26进制转换算法

【问题描述】

在Excel中,列的名称是这样一个递增序列:A、B、C、…、Z、AA、AB、AC、…、AZ、BA、BB、BC、…、BZ、CA、…、ZZ、AAA、AAB…。
我们需要将上述列名序列和以下自然数序列相互转换:1、2、3、…。

 

【问题分析】

经过分析,我们不难发现,这是一个26进制和十进制相互转换的问题。序列A-Z依次对应序列1-26。进制转换的基本办法就是“取余法”,换算规则如下:
ABZ = 1*26² + 2 * 26¹ + 26*26°= 676 + 52 + 26 = 754
于是,我们就知道该如何设计一个十进制转换为26进制的算法了。

 

【算法描述】
Step1.[取余] 用指定自然数n除以26,得到一个余数m。如果m = 0,置m←26。
Step2.[转换为字符] 将m映射为字符c,映射规则是{1-26}->{A-Z}。然后将c拼接到26进制值s的左边,也就是置s←c + s。
Step3.[去余降幂] 置n←(n–m)/26。如果n > 0,则回到Step1继续执行,否则进入Step4。
Step4.[结束] 返回s。

按照上述思想,26进制转换为十进制的过程正好是相反的,而且实现起来也更为简单,在此不述。


c++代码:

#include
#include 
using namespace std;

int main(){
	long long ans=0;
	string s;
	cin>>s;
	
	int len=s.size();
	for(int i=0,j=1;i0){
		int m=ans%26;
		if(m==0) m=26;
		str+=(char)(m+64);
		ans=(ans-m)/26;
	}
	reverse(str.begin(),str.end());	//反序	
	cout<

 


C#源代码如下:

/// 
/// 将指定的自然数转换为26进制表示。映射关系:[1-26] ->[A-Z]。
/// 
/// 自然数(如果无效,则返回空字符串)。
/// 26进制表示。
public static string ToNumberSystem26(int n){
    string s = string.Empty;
    while (n > 0){
        int m = n % 26;
        if (m == 0) m = 26;
        s = (char)(m + 64) + s;
        n = (n - m) / 26;
    }
    return s;
} 

/// 
/// 将指定的26进制表示转换为自然数。映射关系:[A-Z] ->[1-26]。
/// 
/// 26进制表示(如果无效,则返回0)。
/// 自然数。
public static int FromNumberSystem26(string s){
    if (string.IsNullOrEmpty(s)) return 0; 
    int n = 0;
    for (int i = s.Length - 1, j = 1; i >= 0; i--, j *= 26){
        char c = Char.ToUpper(s[i]);
        if (c < 'A' || c > 'Z') return 0;
        n += ((int)c - 64) * j;
    }
    return n;
}

static void Main(string[] args){
    int[] numbers = { 1, 10, 26, 27, 256, 702, 703 };
    foreach (int n in numbers){
        string s = ToNumberSystem26(n);
        Console.WriteLine(n + "\t" + s + "\t" + FromNumberSystem26(s));
    }
    Console.ReadLine();
}

 

你可能感兴趣的:(算法题)