javascript 用字母增加字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30685916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Increment a string with letters?
提问by MortenMoulder
I need to increment a string from.. let's say aaa
to zzz
and write every incrementation in the console (is incrementation even a word?). It would go something like this:
我需要增加一个字符串..假设aaa
到zzz
并在控制台中编写的每增量(增量是连一句话?)。它会是这样的:
aaa
aab
aac
...
aaz
aba
abb
abc
...
abz
aca
acb
And so on. So far I have incremented a single letter by doing this:
等等。到目前为止,我通过这样做增加了一个字母:
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"
However, I am lost when it comes to the final letter being z
and it should then increment letter 2 (index 1) and reset the last letter to be a
.
但是,当涉及到最后一个字母 is 时,我迷路了,z
然后它应该增加字母 2(索引 1)并将最后一个字母重置为a
.
Does anyone have or know a smart solution to this? Thanks!
有没有人有或知道一个聪明的解决方案?谢谢!
回答by Rick Hitchcock
Treat the string like it's a base 36 number.
将字符串视为基数为 36 的数字。
Convert it to decimal, add 1, convert back to base 36, and replace any zeroes with the letter 'a':
将其转换为十进制,加 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;
回答by leaf
This function gives 3 characters based on a number:
此函数根据数字给出 3 个字符:
function n2s (n) {
var s = '';
while (s.length < 3) {
s = String.fromCharCode(97 + n % 26) + s;
n = Math.floor(n / 26);
}
return s;
}
To print strings from "aaa" to "zzz":
将字符串从“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(' ');
Ask for details :-)
询问详情:-)
Improvements
改进
Performances compared to the accepted answer: http://jsperf.com/10-to-26.
与接受的答案相比的表现:http: //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;
}
Usage:
用法:
var from = s2n('azx');
var to = s2n('baa');
for (var n = from; n <= to; n++) {
console.log(pad(n2s(n), 3));
}
Output:
输出:
azx
azy
azz
baa
Recursivity
递归性
Probably less efficient in terms of memory use or computation time: https://jsperf.com/10-to-26/4.
在内存使用或计算时间方面可能效率较低: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))
);
}
回答by fsacer
Took a bit of algorithmic approach. This function takes initial string as an argument, increments next possible char in alphabet and at last returns the result.
采取了一些算法方法。该函数将初始字符串作为参数,递增字母表中下一个可能的字符,最后返回结果。
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;
}
Here is the loop helper function which accepts the initial string to loop through and generate all combinations.
这是循环辅助函数,它接受初始字符串以循环并生成所有组合。
function loop(init){
var temp = init;
document.write(init + "<br>");
while(true)
{
temp = generate(temp);
if(temp == init) break;
document.write(temp + "<br>");
}
}
Usage: loop("aaa");
用法: loop("aaa");
回答by umop aplsdn
I took a different approach with this, using a permutations function which recursively generated all the possible permutations one could generate using characters from an array repeated n times. The code looks like this.
我对此采取了不同的方法,使用排列函数递归生成所有可能的排列,可以使用重复 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(' ');
回答by generalspoonful
I just want to provide an alternative answer to @procrastinator's (since I can't comment on the answer because I don't have enough points on Stackoverflow). His answer seems like the most generic approach but I can't help and notice that after "z" comes "ba" when op expect it to be "aa". Also, this follows how Excel name it's columns.
我只想为@procrastinator 提供一个替代答案(因为我无法对答案发表评论,因为我在 Stackoverflow 上没有足够的分数)。他的回答似乎是最通用的方法,但我不禁注意到,在“z”之后出现“ba”时,op 期望它是“aa”。此外,这遵循 Excel 如何命名它的列。
Here is the code with corrections:
这是带有更正的代码:
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;
}
Instead of starting from 0, this will consider 1 to be "a", 26 to be "z", 27 to be "aa" and so on.
这不是从 0 开始,而是将 1 视为“a”,将 26 视为“z”,将 27 视为“aa”等等。
回答by Will
I used your code and added a few new functions.
我使用了您的代码并添加了一些新功能。
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"
This incrementAt
function is recursive and increments the character it is currently on. If in the process it overflows (the character becomes {
which is after z
) it calls incrementAt
on the letter before the one it is on.
此incrementAt
函数是递归的,并递增它当前所在的字符。如果在这个过程中它溢出(字符变成了{
之后的z
),它会调用它所incrementAt
在的字母之前的字母。
The one problem with this code is if you try to increment zzz
you get aaaz
. This is because it is trying to increment the -1th character which is the last one. If I get time later I'll update my answer with a fix.
此代码的一个问题是,如果您尝试递增,zzz
则会得到aaaz
. 这是因为它试图增加最后一个的第 -1 个字符。如果我以后有时间,我会用修复来更新我的答案。
Note that this solution will work if you have a different length string to start off. For example, "aaaa" will count up to "zzzz" just fine.
请注意,如果您要开始使用不同长度的字符串,则此解决方案将起作用。例如,“aaaa”将算到“zzzz”就好了。
回答by TaoPR
Let's try this approach. It's a straight loop which produces the complete sequence from aaa,aab,aac,.....,xzz,yzz,zzz
让我们试试这个方法。这是一个直接循环,从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]<stopCode);
printSeq(seq);
sequences.push(seq.map(String.fromCharCode).join(''));
})();
The results are displayed in the console and also you'll get a complete sequence stored in sequence
array. Hope this is readable and helpful.
结果显示在控制台中,您还将获得存储在sequence
数组中的完整序列。希望这是可读的和有帮助的。
回答by Darryl Hymanman
Assuming you will always have 3 letters (or any other set number of letters), off the top of my head I would think to:
假设你总是有 3 个字母(或任何其他固定数量的字母),我会想:
Have separate variables for each letter, so instead of:
每个字母都有单独的变量,而不是:
string = "aaa";
Have:
有:
string1 = "a";
string2 = "a";
string3 = "a";
Then increment the one you need at each iteration. This will take a little trial and error probably, and looks like you're going from the right over to the left, so roughly:
然后在每次迭代中增加您需要的那个。这可能需要一些反复试验,看起来你是从右到左,所以粗略地:
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"
}
I didn't test that but it would be something close.
我没有测试,但它会很接近。
Then
然后
string = string1 + string2+ string3
Now you are left with a single variable like before which you can do what you intended with (i.e. output etc.)
现在你只剩下一个像以前一样的变量,你可以用它来做你想要的(即输出等)
You could also do this with a string array, which would make it easier to have a changing amount of letters, and would need a little more code to count the array length and stuff, but I'd want to get it working at least statically first like above.
您也可以使用字符串数组来执行此操作,这将使更改字母数量变得更容易,并且需要更多代码来计算数组长度和内容,但我想让它至少静态地工作首先像上面一样。
回答by adricadar
The example below can work from a...a
to z...z
.
下面的示例可以从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;
<div id="current"></div>
回答by Himanshu Tanwar
This will function will do the part of incrementing the string to next sequence
这个函数将执行将字符串增加到下一个序列的部分
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("");
}
I was working on another solution to increment by any number and also in reverse direction. The code still has some bugs, but just putting it up here to receive some suggestions. pass in negative numbers to go in reverse direction. Code fails for some edge cases, for eg: when character is 'a' and num is negative number
我正在研究另一种以任意数字递增的解决方案,也以相反的方向递增。代码还有一些bug,只是把它放在这里接受一些建议。传入负数以反向。代码在某些边缘情况下失败,例如:当字符为 '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("");
}