输出自然数1到n所有不重复的排列,即n的全排列。 【参考过程】

 procedure Search(I:integer);
  var j:integer;
  begin
    for j:=1 to n do
      if b[j] then
      begin
         a[i]:=j;  b[j]:=false;
         if I<n then Search(I+1)
               else print;
         b[j]=true;
      end;
  end;
const
max=100;
var
i,n:integer;
s:set of 1..max;
a:array[1..9] of 1..9;
//输出过程
procedure print;
begin
    for i:=1 to n do write(a[i]:2);
    writeln;
end;
//回溯过程
procedure search(x:integer);
var c:integer;
begin
for c:=1 to n do
    begin
    if c in s then
        begin
        a[x]:=c;
        s:=s-[c];
        if x=n then print
            else search(x+1);
        s:=s+[c];
        end;
    end;
end;
{
其选择思想:一个数选定后,在一组数(集合)中去除该数,下一位仍然从1开始循环
如果循环的数不在集合内,则跳过,如果在,则选中并进行下一个数的选择。

回溯思想:
首先从1开始排列,规定的n个数字当中先取出已经排列的数,
然后进行下一位数的选择,直到第n个数选择完。
之后退位,到第n-1个数继续选择,以次类推。
因为每次每个位数上的循环都是从1开始,因而数字会呈现出递增趋势,
即第一个必然是从大到小排列,之后较大数和较小数对调。
}

//主函数
BEGIN
readln(n);
s:=[1..n];
search(1);
readln;
END.

找出n个自然数(1,2,3,…,n)中r个数的组合。例如,当n=5,r=3时,所有组合为: 1  2  3 1  2  4 1  2  5 1  3  4 1  3  5 1  4  5 2  3  4 2  3  5 2  4  5 3  4  5 total=10           //组合的总数 【分析】:设在b[1],b[2],…,b[i-1]中已固定地取了某一组值且b[i-1]=k的前提下,过程Search(i,k)能够列出所有可能的组合。由于此时b[i]只能取k+1至n-r+i,对j=k+1,k+2,…,n-r+i,使b[i]:=j,再调用过程Search(i+1,j),形成递归调用。直至i的值大于r时,就可以在b中构成一种组合并输出。

const
max=100;
var
a:array[1..max] of 1..max;
b:array[1..max] of 1..max;
i,count,r,n:integer;

procedure print;
var x:integer;
begin
count:=count+1;
for x:=1 to r do write(b[x]);
writeln;
end;

procedure search(i:integer);
var x:integer;
begin
if i=1 then
    begin
    for x:=i to n-r+i do
        begin
        b[i]:=a[x];
        if i=r then print
            else search(i+1);
        end;
    end
//除了第一位外,把所寻找的位的起始数改为上一位数+1
    else
        begin
        for x:=b[i-1]+1 to n-r+i do
            begin
            b[i]:=a[x];
            if i=r then print
                else search(i+1);
            end;
        end;
end;



BEGIN
count:=0;
write('Enter sum number: ');
readln(n);
write('Enter r munber: ');
readln(r);
for i:=1 to n do a[i]:=i;
search(1);
writeln('total=',count);
readln;
END.

输出字母a、b、c、d,4个元素全排列的每一种排列。

var
s:set of 'a'..'d';
a:array[1..4] of 'a'..'d';
procedure print;
var i:integer;
begin
for i:=1 to 4 do write(a[i]);
writeln;
end;

procedure search(i:integer);
var x:char;
begin
for x:='a' to 'd' do
    begin
    if x in s then
        begin
        a[i]:=x;
        s:=s-[x];
        if i=4 then print
            else search(i+1);
        s:=s+[x];
        end;
    end;
end;

BEGIN
s:=['a'..'d'];
search(1);
readln;
END.

显示从前m个大写英文字母中取n个不同字母的所有种排列。

