Имеем строку из цифр от 0 до 9.
Дина строки больше или равно 3 но меньше или равна 10
Каждая цифра может присутствовать только один раз.
Как найти все варианты перестановок чисел?
Например имеем 123
Начинаем перестовлять
123
132
213
231
132
321
312
и т. д.
Можно конечно перебором, но может есть что-то уневирсальное.
А перебором я делал так.
Сортирум по возрастанию, получаем получившееся число.
Далее сортируем по убыванию, получаем получившееся число.
Пото организую цикл от минимального числа к максимуму и проверяю, если заданные цифры все присутствуют в числе то печатаем если нет то дальше. Этот вариант более менее хорош когда у нас длина строки 3,4 и 5 символов, а дальше это долго.
Вот и хочется что-нить уневирсальное и быстрое.
Заранее спасибо.
Если универсальное, то можно что-нибудь типа такого:
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);
Здравствуйте, 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 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, mafiya, Вы писали:
M>Имеем строку из цифр от 0 до 9. M>Дина строки больше или равно 3 но меньше или равна 10 M>Каждая цифра может присутствовать только один раз. M>Как найти все варианты перестановок чисел?
В STL, в <algorithm> есть шаблон функции next_permutation, которая возвращает следующую перестановку для элементов контейнера. Посмотри ее алгоритм.
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.
Здравствуйте, 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!