字典序dict.pas
【问题描述】
输入文件中包含几行数据,每行又包含多个正整数。你的任务把这些数据(每行数据看作一个整体)按字典序进行排序。这里的字典序是指,先按每行最左边的数进行排序,若有相同的则比较它们的第二个数,以些类推只到比较出大小。例如下面的数据:
14 38 11 89
27 34
27 12 34
27
92 2 3 1
17 2
按此字典排序后的结果为:
14 38 11 89
17 2
27
27 12 34
27 34
92 2 3 1
【输入格式】dict.in
输入的第一行是一个整数N(1<=N<=10000),表示总共有N行数据要进行排序。
以下N行,每行包括Mi(1<=Mi<=50)个数,最好一个数以-1结束,该数不记入到该行数中。
【输出格式】dict.out
按字典序输出数据,共N行。
【样例输入】
6
14 38 11 89 -1
27 34 -1
27 12 34 -1
27 -1
92 2 3 1 -1
17 2 -1
Readln(str1)
Readln(str2);
【样例输出】
14 38 11 89
17 2
27
27 12 34
27 34
92 2 3 1
【问题分析】
本题就是要求我们按字典排序的方式把多行多个数进行排序,称之为多关键字排序。本题的关键点有:
(1)读入数据的处理
由于每行数的个数不一样,以-1为结束,所以读入处理为:
For I := 1 to n do begin
Read(x); j := 0;
While x >=0 do begin
Inc(j);
A[I, j] := x;
Read(x);
End;
A[I, 0] := j; //记录每行有几个数
Readln;
End;
(2)排序中多关键字的处理
把每一行当作一个整体来处理,即定义两个变量x,m都是数组:
Procedure qsort(L, R : longint);
Var
I, j : longint;
X, m :Arr;
Begin
I := L; j := R; m := a[(I + j) shr 1];
Repeat
While check(a[i],m) do inc(i);
While check(m, a[j]) do dec(j);
……
Until I > j;
……
End;
这里定义了一个检查函数,用来判断两个数字按字典序的大小关系。
Function check(x, y : Arr) : boolean;
Var
I : longint;
Mark : Boolean;
Begin
Mark := false;
For I := 1 to 50 do
//由于每行的元素的个数最多为50个,可以事先把把个数字的值都填充为0
If x[i] < y[i] then begin mark := true; break;end
Else x[i] > y[i] then break;
Check := mark;
End;
(3)输出数据的处理
由于在读入时记录了每行数的个数,在输出的时候就容易处理了。
For I := 1 to n do begin
For j := 1 to a[I, 0] do write(a[I, j], ‘ ‘); writeln;
End;
关于主程序中的定义部分为:
Const maxN = 10000;
Type
Arr = array[0..50] of longint;
Var
A : array[1..maxN] of Arr;
N, I, j, x : longint;