用字母增加一个字符串?
我需要增加一个字符串..让我们说aaa
到zzz
并在控制台中写入每个增量(甚至是一个单词的增量?)。 它会是这样的:
aaa aab aac ... aaz aba abb abc ... abz aca acb
等等。 到目前为止,我通过这样做增加了一个字母:
String.prototype.replaceAt = function(index, character) { return this.substr(0, index) + character + this.substr(index+character.length); } string = "aaa"; string = string.replaceAt(2, String.fromCharCode(string.charCodeAt(2) + 1)); //string == "aab"
但是,当最后一个字母为z
时我输了,然后它应该增加字母2(索引1)并将最后一个字母重置为a
。
有没有人知道或知道这个聪明的解决方案? 谢谢!
将字符串视为基数为36的数字。
将其转换为十进制,添加1,转换回基数36,并用字母’a’替换任何零:
var str= 'aaa', s= str; while(str!=='zzz') { str= ((parseInt(str, 36)+1).toString(36)).replace(/0/g,'a'); s+= ' '+str; } document.body.innerHTML= s;
此函数根据数字提供3个字符:
function n2s (n) { var s = ''; while (s.length < 3) { s = String.fromCharCode(97 + n % 26) + s; n = Math.floor(n / 26); } return s; }
要将字符串从“aaa”打印到“zzz”:
var zzz = Math.pow(26, 3) - 1; for (var n = 0; n <= zzz; n++) { console.log(n2s(n)); }
function n2s (n) { var s = ''; while (s.length < 3) { s = String.fromCharCode(97 + n % 26) + s; n = Math.floor(n / 26); } return s; } var result = []; var zzz = Math.pow(26, 3) - 1; for (var n = 0; n <= zzz; n++) { result.push(n2s(n)); } document.body.innerHTML = result.join(' ');
采取了一些算法方法。 此函数将初始字符串作为参数,以字母表为单位递增下一个可能的char,最后返回结果。
function generate(str) { var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split(''); var chars = []; for(var i = 0; i < str.length; i++) { chars.push(alphabet.indexOf(str[i])); } for(var i = chars.length - 1; i >= 0 ; i--) { var tmp = chars[i]; if(tmp >= 0 && tmp < 25) { chars[i]++; break; } else{chars[i] = 0;} } var newstr = ''; for(var i = 0; i < chars.length; i++) { newstr += alphabet[chars[i]]; } return newstr; }
这是循环辅助函数,它接受初始字符串循环并生成所有组合。
function loop(init){ var temp = init; document.write(init + "
"); while(true) { temp = generate(temp); if(temp == init) break; document.write(temp + "
"); } }
用法: loop("aaa");
CODEPEN
我采用了不同的方法,使用排列函数,递归生成所有可能的排列,可以使用重复n次的数组中的字符生成排列。 代码看起来像这样。
//recursively generates permutations var permutations = function (li, rep) { var i, j, next, ret = []; // base cases if (rep === 1) { return li; } if (rep <= 0) { return []; } // non-base case for (i = 0; i < li.length; i += 1) { // generate the next deepest permutation and add // the possible beginnings to those next = permutations(li, rep-1); for (j = 0; j < next.length; j += 1) { ret.push(li[i] + next[j]); } } return ret; }; // returns an array of numbers from [start, end) // range(10, 14) -> [10, 11, 12, 13] var range = function (start, end) { var i, ret = []; for (i = start; i < end; i+= 1) { ret.push(i); } return ret; }; // generates letters ('abcd...') var letters = String.fromCharCode.apply(this, range('a'.charCodeAt(0), 'z'.charCodeAt(0)+1)); // calls the function itself, and .join's it into a string document.body.innerHTML = (permutations(letters, 3)).join(' ');
我们试试这种方法吧。 它是一个直接的循环,可以产生aaa,aab,aac,…..,xzz,yzz,zzz的完整序列
function printSeq(seq){ console.log(seq.map(String.fromCharCode).join('')); } var sequences = []; (function runSequence(){ var seq = 'aaa'.split('').map(function(s){return s.charCodeAt(0)}); var stopCode = 'z'.charCodeAt(0); do{ printSeq(seq); sequences.push(seq.map(String.fromCharCode).join('')); if (seq[2]!=stopCode) seq[2]++; else if (seq[1]!=stopCode) seq[1]++; else if (seq[0]!=stopCode) seq[0]++; }while (seq[0]
我使用了你的代码并添加了一些新function。
String.prototype.replaceAt = function(index, character) { return this.substr(0, index) + character + this.substr(index+character.length); } String.prototype.incrementAt = function(index) { var newChar = String.fromCharCode(this.charCodeAt(index) + 1); // Get the next letter that this char will be if (newChar == "{") { // If it overflows return this.incrementAt(index - 1).replaceAt(index, "a"); // Then, increment the next character and replace current char with 'a' } return this.replaceAt(index, newChar); // Replace this char with next letter } String.prototype.increment = function() { return this.incrementAt(this.length - 1); // Starts the recursive function from the right } console.log("aaa".increment()); // Logs "aab" console.log("aaz".increment()); // Logs "aba" console.log("aba".increment()); // Logs "abb" console.log("azz".increment()); // Logs "baa"
此incrementAt
函数是递归的,并递增当前所在的字符。 如果在进程中它溢出(字符变为{
在z
之后),则在它所在的字母之前调用incrementAt
。
这段代码的一个问题是,如果你尝试增加zzz
你会得到aaaz
。 这是因为它试图增加第-1个字符,这是最后一个字符。 如果我以后有时间,我会用修复程序更新我的答案。
请注意,如果您有一个不同的长度字符串,这个解决方案将起作用。 例如,“aaaa”将计入“zzzz”就好了。
我只是想为@ procrastinator提供一个替代答案(因为我无法对答案发表评论,因为我在Stackoverflow上没有足够的分数)。 他的回答似乎是最通用的方法,但我不禁注意到,当“z”出现“ba”时,op预期它是“aa”。 此外,这遵循Excel如何命名它的列。
这是带有更正的代码:
function s2n(s) { var pow, n = 0, i = 0; while (i++ < s.length) { pow = Math.pow(26, s.length - i); var charCode = s.charCodeAt(i - 1) - 96; n += charCode * pow; } return n; } function n2s(n) { var s = ''; var reduce = false; if (n === undefined) { n = 0; } else { n--; } while (n !== undefined) { s = String.fromCharCode(97 + n % 26) + s; n = Math.floor(n / 26); if (n === 0) { n = undefined; } else { n--; } } return s; }
这将不是从0开始,而是将1视为“a”,将26视为“z”,将27视为“aa”,依此类推。
假设你总是有3个字母(或任何其他设定数量的字母),我会想到:
每个字母都有单独的变量,因此不是:
string = "aaa";
有:
string1 = "a"; string2 = "a"; string3 = "a";
然后在每次迭代时递增所需的值。 这可能需要一些试验和错误,看起来你是从右到左,所以大致:
if(string3 != "z"){ // Increment string 3 by a letter }else if(string2 != "z"){ // Increment string 2 by a letter }else if (string1 != "z"){ // Increment string 1 by a letter }else{ // What ever you want to do if "zzz" }
我没有测试过,但它会很接近。
然后
string = string1 + string2+ string3
现在你只剩下一个像以前一样的变量你可以做你想做的事情(即输出等)
您也可以使用字符串数组来完成此操作,这样可以更容易地获得更改的字母数量,并且需要更多的代码来计算数组长度和内容,但我想让它至少静态地工作首先像上面。
Number#toString
有趣方法:
var n = 13330 var ns = [] for(var i = 0; i < 26; i++) { for(var j = 0; j < 26; j++) { for(var k = 0; k < 26; k++) { ns.push(n.toString(36)) n++ } n += 10 // jump from '(x)0' to '(x+1)a', etc. } n += 360 // jump from '(x)0a' to '(x)aa', etc. } console.log(ns) // the strings you wanted
以下示例可以从a...a
到z...z
。
String.prototype.replaceAt = function(index, character) { return this.substr(0, index) + character + this.substr(index + character.length); } String.prototype.inc = function() { var stop = 'z'; var start = 'a'; var currentIndex = this.length - 1; var string = this.replaceAt(currentIndex, String.fromCharCode(this.charCodeAt(currentIndex) + 1)); for (var i = string.length - 1; i > 0; i--) { if (string[i] == String.fromCharCode(stop.charCodeAt(0) + 1)) { string = string.replaceAt(i - 1, String.fromCharCode(string.charCodeAt(i - 1) + 1)); string = string.replaceAt(i, String.fromCharCode(start.charCodeAt(0))); } } return string; } var string = "aaa"; var allStrings = string; while(string != "zzz") { string = string.inc(); allStrings += " " + string; } document.getElementById("current").innerHTML = allStrings;
这将起到将字符串递增到下一个序列的作用
function increment(str){ var arr = str.split(""); var c; for(var i=arr.length-1; i>=0; i--){ c = (arr[i].charCodeAt(0)+1)%123; arr[i] = String.fromCharCode(c==0?97:c); if(c!=0)break; } return arr.join(""); }
我正在研究另一种解决方案,以任何数字递增,也可以反向。 代码仍然有一些错误,但只是把它放在这里接收一些建议。 传递负数以反向。 对于某些边缘情况,代码失败,例如:当字符为’a’且num为负数时
function jumpTo(str,num){ var arr = str.split(""); var c; for(var i=arr.length-1; i>=0; i--){ c = (arr[i].charCodeAt(0)+1)%123; c += c==0?97+num-1:num-1; arr[i] = String.fromCharCode(c==0?97:c); if(c!=0)break; } return arr.join(""); }