也许我在数学方面还不够好,但我在将数字转换为纯字母Bijective Hexavigesimal时遇到问题,就像Microsoft Excel / OpenOffice Calc一样。
这是我的代码的一个版本,但没有给我所需的输出:
var toHexvg = function(a){ var x=''; var let="_abcdefghijklmnopqrstuvwxyz"; var len=let.length; var b=a; var cnt=0; var y = Array(); do{ a=(a-(a%len))/len; cnt++; }while(a!=0) a=b; var vnt=0; do{ b+=Math.pow((len),vnt)*Math.floor(a/Math.pow((len),vnt+1)); vnt++; }while(vnt!=cnt) var c=b; do{ y.unshift( c%len ); c=(c-(c%len))/len; }while(c!=0) for(var i in y)x+=let[y[i]]; return x; }
我努力的最佳结果是:a b c d ... y z ba bb bc
- 虽然不是上面的实际代码。预期输出为a b c ... y z aa ab ac ... zz aaa aab aac ... zzzzz aaaaaa aaaaab
,您可以得到图片。
基本上,我的问题更多的是做''数学'而不是功能。最后我的问题是:如何在Hexavigesimal转换中进行数学运算,直到[假设]无穷大,就像Microsoft Excel一样。
如果可能,请提供源代码,提前谢谢。
答案 0 :(得分:13)
好的,这是我的尝试,假设您希望序列以“a”开头(代表0)并且继续:
a, b, c, ..., y, z, aa, ab, ac, ..., zy, zz, aaa, aab, ...
这很有效,希望有道理。那个时髦的线是因为它在数学上更有意义,0表示空字符串,然后“a”表示1,等等。
alpha = "abcdefghijklmnopqrstuvwxyz";
function hex(a) {
// First figure out how many digits there are.
a += 1; // This line is funky
c = 0;
var x = 1;
while (a >= x) {
c++;
a -= x;
x *= 26;
}
// Now you can do normal base conversion.
var s = "";
for (var i = 0; i < c; i++) {
s = alpha.charAt(a % 26) + s;
a = Math.floor(a/26);
}
return s;
}
但是,如果您打算按顺序打印出来,那么有更有效的方法。例如,使用递归和/或前缀和东西。
答案 1 :(得分:3)
虽然@ user826788已经发布了一个工作代码(甚至快了三分之一),但我会发布自己的工作,这是我在找到帖子之前做的(因为我不知道单词“hexavigesimal”)。然而,它还包括反过来的功能。请注意,我使用a = 1,因为我用它来转换
中的起始列表元素aa) first
ab) second
到
<ol type="a" start="27">
<li>first</li>
<li>second</li>
</ol>
function linum2int(input) {
input = input.replace(/[^A-Za-z]/, '');
output = 0;
for (i = 0; i < input.length; i++) {
output = output * 26 + parseInt(input.substr(i, 1), 26 + 10) - 9;
}
console.log('linum', output);
return output;
}
function int2linum(input) {
var zeros = 0;
var next = input;
var generation = 0;
while (next >= 27) {
next = (next - 1) / 26 - (next - 1) % 26 / 26;
zeros += next * Math.pow(27, generation);
generation++;
}
output = (input + zeros).toString(27).replace(/./g, function ($0) {
return '_abcdefghijklmnopqrstuvwxyz'.charAt(parseInt($0, 27));
});
return output;
}
linum2int("aa"); // 27
int2linum(27); // "aa"
答案 2 :(得分:0)
我不明白如何从公式中解决这个问题,但我愚弄了一段时间,并提出了以下算法来计算所需的列号:
var getAlpha = (function() {
var alphas = [null, "a"],
highest = [1];
return function(decNum) {
if (alphas[decNum])
return alphas[decNum];
var d,
next,
carry,
i = alphas.length;
for(; i <= decNum; i++) {
next = "";
carry = true;
for(d = 0; d < highest.length; d++){
if (carry) {
if (highest[d] === 26) {
highest[d] = 1;
} else {
highest[d]++;
carry = false;
}
}
next = String.fromCharCode(
highest[d] + 96)
+ next;
}
if (carry) {
highest.push(1);
next = "a" + next;
}
alphas[i] = next;
}
return alphas[decNum];
};
})();
alert(getAlpha(27)); // "aa"
alert(getAlpha(100000)); // "eqxd"
演示:http://jsfiddle.net/6SE2f/1/
highest
数组保存当前最高的数字,每个“数字”包含一个数组元素(元素0是最不重要的“数字”)。
当我开始上述操作时,最好在计算后缓存每个值,以便在再次请求相同值时节省时间,但在实践中(使用Chrome),只需要大约3秒钟来计算第1,000,000个值(bdwgn
)和大约20秒计算10,000,000的值(uvxxk
)。删除缓存后,花费大约14秒到10,000,000的值。
答案 3 :(得分:0)
今晚早些时候刚刚完成了this code的写作,我在寻找这个该死的东西的过程中找到了这个问题。这是(如果有人觉得使用它):
/**
* Convert an integer to bijective hexavigesimal notation (alphabetic base-26).
*
* @param {Number} int - A positive integer above zero
* @return {String} The number's value expressed in uppercased bijective base-26
*/
function bijectiveBase26(int){
const sequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const length = sequence.length;
if(int <= 0) return int;
if(int <= length) return sequence[int - 1];
let index = (int % length) || length;
let result = [sequence[index - 1]];
while((int = Math.floor((int - 1) / length)) > 0){
index = (int % length) || length;
result.push(sequence[index - 1]);
}
return result.reverse().join("")
}
答案 4 :(得分:0)
您可以通过递归来完成此操作,如下所示:
const toBijective = n => (n > 26 ? toBijective(Math.floor((n - 1) / 26)) : "") + ((n % 26 || 26) + 9).toString(36);
// Parsing is not recursive
const parseBijective = str => str.split("").reverse().reduce((acc, x, i) => acc + ((parseInt(x, 36) - 9) * (26 ** i)), 0);
toBijective(1) // "a"
toBijective(27) // "aa"
toBijective(703) // "aaa"
toBijective(18279) // "aaaa"
toBijective(127341046141) // "overflow"
parseBijective("Overflow") // 127341046141
答案 5 :(得分:-3)
a
代表0
,z
代表25
。因此,z
之后的数字为26
,即1*26 + 0
,因此ba
是正确的。 (而zzzzz
之后的数字是baaaaa
。)