Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Нахождение всех возмлжных комбинаций символов


Автор: Code Magister 25.9.2007, 23:48
Допустим будем рассматривать только символы от a до z. Вводится максимальная длинна "слова". И далее находятся все возможные комбинации этих символов, не превыщающие длинны n.
Например если n=2, то должно выдать нечто вроде:
Код

a
aa
ab
ac
...
ay
az
b
ba
bb
bc
...
zy
zz

 smile 

Автор: Akina 26.9.2007, 00:09
Код
'Компилировать не советую
for i="a" to "z"
 print i
 for j="a" to "z"
  print i+j
 next j
next i
При длине более 2 символов (или динамической) разумнее использовать рекурсию.

Автор: Code Magister 26.9.2007, 15:11
Ну ето для 2-х символов, а можешь показать как с рекурсией? У меня с ней всегда проблеммы

Автор: esperant0 27.9.2007, 09:34
for i=1 to n^n*log(n^n)*100

    x=случайное число от 1 до п.
    y=случайное число размером х
нехт



Автор: maxim1000 27.9.2007, 10:31
Цитата(esperant0 @  27.9.2007,  09:34 Найти цитируемый пост)
for i=1 to n^n*log(n^n)*100

    x=случайное число от 1 до п.
    y=случайное число размером х
нехт

этот код не обязательно выведет _все_ комбинации...

Автор: esperant0 27.9.2007, 10:51
Цитата(maxim1000 @ 27.9.2007,  10:31)
Цитата(esperant0 @  27.9.2007,  09:34 Найти цитируемый пост)
for i=1 to n^n*log(n^n)*100

    x=случайное число от 1 до п.
    y=случайное число размером х
нехт

этот код не обязательно выведет _все_ комбинации...

Вероятность того что код не выведет все комбинации на порядки меньше вероятности того что вселенная взорвется. 


А значит?

Автор: Akina 27.9.2007, 12:08
Код

Sub RecursiveOutput(Current As String, Length As Integer, Charset As String)
Dim i As Integer
Debug.Print Current
If Len(Current) < Length Then
 For i = 1 To Len(Charset)
  Call RecursiveOutput(Current & Mid(Charset, i, 1), Length, Charset)
 Next i
End If
End Sub

Private Sub Command1_Click()
Call RecursiveOutput("", 3, "abc")
End Sub

Автор: wils0n 28.9.2007, 12:33
Примерно так. Без рекурсии. Next() генерирует след. комбинацию. Get() выдаёт её.

Код

#include<iostream>
#include<vector>
#include<string>

using std::string;
using std::vector;

class LetterCombination {
public:
    LetterCombination(int length);
    ~LetterCombination() {}

    // генерирует вывод
    string    Get();
    // гачинаем сначала
    void    First();
    // следующая комбинация
    bool    Next();
    // все ли комбинации уже сгенерированы
    bool    ThatsAll();

private:    
    bool    m_ThatsAll;
    // какой длины комбинации генерировать
    int    m_Length;
    // вектор с текущей комбинацией.
    vector<int>    m_Set;
};

LetterCombination::LetterCombination(int length) : m_ThatsAll(true), m_Length(length)
{ 
    m_Set = vector<int>(m_Length);
}

void LetterCombination::First()
{
    m_ThatsAll = false;
    for (int i = 0; i < m_Length; i++) m_Set[i] = 0;
    // первая комбинация 00..001 соответствует 'a'
    m_Set[m_Length-1] = 1;
}

bool LetterCombination::Next()
{
    // если все комбинации уже сгенерированы, то ничего не делаем.
    if ( m_ThatsAll ) return false;

    // увиличиваем последнюю букву.
    int i = m_Length-1;
    m_Set[i]++;

    // если последняя была уже 'z', то превращаем её в 'a' и увиличиваем на один
    // впереди стоящую...
    while( (i>0) && (m_Set[i] == 27) )
    {
        m_Set[i--] = 1;
        m_Set[i]++;
    }

    return !ThatsAll();
}

bool LetterCombination::ThatsAll()
{
    // если в первой позиции буква превзошла 'z', то всё!
    if (m_Set[0] == 27) 
    {
        First();
        m_ThatsAll = true;
    }
    return m_ThatsAll;
}

string LetterCombination::Get()
{
    string res = string();
    int i = m_Length-1;
    
    // конвертируем числа 1..26 в буквы a..z
    while( (i >= 0) && (m_Set[i] > 0) )
    {
        res.insert(0, 1, char(96 + m_Set[i]));
        i--;
    }

    return res;
}

int main(int argc, char** argv)
{
    if (argc < 2) return -1;
    int cnt = atoi(argv[1]);

    LetterCombination lc = LetterCombination(cnt);

    lc.First();
    while (! lc.ThatsAll()) 
    {
        std::cout << lc.Get() << std::endl;
        lc.Next();
    }    

    std::cout << lc.Get() << std::endl;

    return 0;
}


Автор: codelord 18.1.2008, 18:58
как нить так  smile 
Код

#include <iostream>
#include <math.h>
using namespace std;

char start = 'a';
char end = 'z';
void show_mas ( char *mas, int len ) {
 for( int i = 0; i < len; ++i  ) {
   cout << *(mas + i ) << " ";
  }
 cout << endl;
}

void next( char *mas, int Len ) {
 int len = Len;
 while( --len >= 0 ) {
        if( *( mas + len ) < end ) {
          if( *( mas + len ) == start || *(mas + len + 1 ) == end ) {
                        memset( mas+len+1, 'a', Len-len-1 );
                }
          ++ *( mas + len );
          show_mas( mas, Len );
          break;
        }
     }
}
int main( int argc, char **argv ) {
 int len = 6;
 char *mas = new char[ len ];
 memset( mas , 'a', len );

 int iter = (int)pow( 26, len );
 for( int i = 0; i < iter ; ++i ) {
  next( mas, len );
 }
delete[] mas;
 return 0;
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)