Каждая перестановка алфавита до 29 символов? - PullRequest
3 голосов
/ 06 января 2011

Я пытаюсь написать программу, которая будет генерировать текстовый файл с каждой возможной перестановкой алфавита от одного символа до двадцати девяти символов.Я выбрал 29 как самое длинное английское слово, которое все знают, это antidisestablishmentarianism длиной 28 символов.Есть более длинные, но они в основном очень технические и непонятные.

Я понимаю, что это создаст огромное количество строк.Однако я не знаю, с чего начать или даже как выяснить, сколько комбинаций это сгенерирует.

Ответы, пожалуйста, для решений на PHP, Обработка , C ++ или Java (ятолько знакомый с ними, PHP предпочтительнее, но, вероятно, не лучший для этого я должен представить).

Или даже просто псевдокод / ​​идеи будут оценены.

Кроме того, прежде чем кто-то это скажет, это не для грубого принуждения или чего-то в этом роде.Я художник, хотя и немного неизвестный и не совсем понимающий мои концепции.

Ответы [ 13 ]

4 голосов
/ 06 января 2011

Слово «перестановка» обычно означает, что каждая буква встречается ровно один раз, поэтому было бы невозможно создать какую-либо перестановку, содержащую более 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);
}
3 голосов
/ 06 января 2011

Вот простая непроверенная программа на 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;
}

Количество напечатанных слов можно уменьшить, проверив список слов (например, словарь) перед печатью. Если слово есть в списке слов, распечатайте его.

Самая большая проблема с длиной слова в 29 - это количество. Количество выходит за пределы стандартного целого числа C ++ без знака. Библиотека Big Int должна быть использована. Следующая проблема - это время, необходимое для обработки каждой комбинации. Умножьте количество на 1 микросекунду за итерацию (в худшем случае) и уменьшите до дней, часов, минут и секунд. Возможно, могут потребоваться годы.

3 голосов
/ 06 января 2011

Очевидно, что внешний цикл for предназначен для количества символов в вашем слове. Затем вы просто создаете строки с такой длиной. Для длины 5 вы начинаете с «AAAAA», затем «AAAAB», «AAAAC».

Как только вы нажмете «Z», вы вернетесь назад и переместите персонажа влево вверх, т.е. «AAAAZ» станет «AAABA», а «AAAZZ» станет «AABAA». Как только вы нажмете «ZZZZZ», вы закончите с внутренним циклом, и внешний цикл начнется с «AAAAAA».

3 голосов
/ 06 января 2011
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 голосов
/ 06 января 2011
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), ''); ---> print_r(p($l, ''));

PHP продолжает удивлять меня своей терпимостью к ошибкам.Отсутствует обязательный аргумент для моего p?нет проблем, это будет просто пустая строка (или ноль, или ложь, в зависимости от ситуации).Второй аргумент в print_r?без разницы, все равно как по умолчанию false 1011 *

РЕДАКТИРОВАТЬ

Я не знаю, какого черта я здесь делал.Различные типы возвращаемых значений p довольно странные и возвращают составной массив со странной структурой.

В любом случае, это гораздо лучшее решение

$lengthDesired = 29;
for($i='a'; $i != str_pad('',$lengthDesired+1,'a'); $i++)
    echo $i .', ';
2 голосов
/ 06 января 2011

Использование приращения символов в стиле Perl в PHP.

set_time_limit(0);

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

Запустите сценарий из командной строки, чтобы не превышать тайм-аут веб-сервера;затем откиньтесь на спинку кресла и подождите несколько лет, пока он не завершится

1 голос
/ 12 декабря 2014
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;
        }
    }






}
1 голос
/ 06 января 2011

Java-решение, которое должно сработать:

public void characterPermutations(int length, LinkedList<String> permutations) {
    if(length > 1) {
        characterPermutations(length - 1, permutations);

        ListIterator<String> iterator = permutations.listIterator();
        while(iterator.hasNext()) {
            String permutation = iterator.next();
            for(char c = 'a'; c <= 'z'; c++) {
                iterator.add(c + permutation);
            }
        }

    } else {
        for(char c = 'a'; c <= 'z'; c++) {
            permutations.add(c + "");
        }
    }
}
1 голос
/ 06 января 2011

Вот что я бы сделал:

#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());
}
1 голос
/ 06 января 2011

чуть выше моей головы (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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...