Вычисление факториала через использование рекурсии
program z1r;
var n: integer;
function fact(a: integer): longint;
begin
if a=0 then fact:=1
else
fact:=a*fact(a-1);
end;
begin
write('n='); readln (n);
if n<0 then write('error!')
else
writeln (n,'!=',fact(n));
readln;
end.
program z1;
var n, i: integer;
f : double;
begin
{write('n='); readln (n);}
for n:=0 to 25 do
if n<0 then write('error!')
else
begin
f:=1;
for i:=1 to n do
f:=f*i;
writeln (n,'!=',f:0:0);
end;
readln;
end.
program z1;
var
n, i: integer;
f : extended;
begin
{write('n='); readln (n);}
for n:=0 to 25 do
if n<0 then write('error!')
else
begin
f:=1;
for i:=1 to n do
f:=f*i;
writeln (n,'!=',f:0:0);
end;
readln;
end.
ПРОБЛЕМА:
Вычисление факториалов «больших» чисел
Например: 100!
система счисления с основанием 1000!
A = 12345678
Основной алгоритм:
[A]:= 1
нц для k от 2 до 100
[A]:= [A] * k
кц
длинное число
основание 1000000
2)
r := перенос в A[1]
s:= A[0]*k;
A[0]:= s mod d;
r:= s div d;
s:= A[1]*k + r
3) Умножение «длинного» числа на k:
for k:=2 to 100 do
begin
...
end;
i:= N;
while A[i] = 0 do
i:= i - 1;
write( A[i] );
012345
x div 100000
x mod 100000
begin
a[0]:=1;
for k:=2 to 100 do
begin
r:= 0;
for i:= 0 to N do begin
s:= A[i]*k + r;
A[i]:= s mod d;
r:= s div d
end;
end;
i:= N;
while A[i] = 0 do
i:= i - 1;
write( A[i] );
for k:=i-1 downto 0 do
Write6(A[k]);
readln;
end.
Множество всех подмножеств множества из N элементов содержит 2N элементов.
Идея алгоритма:
Заведем вектор B, состоящий из 4-ёх чисел, каждое из которых может принимать значение 0 или 1.
Будем считать, что значение 1 указывает на то, что соответствующий по номеру компонент исходного множества включается в множество, а значение 0 указывает на то, что элемент не включается.
program z3_mnoj;
const alphabet: string[26] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var b : array [1..100] of byte;
N, i : byte;
begin
readln(N);
for i:=1 to N+1 do b[i]:=0;
writeln ('empty set');
while b[N+1]=0 do begin
i:=1;
while b[i]=1 do begin b[i]:=0; inc(i); end;
b[i]:=1;
for i:=1 to n do if b[i]=1 then write(alphabet[i]);
writeln;
end;
readln;
end.
Обнуление массива B из N+1 элемента
0000
1000
0100
1100
0010
1010
0110
1110
…
1111
Лексикографический порядок
Алгоритм построения следующей перестановки
Пример:
Перестановки из 9 компонент, обозначенных цифрами от 1 до 9
1-ая перестановка: 1 2 3 4 5 6 7 8 9
Последняя перестановка:
9 8 7 6 5 4 3 2 1
program z4_perest;
const
alphabet: string[26] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var b : array [1..100] of byte ;
N,i,j,k : byte;
flag: boolean;
procedure swapB(i,k:byte);
var x : byte;
begin
x:=B[i]; B[i]:=B[k]; B[k]:=x;
end;
procedure writeB;
begin
for i:=1 to N do write(alphabet[b[i]]);
writeln;
end;
begin readln(N);
for i:=1 to N do b[i]:=i;
writeB;
flag:=true;
while flag do begin
i:=N;
while (i>0) and (B[i]>=B[i+1]) do i:=i-1;
if i=0 then flag:=false
else begin
for j:=i+1 to N do
if (B[j]>B[i]) then k:=j;
swapB(i,k);
for j:=i+1 to (i+ ((N+1-i) div 2))
do swapB(j,N+i+1-j);
writeB;
end;
end;
end.
Лексикографический порядок
Алгоритм генерации последовательности
Выберем наименьшие M из N чисел и выпишем их в порядке возрастания - 1 2 3 - это начальное сочетание.
Наибольшие M из N чисел (3 4 5), выписанные в порядке возрастания, последнее сочетание.
program z5_sochet;
uses crt;
const
alphabet:
string[26] =
'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var
b : array [1..100] of byte;
N, M, i, j, k : byte;
flag: boolean;
procedure WriteB;
begin
for i:=1 to M do write(alphabet[b[i]]);
writeln;
end;
begin readln(N,M);
for i:=1 to M do b[i]:=i;
writeB;
flag:=true;
while flag do
begin
i:=M;
while (i>0) and (b[i]=N-m+i) do dec(i);
if i=0 then flag:=false
else begin
inc(B[i]);
for j:=i+1 to M do B[j]:=B[j-1]+1;
writeB;
end;
end;
readln;
end.
Все возможные перестановки из 3 букв 1-го элемента строки
1-ые элементы строк представляют все возможные сочетания из 5 букв по 3
procedure PermuteAll(B:barray; N:byte);
var i,k,j : byte;
begin
writeB(B);
while (true) do begin
i:=N;
while (i>0) and (B[i]>=B[i+1]) do i:=i-1;
if i=0 then exit;
for j:=i+1 to N do if (B[j]>B[i]) then K:=j;
swapB(B,i,k);
for j:=i+1 to (i+ ((N+1-i) div 2)) do swapB(B,j,N+i+1-j);
writeB(B);
end;
end;
begin readln(N,M);
for i:=1 to M do b[i]:=i; PermuteAll(B,M);
flag:=true;
while (flag) do begin
i:=M;
while (i>0) and (b[i]=N-m+i) do dec(i);
if i=0 then flag:=false
else begin
inc(B[i]);
for j:=i+1 to M do B[j]:=B[j-1]+1; PermuteAll(B,M);
end;
end;
readln; end.
Оператор exit предназначен для досрочного завершения процедуры или функции
Задача 6.
Написать программу, которая вводит с клавиатуры числа N, M и генерирует все возможные размещения из N букв по M.
Цикл предназначен для вывода в «треугольном» виде
Это сайт презентаций, где можно хранить и обмениваться своими презентациями, докладами, проектами, шаблонами в формате PowerPoint с другими пользователями. Мы помогаем школьникам, студентам, учителям, преподавателям хранить и обмениваться учебными материалами.
Email: Нажмите что бы посмотреть