Больше примеров алгоритмов перестановки для генерации их.
Источник: http://www.ddj.com/architect/201200326
1.
PROGRAM TestFikePerm;
CONST marksize = 5;
VAR
marks : ARRAY [1..marksize] OF INTEGER;
ii : INTEGER;
permcount : INTEGER;
PROCEDURE WriteArray;
VAR i : INTEGER;
BEGIN
FOR i := 1 TO marksize
DO Write ;
WriteLn;
permcount := permcount + 1;
END;
PROCEDURE FikePerm ;
{Outputs permutations in nonlexicographic order. This is Fike.s algorithm}
{ with tuning by J.S. Rohl. The array marks[1..marksizn] is global. The }
{ procedure WriteArray is global and displays the results. This must be}
{ evoked with FikePerm(2) in the calling procedure.}
VAR
dn, dk, temp : INTEGER;
BEGIN
IF
THEN BEGIN { swap the pair }
WriteArray;
temp :=marks[marksize];
FOR dn := DOWNTO 1
DO BEGIN
marks[marksize] := marks[dn];
marks [dn] := temp;
WriteArray;
marks[dn] := marks[marksize]
END;
marks[marksize] := temp;
END {of bottom level sequence }
ELSE BEGIN
FikePerm;
temp := marks[k];
FOR dk := DOWNTO 1
DO BEGIN
marks[k] := marks[dk];
marks[dk][ := temp;
FikePerm;
marks[dk] := marks[k];
END; { of loop on dk }
marks[k] := temp;l
END { of sequence for other levels }
END; { of FikePerm procedure }
BEGIN { Main }
FOR ii := 1 TO marksize
DO marks[ii] := ii;
permcount := 0;
WriteLn ;
WrieLn;
FikePerm ; { It always starts with 2 }
WriteLn ;
ReadLn;
END.
2.
PROGRAM TestLexPerms;
CONST marksize = 5;
VAR
marks : ARRAY [1..marksize] OF INTEGER;
ii : INTEGER;
permcount : INTEGER;
PROCEDURE WriteArray;
VAR i : INTEGER;
BEGIN
FOR i := 1 TO marksize
DO Write ;
permcount := permcount + 1;
WriteLn;
END;
PROCEDURE LexPerm ;
{ Outputs permutations in lexicographic order. The array marks is global }
{ and has n or fewer marks. The procedure WriteArray () is global and }
{ displays the results. }
VAR
work : INTEGER:
mp, hlen, i : INTEGER;
BEGIN
IF
THEN BEGIN { Swap the pair }
work := marks[1];
marks[1] := marks[2];
marks[2] := work;
WriteArray ;
END
ELSE BEGIN
FOR mp := DOWNTO 1
DO BEGIN
LexPerm<>;
hlen := DIV 2;
FOR i := 1 TO hlen
DO BEGIN { Another swap }
work := marks[i];
marks[i] := marks[n - i];
marks[n - i] := work
END;
work := marks[n]; { More swapping }
marks[n[ := marks[mp];
marks[mp] := work;
WriteArray;
END;
LexPerm<>
END;
END;
BEGIN { Main }
FOR ii := 1 TO marksize
DO marks[ii] := ii;
permcount := 1; { The starting position is permutation }
WriteLn < Starting position: >;
WriteLn
LexPerm ;
WriteLn < PermCount is , permcount>;
ReadLn;
END.
3.
PROGRAM TestAllPerms;
CONST marksize = 5;
VAR
marks : ARRAY [1..marksize] of INTEGER;
ii : INTEGER;
permcount : INTEGER;
PROCEDURE WriteArray;
VAR i : INTEGER;
BEGIN
FOR i := 1 TO marksize
DO Write ;
WriteLn;
permcount := permcount + 1;
END;
PROCEDURE AllPerm (n : INTEGER);
{ Outputs permutations in nonlexicographic order. The array marks is }
{ global and has n or few marks. The procedure WriteArray is global and }
{ displays the results. }
VAR
work : INTEGER;
mp, swaptemp : INTEGER;
BEGIN
IF
THEN BEGIN { Swap the pair }
work := marks[1];
marks[1] := marks[2];
marks[2] := work;
WriteArray;
END
ELSE BEGIN
FOR mp := DOWNTO 1
DO BEGIN
ALLPerm<< n - 1>>;
IF >
THEN swaptemp := 1
ELSE swaptemp := mp;
work := marks[n];
marks[n] := marks[swaptemp};
marks[swaptemp} := work;
WriteArray;
AllPerm< n-1 >;
END;
END;
BEGIN { Main }
FOR ii := 1 TO marksize
DO marks[ii] := ii
permcount :=1;
WriteLn < Starting position; >;
WriteLn;
Allperm < marksize>;
WriteLn < Perm count is , permcount>;
ReadLn;
END.
Я бы предпочел отказаться от ванильной поддержки CGI. Хостинг FCGI в наши дни действительно дешев, и нет причин потворствовать ванильным CGI (IMO), потому что он просто укрепляет мнение о том, что Perl медленный. Но если вы не можете этого избежать, вы можете использовать что-то вроде Object :: Tiny . Но если вам нужны роли, ограничения, метапрограммирование и все остальное очарование, которое предоставляет Moose, вам не повезло, если вы не откажетесь от ванильного CGI.
Вы можете написать приложение внутреннего сервера, используя Moose, а затем написать очень небольшие простые сценарии CGI, которые запрашивают серверную часть.
+-------+ +--------------+
| Small |===>| Persistent |
| CGI |<===| Moose Server |
+-------+ ^ +--------------+
|
Socket
Connection
Это более или менее то, что делает FCGI, поэтому может иметь больше смысла просто использовать FCGI.
С другой стороны, наличие внутреннего сервера без поддержки cgi, который может иметь ЛЮБОЙ абстрактный интерфейс, подключаемый по мере необходимости.
Например, если вы используете сокеты TCP (или UDP), тогда у вас может быть собственное настольное приложение, работающее в той же серверной части, что и ваш CGI.
Что лучше всего подходит Ваш случай действительно зависит от вашей конкретной ситуации.
Джонатан Роквей писал о APP :: Peristent (который, как ни странно, не входит в CPAN) несколько месяцев назад. Я не использовал его, но, судя по его сообщению в блоге по ссылке выше, похоже, что он обеспечивает довольно прозрачную архитектуру сервер-клиент, в которую вы можете заключить фактическую обработку вашего CGI.
Я предлагаю выбрать вариант №2 и затем помочь нам реорганизовать Moose, чтобы CGI стал жизнеспособным. В настоящее время fREW работает над набором тестов Moose, чтобы включить проект MooseX :: Antlers, который должен снизить большую часть накладных расходов, что означает, что Moose непригоден для использования в среде CGI.
Мэтт Траут (mst), человек, который в настоящее время стоит за MooseX :: Antlers, выразил желание иметь возможность запускать приложения в среде CGI, если это необходимо. Я бы посоветовал пока остаться с FCGI и приставать к нему, чтобы узнать, чем вы можете помочь!
Основная идея App :: Persistent
, pperl
, SpeedyCGI
и, возможно, некоторых других, заключается в том, что процесс компиляции ваша программа Perl для байтового кода выполняется только один раз, и после этого при вызовах используется какое-то кеширование. Поскольку говорят, что у Moose довольно много времени на компиляцию, я бы сначала попробовал этот подход.
Я успешно использовал pperl
для рисования большого количества MRTG графиков на древнем примерно в 2001 году. Программа Perl выполнялась для каждого графа, что было довольно накладным - это, вероятно, сопоставимо с вашим сценарием CGI.
There is also another option - PPerl.
I have never used it, but it definitely looks interesting. And the person who wrote it (Matt Sergeant aka baud) - it gives you practically guarantee of good quality code.