字母表的每个排列最多29个字符?

时间:2011-01-05 23:01:38

标签: java php c++ processing permutation

我正在尝试编写一个程序,该程序将生成一个文本文件,其中包含从一个字符到二十九个字符的字母表的每个可能的排列。我选择了29作为最长的英语单词,每个人都知道是反歧视的英语单词,长度为28个字符。有更长的,但它们主要是技术性和模糊性。

我意识到这会产生大量的字符串。但是我不知道从哪里开始,甚至不知道如何计算出这将产生多少组合。

请回答有关PHP,Processing,C ++或Java的解决方案(我只熟悉那些,PHP是首选,但可能不是我想象的最好的)。

即使只是伪代码/想法也会受到赞赏。

此外,在有人说出来之前,这不是为了暴力强迫或类似的东西。我是一名艺术家,虽然有点不为人知,但我的概念模糊不清。

13 个答案:

答案 0 :(得分:4)

“置换”一词通常意味着每个字母只出现一次,因此不可能生成超过26个字母的任何排列。无论如何,由于生成的字符串数量太大,您可以使用随机字符串(以下是C代码):

char s[30];
int p;
for (;;) // repeat forever: you cannot use a realistic iteration limit anyway
{
    for (p = 0; p < 29; ++p)
        s[p] = 'a' + rand() % 26;
    s[29] = '\0';
    puts(s);
}

答案 1 :(得分:3)

void out_perms(std::string word) {
    std::vector<int> indexes(word.size());
    for (size_t i = 0; i < indexes.size(); ++i)
        indexes[i] = i;
    do {
        for (size_t i = 0; i < indexes.size(); ++i)
            std::cout << word[indexes[i]];
        std::cout << std::endl;
    } while (std::next_permutation(indexes.begin(), indexes.end()));
}

int main(int, char**) {
    out_perms("asdfg");
}

请参阅http://codepad.org/6lQTPQrG输出示例

答案 2 :(得分:3)

显然,外部for循环用于单词中的字符数。然后,您只需创建具有该长度的字符串。对于长度为5,您从“AAAAA”开始,然后是“AAAAB”,“AAAAC”。

一旦你点击“Z”,你就回去向左移动角色,即“AAAAZ”变为“AAABA”,“AAAZZ”变为“AABAA”。一旦你点击“ZZZZZ”,你就完成了内循环,外循环将以“AAAAAA”开始。

答案 3 :(得分:3)

这是一个简单的未经测试的C ++程序,通过在Base 26中计算来创建单词:

#include <string>
#include <iostream>

int main(void)
{
    //----------------------------------------------------------
    //  Print permuations of strings of letters up to length 5.
    //  Use base 26 arithmetic.
    //----------------------------------------------------------
    const unsigned int MAX_ITERATIONS = 26 * 26 * 26 * 26 * 26;

    std::string word = "A";
    for (unsigned int i = 0; i < MAX_ITERATIONS; ++i)
    {
        //------------------------------------------------------
        //  Print the word
        //------------------------------------------------------
        std::cout << word << std::endl;

        //------------------------------------------------------
        //  Increment the word, using base 26 arithmetic.
        //  A, B, C, ..., Z.
        //  AA, BA, CA, ..., ZA, AB, BB, CB, DB, ..., ZZ.
        //  AAA, BAA, CAA, ..., ZAA, ABA, BBA, CBA, DBA, ..., ZZZ.
        //------------------------------------------------------
        bool            carry_generated = false;
        unsigned int    digit = 0;
        do
        {
            carry_generated = false;
            if (word[digit] < 'Z')
            {
                ++word[digit];
                break;
            }
            word[digit++] = 'A';
            if (word.length() == digit)
            {
                word += "A";
                break;
            }
            carry_generated = true;
        } while (carry_generated && (digit < 5));
    }

    return 0;
}

通过在打印前检查单词列表(a.k.a.字典),可以减少打印的单词数。如果单词在单词列表中,则将其打印出来。

字长为29的最大问题是表示数量。数量溢出标准C ++无符号整数的范围。需要使用 Big Int 库。 下一个问题是处理每个组合所需的时间。每次迭代将数量乘以1微秒(一种更糟糕的情况)并减少到天,小时,分钟和秒。也许可能需要几年时间。

答案 4 :(得分:2)

使用PHP的Perl样式字符递增。

set_time_limit(0);

$perm = 'A';
$endTest = str_repeat('Z',28).'A';
while ($perm != $endTest) {
    echo $perm++,"\n";
}

从命令行运行脚本,这样就不会遇到Web服务器超时;然后坐下来等待几年才能完成

