如何创build一个函数,将一个数字转换为一个双hex数字?
也许我在math方面还不够好,但是在将数字转换为纯字母forms的单体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(); 做{ A =(A-(一%LEN))/ LEN; CNT ++; }而(一个!= 0) A = B; var vnt = 0; 做{ B + = Math.pow((LEN),VNT)* Math.floor(A / Math.pow((LEN),VNT + 1)); VNT ++; }而(VNT!= CNT) var c = b; 做{ y.unshift(c%len); C =(C-(C%LEN))/ LEN; }而(C!= 0) for(var i in y)x + = let [y [i]]; return x; }
我的努力可以得到的最佳输出是: abcd ... yz ba bb bc
– 虽然不是上面的实际代码。 预期的输出是假设是abc ... yz aa ab ac ... zz aaa aab aac ... zzzzz aaaaaa aaaaab
,你得到的图片。
基本上,我的问题更多的是做“math”而不是function。 最终我的问题是:如何在Hexavigesimal转换中的math,直到一个[假设]的无穷大,就像Microsoft Excel。
如果可能的话,一个源代码,提前谢谢。
好的,这是我的尝试,假设你想要序列以“a”(代表0)开始,并且要:
a, b, c, ..., y, z, aa, ab, ac, ..., zy, zz, aaa, aab, ...
这工作,希望有一定道理。 时髦的线是在那里,因为它在math上更有意义的0代表空string,然后“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; }
但是,如果您打算按顺序打印出来,则有更有效的方法。 例如,使用recursion和/或前缀和东西。
虽然@ user826788已经发布了一个工作代码(甚至更快),但我会发布我自己的工作,我在find这里的post之前(因为我不知道单词“hexavigesimal”)。 但是它也包含了相反的function。 请注意,我使用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"
我不明白如何从一个公式中解决这个问题,但是我用了一段时间,并且想出了下面的algorithm来从字面上计算出所需的列数:
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是最不重要的“数字”)。
当我开始上述时,如果再次请求相同的值,caching每个值似乎是一个好主意,以节省时间,但实际上(使用Chrome),只需要大约3秒钟来计算第1,000,000个值( bdwgn
)约20秒计算第10,000,000个值( uvxxk
)。 随着caching的删除,花了大约14秒的第10,000,000的价值。
刚刚在今天早些时候完成了这个代码 ,我发现这个问题,而寻求什么来命名该死的东西。 在这里(如果有人想使用它):
/** * 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("") }
a
代表0
, z
代表25
。 所以z
之后的数字是26
,即1*26 + 0
,所以ba
是正确的。 ( zzzzz
之后的zzzzz
是baaaaa
。)