置换字符串直到匹配某些输入?

时间:2015-11-24 07:21:34

标签: javascript algorithm permutation

我在网上看了很多,没有太多结果,因为用几句话来形容很难。

基本上,我需要一个函数,比如sleep(1); ,它接受​​参数puntil。基本上,函数置换直到字符串等于参数。

例如,如果你运行string,它应该在函数内部执行:

一 b C d Ë F G H 一世 Ĵ ķ 升 米 ñ Ø p q [R 小号 Ť ü v w ^ X ÿ ž AA ab !! MATCH

另一个例子,对于puntil('ab'),它会做

一 b C d Ë F G H 一世 Ĵ ķ 升 米 ñ Ø p q [R 小号 Ť ü v w ^ X ÿ ž AA AB AC 广告 AE AF 股份公司 啊 嗳 AJ AK 人 上午 一个 AO 美联社 水性 AR 如 在 AU AV AW 斧头 AY AZ

...等等.. 直到匹配abcd。

基本上是一个无限的排列,直到它匹配。

有什么想法吗?

5 个答案:

答案 0 :(得分:2)

OP提出的问题有点含糊不清,所以我会发布OP所要求的两件事(我怀疑)OP。

首先,问题可能是,输入字符串在字母表的无限排列中的位置是什么(我认为这是更合法的问题,我之后给出了原因)。这可以通过以下方式完成:

举个例子(输入= dhca)。因此,所有长度为1到3个字符的字符串都将出现在此字符串之前。因此,请在答案中添加:26^1 + 26^2 + 26^3。然后,第一个字符是d,这意味着,在字典之后,如果第一个字符是a | b | c,那么过去的所有字符都是有效的。因此,请在答案中添加3 * 26^3。现在,假设第一个字符是d。然后,我们可以拥有a to g (7)中的所有字符,最后2个字符可以是任何字符。因此,请在答案中添加7 * 26^2。继续这样,我们得到答案:

26^1 + 26^2 + 26^3 + (3 * 26^3) + (7 * 26^2) + (2 * 26^1) + (0) + 1
= 75791

行。现在第二件事,我认为OP实际上是在询问(在我们得到匹配之前打印所有字符串)。现在,为什么我认为这是不可行的,因为如果我们输入zzzzz(长5个字符),我们需要打印26^1 + 26^2 + 26^3 + 26^4 + 26^5字符串,即12356630。因此,对于这部分,我假设输入字符串的最大长度是5(并且绝对不再),因为对于6个字符长度的字符串,我们需要打印~321272406字符串 - >不可能。

因此,一个简单的解决方案可以是:

  • 创建一个大小为27的数组:arr [] = {'','a','b',...,'y','z'}。第一个字符为空。
  • 从0到26(包括)写入5(最大字符串长度)嵌套循环,并将其添加到虚拟字符串并打印它。像。的东西。

    for i from 0 to 26
        String a = "" + arr[i]
        for j from 0 to 26
            String b = a + arr[j]
            for k from 0 to 26
                String c = b + arr[k]
                for l from 0 to 26
                    String d = c + arr[l]
                    for m from 0 to 26
                        String e = d + arr[m]
                        print e
                        if(e equals input string)
                            break from all loops //use some flag, goto statement etc.
    

答案 1 :(得分:2)

Fiddle here

function next(charArray, rightBound){

    if(!rightBound){
        rightBound = charArray.length;
    }

    var oldValue = charArray[rightBound-1];
    var newValue = nextCharacter(charArray[rightBound-1]);
    charArray[rightBound-1] = newValue;

    if(newValue < oldValue){
        if(rightBound > 1){
            next(charArray, rightBound-1);
        }
        else{
            charArray.push('a');
        }
    }
    return charArray;
}

function nextCharacter(char){
    if(char === 'z'){
        return 'a'
    }
    else{
        return String.fromCharCode(char.charCodeAt(0) + 1)
    }
}

function permuteUntil(word){
    var charArray = ['a'];
    var wordChain = ['a'];

    while(next(charArray).join('') !== word){
        wordChain.push(charArray.join(''));
    }

    wordChain.push(word);

    return wordChain.join(', ');
}


alert(permuteUntil('ab'));

答案 2 :(得分:2)

以下是fiddle

 var alphabet = ['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'];

 var output = "";
 var match = "cccc";  //<----------- match here

//This is your main function 
function permutate() {

    var d = 0;   // d for depth

    while (true) {

       //Your main alphabet iteration             
       for (var i=0; i<alphabet.length; i++){

          //First level 
          if (d === 0) {
             console.log(alphabet[i])
             output = alphabet[i];
          }    
          else
             iterator(alphabet[i], d);   //Call iterator for d > 0

          if (output === match)
             return;
          }


          d++;  //Increase the depth
       }
 }


 //This function runs n depths of iterations
 function iterator(s, depth){

    if (depth === 0)
       return;

    for (var i=0; i<alphabet.length; i++){

       if (depth > 1)
          iterator(s + alphabet[i], depth - 1)
       else {
          console.log(s + alphabet[i]);
          output = s + alphabet[i];
       } 

       if (output === match)
          return;
    }

 };                

说明:

您的程序需要遍历这样的字母树

[a] 
    -[a]
        -[a] 
             -[a]...
             -[b]...

         [b] ...
    -[b] -
         -[a]...
         -[b]...

[b] - ...
[c] - ...

如果不是首先需要完成每个深度的要求,这可以通过传统的递归函数轻松完成。

所以我们需要一个特殊的iterator(s, depth)函数,它可以执行多个请求的嵌套迭代(深度)。

因此main函数可以调用深度增加的迭代器(d ++)。

那就是!!

警告:这只是原型。这可以被优化和改进。它使用全局变量来简化演示。你真正的程序应该避免全局变量。如果您的匹配字太长,我建议您在iterator()内拨打setTimeoutn深度只能受您资源的限制。

答案 3 :(得分:-1)

你要求一个更优雅的解决方案,这是一个简单的函数,它将整数转换为小写的字符串,使你可以轻松地遍历字符串。

function toWord(val, first, out) {
if(first == 1)
    out = String.fromCharCode(97 + val % 26) + out;
else
    out = String.fromCharCode(97 + (val-1) % 26) + out;
if(val % 26 == 0 && first == 0) {
    val -= 26;
}
else {
    val -= val %26;
}
val = val / 26;
if(val != 0)
    return toWord(val, 0, out);
else
    return out;
}

这绝不是完美的,但它简短而简单。当调用函数set val为要转换的整数时,首先调用1,然后调出为“”。

例如,以下内容将yourFunction应用于前10,000个小写字符串

for(int i=0; i<10000; i++) {
    youFunction(toWord(i, 1, ""));
}

答案 4 :(得分:-1)

所以你需要始终从Student开始递增?由于它们是char值,因此您可以使用以下构造轻松完成此操作:

请注意,这是一个java解决方案:)

GroupID