Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > помогите решить задачку


Автор: DooZ 27.9.2007, 10:15
есть строка например: abcd
надо сделать замены каждой буквы например на цифры (это не столь важно на что)
т.е. нужно сделать вот такие замены:
a b c d
--------
1
   2
      3
         4
1 2
1    3
1       4
   2 3
   2    4
      3 4
1 2 3 4
---------
тут показано в столбик как менается каждая буква
в итоге имеем: 11 строк (замен)
т.е. в итоге имеем список:
1 b c d
a 2 c d
a b 3 d
a b c 4
1 2 c d
1 b 3 d
1 b c 4
a 2 3 d
a 2 c 4
a b 3 4
1 2 3 4
собственное вот...

как это сделать? =)
я не могу въехать

смысл еще в том что кол-во символов в строке может быть больше или меньше 4-х как в данном примере
цифры любые (это просто для примера)

заранее благодарю

Автор: amg 27.9.2007, 12:21
Так?
Код

@a = qw(a b c d);

@m = (
[qw(1 0 0 0)],
[qw(0 2 0 0)],
[qw(0 0 3 0)],
[qw(0 0 0 4)],
[qw(1 2 0 0)],
[qw(1 0 3 0)],
[qw(1 0 0 4)],
[qw(0 2 3 0)],
[qw(0 2 0 4)],
[qw(0 0 3 4)],
[qw(1 2 3 4)],
);

@ma = map {$i=0;[map {$_ or $a[$i++]} @$_]} @m;
print "@$_\n" for @ma;
Разбирайся smile 

Автор: igorold 27.9.2007, 13:41
а такие сочетания не нужны?

1 2 3
1 2    4
1    3 4
   2 3 4

Автор: DooZ 27.9.2007, 22:46
2igorold - нужны, я просто их упустил (забыл) smile
2amg - а если слово будет из 10 букв? (из 100 букв)?

надо универсальный пример который будет обрабатывать любое кол-во букв, хоть 1 хоть 1000

Автор: amg 28.9.2007, 08:54
Если нужны все перестановки такого рода (а не "наложить" вектор на заданную матрицу, как я понял в начале), то задача даже упрощается (легко заметить, что при замене цифр на 0 и букв на 1 весь набор перестановок превращается в обыкновенный ряд двоичных чисел). Правда, чтобы была возможность обрабатывать слово из 1000 букв, пришлось использовать модуль Math::BigInt (уважаю мыслящих космическими масштабами: такая задача будет считаться до смерти вселенной и все равно не закончится, хотя ее придется прервать раньше, когда на Земле закончится вся бумага, чтобы распечатывать результат).
Код

use Math::BigInt;
my @a = split '', 'abcd';
my $size = 2**(Math::BigInt->new($#a+1));

while ($size--) {
  (my $d = $size->as_bin) =~ s/^0b//;
  print "@{[map {chop $d ? $_+1 : $a[$_]} 0..$#a]}\n";
}


Автор: DooZ 28.9.2007, 10:14
замена на что не важна (не только цифры) возможна замена на какие-то символы, яж написал что это не столь важно
к примеру можно создать шаблон типа:
a - .
b - =
c - ||
и т.д.
смысл ясен?
цифры я дал как простой пример
в данном случае их можно отнести к:
a - 1
b - 2
c - 3
шаблон изменяемый

так что пример с цифрами отпадает

Добавлено @ 10:15
задачка остается до сих пор не решенной
ну же гуру перла, подсобите =)

Автор: amg 28.9.2007, 11:31
Я так и не понял, чем не устраивает моё решение. Вместо цифр подставлять другие символы, из шаблона? Так это совсем просто. Заменить в коде массив цифр 0..$#a на массив символов и , $_+1 на $_ переправить, и все. Если опять не то, то нужно задачу точно сформулировать.

Автор: DooZ 29.9.2007, 06:41
да куда уж точнее формулировать-то?
помоему максимально точная формулировка была дана

повторюсь, может кто чего не понял
нужно заменять буквы символами из шаблона которые соответствуют
буква a = например символу {
буква b = например символу *
ну и т.д.

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

если и щас задача не ясна, тогда я уж не знаю как объяснить

Автор: amg 29.9.2007, 13:54
Цитата(DooZ @  29.9.2007,  06:41 Найти цитируемый пост)
помоему максимально точная формулировка была дана
Ну это только по твоему. Между прочим, задача твоя увлекательная, и не очень сложная. И на нее было бы масса откликов, если бы все было понятно. А так кроме меня один igorold отметился, проявив чудеса интуиции... Ладно, не будем обострять отношения...
Цитата(DooZ @  29.9.2007,  06:41 Найти цитируемый пост)
заменять как было написано в первой мессаге
Из того, что там написано можно догадаться, как сделать первую замену, вторую тоже, а дальше? 
В связи с требованием упорядочения приведенный ниже код я немного изменил, чтобы при замене в перестановках букв на 0 и символов на 1 получался последовательный ряд двоичных чисел, так что заранее легко узнать, как будет выглядеть n-ая перестановка. Также ограничил длину слова (исчезла надобность в модуле, без него быстрее работает, и все равно при максимальной длине слова много часов счета).

В общем, делаю еще одну попытку
Код

# Алфавит и соответствующие ему символы (сойдет за шаблон ?)
my @alph  = qw!  a b c d e f g h i j k l m n o p q r s t u v w x y z  !;
my @templ = qw!  " : $ % & ' ( ) * + - / ; < = > @ [ \ ] ^ ` { | } ~  !;

# Хэш буква => символ
my %templ = map {$alph[$_]=>$templ[$_]} 0..$#alph;
## Заглавная буква => удвоенный символ
#map {$templ{uc $_} = $templ{$_} x 2} keys %templ;

# Слово
my @a = split '', 'abcd';
die "Слишком длинное слово\n" if @a > 31;

# Число перестановок 
my $size = 2**@a;
warn "$size\n";  

my $i = 0;
while ($i<$size) {
  my $d = unpack("B32", pack("N", $i++)); # Двоичное число
  print "@{[reverse map {chop $d ? $templ{$_} : $_} reverse @a]}\n";

#  # Другой вариант, более "прямолинейный" и понятный, но в 2 раза медленнее
#  my $d = sprintf "%b", $i++;    # Двоичное число
#  $d = '0'x(@a-length($d)) . $d; # Добавляем недостающие нули
#  print "@{[map {$d=~s/.// && $& ? $templ{$_} : $_} @a]}\n"; 
}


Автор: DooZ 30.9.2007, 15:42
2amg - ты молоток!!! максимально четко понял задачу, и реализовал
огромный респект и уважуха (как любят щас говорить) smile

реализована так как мне нужно =)

еще раз огромное спасибо! =)

Автор: igorold 1.10.2007, 07:59
Цитата(DooZ @  30.9.2007,  15:42 Найти цитируемый пост)
уважуха (как любят щас говорить) smile


сейчас моднее говорить правильным русским языком ... не надо копировать нежизнеспособные ветки развития ...


DooZ, с твоего позволения ставлю amg +1
... я тоже начал придумывать алгоритм решения, но amg уже предложил ... как математик я понял чего тебе надо ... немного не хватило времени придумать ... 

... пометь тему как решенную ... 

Автор: DooZ 3.10.2007, 19:03
яб amg +10 поставил но тут низя )
помечаю как решенную
всем сенькс!

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