2010-07-27 2 views
1

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

"100","200","300","400","500", ... 

И у меня есть строка шаблона, который имеет несколько маркеров, которые должны быть заменены:

"@[email protected]@[email protected]@[email protected]@[email protected]" 

Использование списка значений, как я могу генерировать все возможные комбинации значений в шаблоне?

Значения могут использоваться более одного раза, поэтому результат может быть «100-100-100». Дополнительные очки для метода, учитывающего переменное количество токенов!

+1

могут быть использованы значения более чем один раз? число фиксированных 3 токов? – mvds

+0

Значения могут использоваться более одного раза, что означает, что результатом может быть: 100-100-100. Токены также не фиксированы. –

+0

Будьте готовы к долгому ожиданию, если ваш список значений действительно может быть любой длины, так как число перестановок N равно N! (т.е. факториал N). Это очень быстро, и для списка умеренного размера (скажем, 20-30) создание всех комбинаций может занять больше времени, чем продолжительность жизни Вселенной. –

ответ

2

редактирования: удалены фиксированное количество версии токенов

использовать рекурсию, просто для удовольствия:

r($values,false,$numtokens); // false to get 100-100-100 as well. 

function r($values,$unique=true,$depth=3,$collect=array()) 
{ 
    if ($depth == 0) 
    { 
      print implode("-",$collect)."\n"; 
    } else { 
      foreach ($values as $id=>$t) 
      { 
        if ($unique) unset($values[$id]); 
        r($values,$unique,$depth-1,array_merge($collect,array($t))); 
        if ($unique) $values[$id] = $t; 
      } 
    } 
} 

(это может потребоваться адаптация для разных языков)

+0

Означает ли это, что строка шаблона с токенами в нем всегда отформатирована с помощью дефиса? –

+0

в основном дает вам массив элементов, которые вы можете использовать в любых целях. 'implode (" - ", $ collect)' означает просто конкатенировать их с '-' между элементами. Но вы можете сделать что-нибудь в этом пункте - '$ template =" .. @ token0 @ .. "; foreach ($ collect as $ id => $ el) $ template = str_replace ("@ token $ id @", $ el, $ template); 'например (note: first element id 0!) – mvds

1

Python:

from itertools import permutations 
list_of_values = ["100","200","300","400","500"] 
template = "%s-%s-%s" 
for p in permutations(list_of_values,3): 
    print(template % p) 

Вы можете сделать co mbinations вместо перестановок, если вы не хотите «500-400-300» и «300-400-500» в качестве примера.

0

Предполагая, что значения могут быть повторены:

#!/usr/bin/env python 

VALUES=['100','200','300','400','500'] 

TOKEN='@token%[email protected]' 

TARGET="@[email protected]@[email protected]@[email protected]" 

def rep(n,target): 
    src=TOKEN%n 
    if src not in target: 
     return [target] 

    ret = [] 
    for v in VALUES: 
     ret += rep(n+1, target.replace(src,v)) 
    return ret 

print rep(1,TARGET) 
Смежные вопросы