动态字符发生器;从字符集

时间:2015-09-22 14:41:58

标签: string for-loop language-agnostic dynamically-generated

我想创建一个动态字符串生成器,它将从具有动态长度的字符集生成所有可能的唯一字符串。

我可以很容易地使用for循环但是它的静态而不是动态长度。

// Prints all possible strings with the length of 3

for a in allowedCharacters {
    for b in allowedCharacters {
        for c in allowedCharacters {
            println(a+b+c)
        }
    }
}

但是当我想要使这个动态变长时,我可以调用generate(length: 5)我感到困惑。

我发现了这个Stackoverflow question但是接受的答案会产生字符串1-maxLength长度,而我希望字符串上的maxLength。

3 个答案:

答案 0 :(得分:4)

如上所述,使用递归。以下是如何使用C#:

static IEnumerable<string> Generate(int length, char[] allowed_chars)
{
    if (length == 1)
    {
        foreach (char c in allowed_chars)
            yield return c.ToString();
    }
    else
    {
        var sub_strings = Generate(length - 1, allowed_chars);

        foreach (char c in allowed_chars)
        {
            foreach (string sub in sub_strings)
            {
                yield return c + sub;
            }

        }
    }
}

private static void Main(string[] args)
{

    string chars = "abc";

    List<string> result = Generate(3, chars.ToCharArray()).ToList();

}

请注意,随着长度的增加,此算法的运行时间及其返回的数据量呈指数级增长,这意味着如果您的长度较长,则应该预计代码需要很长时间并返回大量数据数据。

答案 1 :(得分:1)

将@YacoubMassad的C#代码翻译成Swift:

$(document).ready(function(){
  FB.init({
    appId  : 'IDAPP',
    status : true,
    cookie : true,
    xfbml  : true
  });

  FB.getLoginStatus(function(response) {
    if (response.status == 'connected') {
        var user_id = response.authResponse.userID;
        var page_id = "PAGE_ID";
        var fql_query = "SELECT uid FROM page_fan WHERE page_id =" + page_id + " and uid =" + user_id;
        var the_query = FB.Data.query(fql_query);

        the_query.wait(function(rows) {
          alert(rows);
            if (rows.length == 1 && rows[0].uid == user_id) {
                alert("like");

            } else {
                alert("not like");
            }
        });

    } else if (response.status === 'not_authorized') {
       alert("not authorized");

    } else {
       alert("not login");
    }
  });
});

打印:

  

aaa,aab,aac,aba,abb,abc,aca,acb,acc,baa,bab,bac,bba,bbb,bbc,bca,bcb,bcc,caa,cab,cac,cba,cbb,cbc ,cca,ccb,ccc

答案 2 :(得分:1)

虽然可以(显然已经足够)使用递归来解决这个问题,但这是一种非常低效的工作方式。

你真正在做的只是数数。在你的例子中,用“a”,“b”和“c”作为允许的字符,你在基数3中计算,因为你允许三个字符串,所以它们是三位数字。

基数M中的N位数字可以表示N M 不同的可能值,从0到N M -1。所以,对于你的情况,那是limit=pow(3, 3)-1;。要生成所有这些值,只需从0到极限计数,并使用指定的字符作为“数字”将每个数字转换为基数M.例如,在C ++中,代码可能如下所示:

#include <string>
#include <iostream>

int main() { 
    std::string letters = "abc";
    std::size_t base = letters.length();
    std::size_t digits = 3;

    int limit = pow(base, digits);

    for (int i = 0; i < limit; i++) {
        int in = i;
        for (int j = 0; j < digits; j++) {
            std::cout << letters[in%base];
            in /= base;
        }
        std::cout << "\t";
    }
}

一个小注:正如我在这里写的那样,这产生了基本上是小端格式的输出。也就是说,最快变化的“数字”在左侧,而变化最慢的“数字”在右侧。