var
s:set of 'A'..'Z';
a:array[1..26] of 'A'..'Z';
c:char;
m,n:integer;
//
procedure print;
var i:integer;
begin
for i:=1 to 4 do write(a[i]);
writeln;
end;
//
procedure search(i:integer);
var x:char;
begin
for x:='A' to c do
    begin
    if x in s then
        begin
        a[i]:=x;
        s:=s-[x];
        if i=n then print
            else search(i+1);
        s:=s+[x];
        end;
    end;
end;

BEGIN
write('Enter Max Number: ');
readln(m);
c:=chr(m+64);
write('Enter Target Number: ');
readln(n);
s:=['A'..c];
search(1);
readln;
END.

全排列问题(Form.pas) 【问题描述】 输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字。 【输入格式】 n(1≤n≤9) 【输出格式】 由1~n组成的所有不重复的数字序列,每行一个序列。 【输入样例】Form.in 3 【输出样例】Form.out 1  2  3 1  3  2 2  1  3 2  3  1 3  1  2 3  2  1

var
i,n:integer;
s:set of 1..9;
a:array[1..9] of 1..9;
//输出过程
procedure print;
begin
    for i:=1 to n do write(a[i]:2);
    writeln;
end;
//回溯过程
procedure search(x:integer);
var c:integer;
begin
for c:=1 to n do
    begin
    if c in s then
        begin
        a[x]:=c;
        s:=s-[c];
        if x=n then print
            else search(x+1);
        s:=s+[c];
        end;
    end;
end;
{
其选择思想:一个数选定后,在一组数(集合)中去除该数,下一位仍然从1开始循环
如果循环的数不在集合内,则跳过,如果在,则选中并进行下一个数的选择。

回溯思想:
首先从1开始排列,规定的n个数字当中先取出已经排列的数,
然后进行下一位数的选择,直到第n个数选择完。
之后退位,到第n-1个数继续选择,以次类推。
因为每次每个位数上的循环都是从1开始,因而数字会呈现出递增趋势,
即第一个必然是从大到小排列,之后较大数和较小数对调。
}

//主函数
BEGIN
assign(input,'Form.in');
assign(output,'Form.out');
rewrite(output);
reset(input);
readln(n);
s:=[1..n];
search(1);
readln;
close(input);
close(output);
END.

组合的输出(Compages.pas) 【问题描述】 排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r<=n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。 现要求你用递归的方法输出所有组合。 例如n=5,r=3,所有组合为: l 2 3   l 2 4   1 2 5   l 3 4   l 3 5   1 4 5   2 3 4   2 3 5   2 4 5   3 4 5 【输入】 一行两个自然数n、r(1<n<21,1<=r<=n)。 【输出】 所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。 【样例】 compages.in        compages.out 5   3                1 2 3          1 2 4          1 2 5          1 3 4          1 3 5          1 4 5          2 3 4          2 3 5          2 4 5          3 4 5

const
max=100;
var
a:array[1..max] of 1..max;
b:array[1..max] of 1..max;
i,r,n:integer;

procedure print;
var x:integer;
begin
for x:=1 to r do write(b[x]);
writeln;
end;

procedure search(i:integer);
var x:integer;
begin
if i=1 then
    begin
    for x:=i to n-r+i do
        begin
        b[i]:=a[x];
        if i=r then print
            else search(i+1);
        end;
    end
    else
        begin
        for x:=b[i-1]+1 to n-r+i do
            begin
            b[i]:=a[x];
            if i=r then print
                else search(i+1);
            end;
        end;
end;



BEGIN
assign(input,'compages.in');
assign(output,'compages.out');
reset(input);
rewrite(output);
read(n);
read(r);
for i:=1 to n do a[i]:=i;
search(1);
close(input);
close(output);
END.

Pascal:搜索回溯算法,习题
https://Mundnaity.moe/post/pascal_chap_A5_ex
作者
申酉和风
发布于
2016-11-07
许可协议