答案 5 :(得分:2)

function p($length, $partial)
{
      if ($length == 0) return $partial;
      $ans = array();
      foreach (range('a', 'z') as $i)
      {
          $ans[] = p($length -1, $partial . $i);
      }
      return $ans;  
}

$top = 3;
//$f = fopen('out.txt');
for ($l = 1; $l < $top+1; $l++)
{
     print_r(p($l), '');
     //fwrite($p($l), '');
}

如果你想将$top设置为29并试一试,请继续。我不打算。

编辑 - print_r(p($l), ''); ---&gt; print_r(p($l, ''));

PHP一直以来对错误的容忍度让我印象深刻。缺少p的“必需”参数?没问题,它只是以某种方式为空字符串(或零,或假,情况依赖)。 print_r的第二个参数?无差异,无论如何都被视为默认的false

编辑

我不知道我到底在做什么。 p的不同返回类型非常奇怪,并且将返回具有奇怪结构的复合数组。

无论如何,这是一个更好的解决方案

$lengthDesired = 29;
for($i='a'; $i != str_pad('',$lengthDesired+1,'a'); $i++)
    echo $i .', ';

答案 6 :(得分:1)

这是一个用java http://www.merriampark.com/perm.htm编写的置换生成器。

然而,正如他提到的那样

  //-----------------------------------------------------------
  // Constructor. WARNING: Don't make n too large.
  // Recall that the number of permutations is n!
  // which can be very large, even when n is as small as 20 --
  // 20! = 2,432,902,008,176,640,000 and
  // 21! is too big to fit into a Java long, which is
  // why we use BigInteger instead.
  //----------------------------------------------------------

由于您的n是29,您将等待很长时间。它太大了,因为EboMike试图在他的评论中告诉你。

答案 7 :(得分:1)

就在我的头顶(PHP)。

$index = 0;

while(1) {
   $output_string = '';
   $base_26 = (string)base_convert($index, 10, 26);
   if (strlen($base_26) > 29) break;
   for ($i = 0; $i < strlen($base_26); $i++) {
      $output_string .= chr(65 + base_convert($base_26[$i], 26, 10));
   }
   $index++;
   echo $output_string;
}

答案 8 :(得分:1)

这就是我要做的事情:

#include <iostream>

void printWords(std::string& word, int index, int last)
{
    std::cout << word << "\n";
    if (index != last)
    {
        for(char loop = 'a'; loop <= 'z'; ++loop)
        {
            word[index] = loop;
            printWords(word, index+1, last);
        }
        word[index] = ' ';
    }
}

int main()
{
    std::string word("                             "); // 29 space

    printWords(word,0,word.length());
}

答案 9 :(得分:1)

答案 10 :(得分:1)

public class hii {  

public static void main(String[] args){

    String[] database = {"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"};

    for(int i=1; i<=database.length; i++){
        String[] result = getAllLists(database, i);
        for(int j=0; j<result.length; j++){
            System.out.println(result[j]);
        }
    }



}


    public static String[] getAllLists(String[] elements, int lengthOfList)
    {
        //initialize our returned list with the number of elements calculated above
        String[] allLists = new String[(int)Math.pow(elements.length, lengthOfList)];

        //lists of length 1 are just the original elements
        if(lengthOfList == 1) return elements; 
        else {
            //the recursion--get all lists of length 3, length 2, all the way up to 1
            String[] allSublists = getAllLists(elements, lengthOfList - 1);

            //append the sublists to each element
            int arrayIndex = 0;

            for(int i = 0; i < elements.length; i++){
                for(int j = 0; j < allSublists.length; j++){
                    //add the newly appended combination to the list
                    allLists[arrayIndex] = elements[i] + allSublists[j];
                    arrayIndex++;
                }
            }
            return allLists;
        }
    }






}

答案 11 :(得分:0)

我能想到的最简单的方法是在伪代码中将每个排列从1个char变为29个字符:

loop from i = 1 to 26^29 or 27^29 if you want to include spaces
{
   convert i to base 26 or 27;
   translate each number to the corresponding letter;
}

答案 12 :(得分:0)

即使你可以将它存储在磁盘上,就像thirydot指出的那样,你也会没时间这样做。

只需在我的计算机上生成(而不是存储)所有6个字母的可能性需要24秒:

$ time perl letters.pl

real    0m24.837s
user    0m24.765s
sys     0m0.030s

每个单词7.7X10 ^ -8s,这意味着它需要8.4x10 ^ 33s或2.6x10 ^ 26s才能完成。

您需要更多地考虑您的算法。