我正在尝试编写一个程序,该程序将生成一个文本文件,其中包含从一个字符到二十九个字符的字母表的每个可能的排列。我选择了29作为最长的英语单词,每个人都知道是反歧视的英语单词,长度为28个字符。有更长的,但它们主要是技术性和模糊性。
我意识到这会产生大量的字符串。但是我不知道从哪里开始,甚至不知道如何计算出这将产生多少组合。
请回答有关PHP,Processing,C ++或Java的解决方案(我只熟悉那些,PHP是首选,但可能不是我想象的最好的)。
即使只是伪代码/想法也会受到赞赏。
此外,在有人说出来之前,这不是为了暴力强迫或类似的东西。我是一名艺术家,虽然有点不为人知,但我的概念模糊不清。
答案 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才能完成。
您需要更多地考虑您的算法。