Помогите плиз алгорит придумать =)
Сложность в том, что {...|...} может быть сколько угоднонеужели прям совсем сколько угодно? двадцать пять тыщ мильенов может быть?
И что, рекурсия не канает?
void GenerateVariants(int depth, List<string> variants, char[] current, List<string> result)
{
if (depth >= variants.Count)
{
result.Add(new String(current;
}
for (int i = 0; i < variants[depth].Length; i++)
{
current[depth] = variants[depth][i];
GenerateVariants(depth+1, variants, current, result);
}
}
В случае С++, вместо List<string> надо будет использовать vector<string>.
пусть таких скобочек N штук.
делаем массив
int CurrentLetter[N] (инициализируем нулями)
int Limits[N]; (Limits[k] = кол-во буковок в скобочке номер k минус 1)
Метакод:
main
{
//цикл, пока массивы не совпадут
while (1)
{
PrintSet(CurrentLetters, N);
int i;
for (i = 0; i < N; i++)
{
if (!IncrementNumber(CurrentLetters + i, Limits + i
break;
}
if (i == N) break;
}
}
bool IncrementNumber(int* current, int* limit)
{
(*current)++;
if (*current > *limit)
{
*current = 0;
return true;
}
return false;
}
void PrintSet(int* current, int size)
{
for(int i=0; i < size; i++)
{
std::cout << Data[i][current[i]] << ","
}
std::cout << std::endl;
}
ps: соптимайзил чуток
Скобочек {} ну штук 10, каждых элементов то же 10 макс, т.е. на скорость алгоритма пофиг.
Для входной строки ответ должен быть вот таким
AEG
AEH
ADG
ADH
BEG
BEH
BDG
BDH
CEG
CEH
CDG
CDH
Рекурсию, что то не соображу как
О, попробую перевести
$ cat a.php
<?php
$x = array(
array(1, 2, 3
array('a', 'b', 'c'
array('X', 'Y'
);
function go($x, $n = 0, $res = array {
if ($n == count($x {
echo implode(',', $res "\n";
return;
}
foreach ($x[$n] as $v) {
array_push($res, $v);
go($x, $n + 1, $res);
array_pop($res);
}
}
go($x);
?>
$ php a.php
1,a,X
1,a,Y
1,b,X
1,b,Y
1,c,X
1,c,Y
2,a,X
2,a,Y
2,b,X
2,b,Y
2,c,X
2,c,Y
3,a,X
3,a,Y
3,b,X
3,b,Y
3,c,X
3,c,Y
Еще бы перл уметь курить, но идею я уловил.
Псиб всем откликнувшимся, буду писать
энто пыхпых
return [x + y for x in a[0] for y in l(a[1:])] if a else ['']
о, ещё круче придумал! без всякой рекурсии.
a = ['ABC', 'CDEF', 'GH']
print reduce(lambda l, s: [x + y for x in l for y in s], a, [''])
ЗЫ верный путь к окулисту
как всегда, функциональное решение самое короткое
mGauss :: [[a]] -> [[a]]
mGauss [] = []
mGauss [x] = [[ksi]|ksi <- x]
mGauss (x:s) = [ksi:y|y <- mGauss s, ksi <- x]
задача стандартная на лексикографический перебор вариантов
variants - это какое кол-во букв может быть на каждом месте
int[] Init(int[] variants)
{
return new int[variants.Length];
}
//true - есть еще один вариант, false - перебор окончен
bool Next(int[] variant, int[] variants)
{
for(int i = variant.Length-1; i>=0; --i)
{
variant[i]++;
if (variant[i] < variants[i])
return true;
variant[i] = 0;
}
return false;
}
Все сделал.
Скобочек {} ну штук 10, каждых элементов то же 10 макс, т.е. на скорость алгоритма пофиг.У тебя там 10^10 вариантов выйдет, а у современных процессоров такого же порядка количество операций в секунду.
Неужели тебе ну совсем пофигу, будет оно выполняться пять секунд или пять часов?
Пофиг, это небольшая тулза для знакомого.
кроссворды разгадывает?
Но вообще это не тру хаскелл - слишком просто и не понятно, причём здесь теория категорий
f:: [[a]]->[[a]]
f=foldr (flip $ (flip (>>.(flip $ map.( [[]]
Чую меня камнями побьют, но это для подъема рейта в поисковиках (на формах гадить).
а вот это следовало тихо не упоминать
mGauss [] должно быть [[]] по идееЭ-э-э. А мне кажется как раз наоборот: пустое множество пустое же порождает.
f=foldr (flip $ (flip (>>.(flip $ map.( [[]]Хотелось написать вариант, в котором нет ни одного слова map. ^_^
В случае []: длина входного списка 0, поэтому ответ - это список списков нулевой длины. Входит ли в него единственный список нулевой длины? Да, потому что каждый его элемент входит в соответствующий элемент входного списка (по крайней мере, нельзя утверждать обратного).
Другими словами, у нас ведь количество комбинаций есть произведение количеств вариантов по каждой позиции. Произведение нуля сомножетелей по соглашению (и не без оснований) считают равным нейтральному элементу по умножению, то есть единице. Поэтому в ответе должна быть одна комбинация (пустая).
И повторю уже приведённый аргумент: такое определение получается менее симметричным, избыточным и противоречивым (в том смысле что можно придумать естественные свойства этой функции, которые нарушатся в граничном случае т.к. приходится отдельно рассматривать вариант [x]. Если не нравится f [] = [[]], то выходом могло бы быть определение частичной функции, начиная с одноэлементного списка.
> Хотелось написать вариант, в котором нет ни одного слова map. ^_^
А мне хотелось написать вариант в котором ни одного шаблона.
Произведение нуля сомножетелей по соглашению (и не без оснований) считают равным нейтральному элементу по умножению, то есть единице.Во как!
Во как!стандартная вещь
ничего удивительного
Оставить комментарий
0000
Попросили программку написать, а вот алгоритм реализации одного куска не получается придумать.Собственно вот что нужно:
{A|B|C}, {C|D|E|F}, {G|H}, ...
Надо нагенерить все возможные наборы вида
A, C, G, ...
B, C, H, ...
Сложность в том, что {...|...} может быть сколько угодно, ну и в каждой такой штуке A, B, C-элементов то же.
Пишется все на C++, данные хранятся в массиве Data[Номер {...|...}] [Номер буквы], но это не важно, т.к. можно переписать.