字母表示数字法的转换

问题描述

今天在工作中遇到一个问题;在使用excel的web插件的时候,需要将列数字转化为字母表示法;即

  • 数字0的字母表示法A
  • 数字1的字母表示法B
  • 数字25的字母表示法Z
  • 数字26的字母表示法AA
  • 数字27的字母表示法AB

以此类推;我想既然写了,就写一个适应任意大的数字吧!

本来想一下使用25进制,将数字转化为字母使用最小短除法,然后得到结果,但是在实践的过程中发现,如果使用0代表A,那就会面临一个问题,使用字母表示法,A是可以打头的,这样就没办法进行了。

经过了两个小时的奋战,中与找到其中的规律了;过程就不记录了,直接说分析结果;在这里记录一下,以防下次使用时忘记;这个方法可能不是最简单的方法,不喜勿喷。

解决方案

1. 将字母转化为数字

字母转化为数字,0代表A往后以此类推,转化公式:

number = 26n-1 + word1 * 26n-1 + word2 * 26n-2 + … + wordn-1 * 261 + wordn * 260

注释:
	number:表示转化后的十进制数字
	word:代表将要转化的字母表示法
	n:代表字符长度
	word下标:代表字符的第几位,从1开始

例如:我们将FUK转化为数字表示法

	F = 5
	U = 20
	K = 10
	n = 3

262 + 5 * 262 + 20 * 261 + 10 * 260 = 4586

则他代表的数字就是FUK的十进制数字4586



2. 将字数字化为母转表示法

字母转数组稍微有点复杂,首先我们得取到对应字母表示法的长度;然后用最小短处法除以26,取得结果。

我们可以使用上面的那个方法,判断出数字所对应的字母表示法的位数;这里我们使用n表示:

pow = pow - 26n-1
字母表示数字法的转换_第1张图片
word = char(h) + … + char© + char(b) + char(a)

如果最终结果word和第一步计算的长度相等,则word就是结果;如果比计算长度小1,则word需要在第一位补充一个A

这里就不举例子了,补上一段js的实现代码:

numberToLet = (pow) => {
	// 如果待计算数字小于26,直接计算即可
    if(pow < 26) {
        return String.fromCharCode(pow + 65);
    }
    // 计算目标字符串的长度
    let size = 1;
    while(true) {
        let sum = Math.pow(26, size);
        for(let i = size;i >= 0;i--) {
            sum += 25 * Math.pow(26, i);
        }
        if(pow <= sum) {
            break;
        }
        size++;
    }
    // 首先去掉影响值
    pow = pow - Math.pow(26, size);
    // 最小短除法的实现
    let arr = []
    while(true) {
        arr.push(pow % 26);
        pow = Math.floor(pow / 26);
        if(pow === 0) {
            break;
        }
    }
    // 结果拼接
    let rtbStr = '';
    for(let item of arr) {
        rtbStr = String.fromCharCode(item + 65) + rtbStr;
    }
    // 检测长度是否达标
    if(rtbStr.length === size) {
        rtbStr = 'A' + rtbStr;
    }
    return rtbStr;
}

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