Перестановки
От: mafiya  
Дата: 03.02.03 09:28
Оценка:
Имеем строку из цифр от 0 до 9.
Дина строки больше или равно 3 но меньше или равна 10
Каждая цифра может присутствовать только один раз.
Как найти все варианты перестановок чисел?
Например имеем 123
Начинаем перестовлять
123
132
213
231
132
321
312
и т. д.
Можно конечно перебором, но может есть что-то уневирсальное.
А перебором я делал так.
Сортирум по возрастанию, получаем получившееся число.
Далее сортируем по убыванию, получаем получившееся число.
Пото организую цикл от минимального числа к максимуму и проверяю, если заданные цифры все присутствуют в числе то печатаем если нет то дальше. Этот вариант более менее хорош когда у нас длина строки 3,4 и 5 символов, а дальше это долго.
Вот и хочется что-нить уневирсальное и быстрое.
Заранее спасибо.
Re: Перестановки
От: siavol Россия  
Дата: 03.02.03 12:19
Оценка:
Здравствуйте, mafiya, Вы писали:

[...]

Если универсальное, то можно что-нибудь типа такого:

        void Next(int it, string str)
        {
            if (it<str.Length)
            {
                Next(it+1, str);

                for (int i = it+1; i<str.Length; i++)
                {
                    string temp = str;
// За следующие строки прошу меня простить, самому страшно на них смотреть,
// но как заменить i-й символ в строке так сразу с нелету не сообразил
                    temp = temp.Remove(it, 1);
                    temp = temp.Insert(it, str[i].ToString());
                    temp = temp.Remove(i, 1);
                    temp = temp.Insert(i, str[it].ToString());
                    listBox1.Items.Add(temp); 
                    counter++;
                    Next(it+1, temp);
                }
            }
        }


Правда таким методом теряется самая первая (исходная) перестановка. Используется так:
    listBox1.Items.Add(temp); // Шоб не потерялась...
    Next(0, str);


Работает вроде приемлимо...
... << RSDN@Home 1.0 beta 5 >>
Re: Перестановки
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.02.03 22:14
Оценка:
Здравствуйте, mafiya, Вы писали:
Сделай рекурсивный алгоритм. Идея такая:
Нам передают множество цифр.
Берем первую цифру из этого множества. Берем множество переданных цифр, кроме выбратой, вызываем себя же с этим уменьшенным множеством. К каждому результату приписываем выбранную цифру.
Теперь берем вторую цифру, и делаем то же самое.
Все.
Примерный код на С++:
void PrintRepositions(char * pPrefix, char * pDigits, int DigitCount)
{
  if (DigitCount==1) // вывести единственную перестановку
  {
    cout << pPrefix << pDigits  << endl;
  } else 
  {
    size_t PrefixLen = strlen(pPrefix);
    char *tempDigits= new char[DigitCount]; // подготовим массив цифр без выбранной
    strcpy(tempDigits, pDigits+1); // теперь у нас есть "хвост" массива
    char *tempPrefix= new char[PrefixLen+2];
    strcpy(tempPrefix, pPrefix);
    tempPrefix[PrefixLen+1]=0;
    for (int i=0; i<DigitCount; i++)
    {
      tempPrefix[PrefixLen] = pDigits[i]; // указали выбранную цифру
      // урезанный массив цифр нами уже подготовлен
      PrintRepositions(tempPrefix, tempDigits, DigitCount-1);
      // подправим массив выбранных цифр для следующей итерации
      tempDigits[i] = pDigits[i]; 
    }
    delete[] tempDigits;
    delete[] tempPrefix;
  }
}
int _tmain(int argc, _TCHAR* argv[])
{
    PrintRepositions("", "1234567", 7);
    return 0;
}
... << RSDN@Home 1.0 beta 3 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Перестановки
От: Mink Россия  
Дата: 04.02.03 08:02
Оценка:
Здравствуйте, mafiya, Вы писали:

M>Имеем строку из цифр от 0 до 9.

M>Дина строки больше или равно 3 но меньше или равна 10
M>Каждая цифра может присутствовать только один раз.
M>Как найти все варианты перестановок чисел?


В STL, в <algorithm> есть шаблон функции next_permutation, которая возвращает следующую перестановку для элементов контейнера. Посмотри ее алгоритм.
Сила, она в ньютонах
Re: Перестановки
От: DemAS http://demas.me
Дата: 05.02.03 06:17
Оценка:
Здравствуйте, mafiya, Вы писали:

[..]

А вот вариант на Pascal:

program Perestanovki;
      type Pere=array [byte] of byte;
      var N,i,j:byte;
      X:Pere;
      Yes:boolean;
      procedure Next(var X:Pere;var Yes:boolean);
    var i:byte;
    procedure Swap(var a,b:byte);  {обмен переменных}
      var c:byte;
    begin c:=a;a:=b;b:=c end;
      begin
    i:=N-1;
    {поиск i}
    while (i>0)and(X[i]>X[i+1]) do dec(i);
    if i>0 then
      begin
        j:=i+1;
        {поиск j}
        while (j<N)and(X[j+1]>X[i]) do inc(j);
        Swap(X[i],X[j]);
        for j:=i+1 to (N+i) div 2 do Swap(X[j],X[N-j+i+1]);
        Yes:=true
      end
    else Yes:=false
      end;
    begin
      write('N=');readln(N);
      for i:=1 to N do X[i]:=i;
      repeat
    for i:=1 to N do write(X[i]);writeln;
    Next(X,Yes)
      until not Yes
    end.
... <<Наслаждаюсь — Slipknot — Tattered & Torn>>
Re: Перестановки
От: GiDRAvlic Латвия  
Дата: 06.02.03 13:05
Оценка:
Здравствуйте, mafiya, Вы писали:

M>Имеем строку из цифр от 0 до 9.

M>Дина строки больше или равно 3 но меньше или равна 10
M>Каждая цифра может присутствовать только один раз.
M>Как найти все варианты перестановок чисел?
M>Например имеем 123
M>123
M>132
M>213
M>231
M>132
Ета повторяется
M>321
M>312
M>и т. д.
M>Можно конечно перебором, но может есть что-то уневирсальное.
M>Вот и хочется что-нить уневирсальное и быстрое.
Длина строки в факториале — 3!
... << RSDN@Home 1.0 beta 6a >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.