用字母增加一个字符串?

时间:2015-06-06 17:55:09

标签: javascript jquery increment

我需要从..增加一个字符串...让我们说aaazzz并在控制台中写入每个增量(甚至增加一个字?)。它会是这样的:

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

有没有人拥有或知道这个智能解决方案?谢谢!

12 个答案:

答案 0 :(得分:20)

将字符串视为基数为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;

答案 1 :(得分:6)

此功能根据数字提供3个字符:

function n2s (n) {
    var s = '';
    while (s.length < 3) {
        s = String.fromCharCode(97 + n % 26) + s;
        n = Math.floor(n / 26);
    }
    return s;
}

从&#34; aaa&#34;打印字符串到&#34; zzz&#34;:

var zzz = Math.pow(26, 3) - 1;
for (var n = 0; n <= zzz; n++) {
    console.log(n2s(n));
}

&#13;
&#13;
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(' ');
&#13;
&#13;
&#13;

询问详情: - )

<强>改进

效果与accepted answerhttp://jsperf.com/10-to-26相比较。

// string to number: s2n("ba") -> 26
function s2n(s) {
    var pow, n = 0, i = 0;
    while (i++ < s.length) {
        pow = Math.pow(26, s.length - i);
        n += (s.charCodeAt(i - 1) - 97) * pow;
    }
    return n;
}

// number to string: n2s(26) -> "ba"
function n2s(n) {
    var s = '';
    if (!n) s = 'a'; 
    else while (n) {
        s = String.fromCharCode(97 + n % 26) + s;
        n = Math.floor(n / 26);
    }
    return s;
}

// pad("ba", 4) -> "aaba"
function pad (s, n) {
    while (s.length < n) s = 'a' + s;
    return s;
}

用法:

var from = s2n('azx');
var to = s2n('baa');
for (var n = from; n <= to; n++) {
    console.log(pad(n2s(n), 3));
}

输出:

azx
azy
azz
baa

<强>递归性

在内存使用或计算时间方面可能效率较低:https://jsperf.com/10-to-26/4

function n2s(n) {
    var next = Math.floor(n / 26);
    return (
        next ? n2s(next) : ''
    ) + (
        String.fromCharCode(97 + n % 26)
    );
}

function s2n(s) {
    return s.length && (
        (s.charCodeAt(0) - 97)
    ) * (
        Math.pow(26, s.length - 1)
    ) + (
        s2n(s.slice(1))
    );
}

答案 2 :(得分:3)

采用了一些算法方法。此函数将初始字符串作为参数,以字母表为单位递增下一个可能的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 + "<br>");
  while(true)
  {
    temp = generate(temp);
    if(temp == init) break;
    document.write(temp + "<br>");
  }
}

用法:loop("aaa");

CODEPEN

答案 3 :(得分:2)

我采用了一种不同的方法,使用排列函数,递归生成所有可能的排列,可以使用重复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(' ');

答案 4 :(得分:1)

我使用了您的代码并添加了一些新功能。

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”就好了。

答案 5 :(得分:1)

让我们尝试这种方法。它是一个直接循环,可以从 aaa,aab,aac,.....,xzz,yzz,zzz

生成完整的序列

&#13;
&#13;
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]<stopCode);
    printSeq(seq);
    sequences.push(seq.map(String.fromCharCode).join(''));
})();
&#13;
&#13;
&#13;

结果显示在控制台中,您还可以获得存储在sequence数组中的完整序列。希望这是可读和有用的。

答案 6 :(得分:1)

我只想提供@ procrastinator的替代答案(因为我无法对答案发表评论,因为我在Stackoverflow上没有足够的分数)。他的答案似乎是最通用的方法,但我不禁注意到,当“z”出现“ba”时,op预计它是“aa”。此外,这遵循Excel如何命名它的列。

以下是带有更正的代码:

printfLR() { if [ "$1" ] ; then echo "$@" ; else cat ; fi |
             while read l r ; do
                 printf "%-$(( ( 1 + ( ${#l} + ${#r} ) / COLUMNS ) \
                              * COLUMNS - ${#r} ))s%s"   "$l" "$r"
             done ;  }

不是从0开始,而是将1视为“a”,将26视为“z”,将27视为“aa”,依此类推。

答案 7 :(得分:0)

假设你总是有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

现在你只剩下一个像以前一样的变量,你可以做你想做的事情(即输出等)。

您也可以使用字符串数组来完成此操作,这样可以更容易地更改字母数量,并且需要更多代码来计算数组长度和内容,但我想让它工作至少静态地首先如上所述。

答案 8 :(得分:0)

以下示例可以从a...az...z

&#13;
&#13;
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;
&#13;
<div id="current"></div>
&#13;
&#13;
&#13;

答案 9 :(得分:0)

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

答案 10 :(得分:0)

这将起到将字符串递增到下一个序列

的作用
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("");
}

我正在研究另一种解决方案,可以按任意数字递增,也可以反方向递增。代码仍然有一些错误,但只是把它放在这里接收一些建议。传递负数以反向。 对于某些边缘情况,代码失败,例如:当字符是&#39; a&#39;和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("");
}

答案 11 :(得分:0)

获取A-Z,AA-ZZ,AAA-ZZZ等,直到循环数增加为止。

function createList(maxCycles) {
  if (typeof maxCycles != "number") {
    console.log("number expected");
    return;
  }

  const alphaLen = 26;
  const alpha = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];

  let list = [alpha];

  // go through all cycles
  for (let cycleNo = 1; cycleNo < maxCycles; cycleNo++) {
    list[cycleNo] = [];
    pastCollection = list[cycleNo - 1];
    pastLen = pastCollection.length;

    for (let i = 0; i < pastLen; i++) {
      for (let j = 0; j < alphaLen; j++) {
        // use past item then add a letter of the alphabet at the end
        list[cycleNo].push(pastCollection[i] + alpha[j]);
      }
    }
  }

  return list;
}

(function(maxCycles) {
  console.log(createList(maxCycles));
})(3);