package com.it.stephen.utils;
public class Sn26Util {
/**
* 0-9 a-p 26 位, 可以理解为 26 进制
*/
private static Sn26Util instance;
public static Sn26Util getInstance() {
if (instance == null) {
instance = new Sn26Util();
}
return instance;
}
private char[] MySerials;
private Sn26Util() {
MySerials = new char[]{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'
};
}
/**
* 获取当前 26 进制 数的索引
* 即 一个字符时: 26 进制的 十进制表示
*
* @param c
* @return
*/
private int GetMySnIndex(String c) {
int index = 0;
for (int i = 0; i < MySerials.length; i++) {
String s = String.valueOf(MySerials[i]);
if (c.equalsIgnoreCase(s)) {
index = i;
break;
}
}
return index;
}
/**
* 目的: 获取 26 进制的下一位 Sn
* 步骤:
* 1. 获取26进制数,转成10进制,
* 2.10进制数+1
* 3.再转成26进制
* 因为26不可直接计算
*
* @param start
* @return
*/
public String next(String start) {
int i = Sn2Int(start);
return Int2Sn(i + 1);
}
/**
* Sn to Int
* 26 进制数转成 10 进制
*
* @param start
* @return
*/
public int Sn2Int(String start) {
int result = 0;
//将字符串拆成 char 数组
char[] chars = start.toCharArray();
//循环数组,对每一个字符运算转成26进制, 然后相加得到10进制数
for (int i = 0; i < chars.length; i++) {
/**
* 1.个位直接取26的索引,即26进制的数字
* 十位取26进制的数字后要 乘以26 (类似10位的数字"1"表示10,"2"表示 20,即 数字*10的一次方)
* 百位取26进制的数字后要乘以26 的二次方(类似百位的数字"1"表示100,"2"表示200,即数字*10的二次方)
* 所以: 26进制的数字为 n*26* 的(n的位数-1 次方)
*/
/**
* 获取位数(十位,百位,千位): 正向循环 第一位实际是数字的最高位
* 减1 : 取 位数-1 次方
*/
int pow = chars.length - i - 1;
/**
* 索引即 26进制单字符转10进制后的数值
*/
int index = GetMySnIndex(String.valueOf(chars[i]));
/**
*数字 n * 26的(位数减1次方)
* 相加 得到所有位数的10进制数字
*/
result += index * Math.pow(26, Double.valueOf(pow));
}
return result;
}
/**
* 通过取模获取 26 进制的余数 index
* 反向加到加入字符串中
*
* @param n
* @return
*/
public String Int2Sn(int n) {
String s = "";
if (n == 0) {
s = "0";
}
//商==0 代表循环完毕
// 小余26的数字 除以26 等于0
while (n != 0) {
//对26取余
int i = n % 26;
//获取26进制数值
char c = MySerials[i];
//反向加入字符串中
s = c + s;
//求商
n = n / 26;
}
//返回结果
return s;
}
}
来源:CSDN
作者:Stephen_java
链接:https://blog.csdn.net/u012477144/article/details/103648960