All right, here is a solution. The code is kind of long, so please simplify it by all means.
The basic ideas is to generate 2 sets containing all the combinations of 5 (a5 126 Obs) and 6 (a6 84 Obs) numbers, then for each of the observation in a5, compare it to each observation in a6 to see if the first is part of the latter.
Here are the codes:
/*Create set containing all combinations of 6 numbers, it contains 84 observations*/
data a6 (keep=d1-d6 Nbr);
array hm[9] (1 2 3 4 5 6 7 8 9 );
Nbr=0;
do i1=1 to 9; d1=hm{i1};
do i2=i1+1 to 9; d2=hm{i2};
do i3=i2+1 to 9; d3=hm{i3};
do i4=i3+1 to 9; d4=hm{i4};
do i5=i4+1 to 9; d5=hm{i5};
do i6=i5+1 to 9; d6=hm{i6};
nbr+1;
output; end; end; end; end; end; end; run;
/*Create set containing all combinations of 5 numbers, it contains 126 observations*/
data a5 (keep=d1-d5);
array hm[9] (1 2 3 4 5 6 7 8 9 );
do i1=1 to 9; d1=hm{i1};
do i2=i1+1 to 9; d2=hm{i2};
do i3=i2+1 to 9; d3=hm{i3};
do i4=i3+1 to 9; d4=hm{i4};
do i5=i4+1 to 9; d5=hm{i5};
output; end; end; end; end; end; run;
/*Transpose a6, so each number is in a single column, so that it is easies to be put in a macro later */
proc transpose data=a6 out=a6t(drop=_name_);
run;
/*Create a table for future use, it contains the five digits and in what order number it would be in the 6 number
combinations*/
proc sql;
create table results
(d1 num, d2 num,d3 num, d4 num,d5 num,d5 num, Nbr num);
quit;
%macro AllResults;
%do i=1 %to 84;
/*For each of the 6 digit number, we want to change it in a set form, say 123456 in the form of
(1,2,3,4,5,6), we achieve that by using macro, that's why we did transpose earlier
*/
proc sql noprint;
select col&i into:compare separated by ','
from a6t
;
quit;
%put &compare;
/*Pick each of the number in a5 and compare it with &compare, e.g. for 12345
we want to see if 1 we have all this 1 in (1,2,3,4,5,6), 2 in (1,2,3,4,5,6), 3 in (1,2,3,4,5,6),
4 in (1,2,3,4,5,6) and 5 in (1,2,3,4,5,6), if it does we mark in which number it is and output the result
*/
data temp(keep=d1-d5 nbr);
set a5;
if d1 in (&compare) and d2 in (&compare) and d3 in (&compare) and d4 in (&compare) and d5 in (&compare) then
do;
nbr=&i;
output;
end;
run;
/*Export the reult to set results, so we can move on to the next number in a6*/
proc sql;
insert into results
select *
from temp;
quit;
%end;
/*delete the temp set*/
proc sql;
drop table temp;
quit;
%mend;
%AllResults
/*Now we have all the senarios, e.g., for each 6 digit number what combination of 5 digit numbers it contains
but we want the story from another view, i.e. for each of the 5 digit number in what 6 digit number it is in, so we
sort by the 5 digits
*/
proc sort data=results;
by d1-d5;
run;
/*Now we know more, for example, we know 12345 is contained in the first four numbers of a6: 1 2 3 4, in this case
we only want to keep the first one*/
data results126;
set results;
by d1-d5;
if first.d5;
run;
/*Now we see that we caught all the 126 different cases, at the same time we know that some of the 6 digit numbers are used
more than once*/
proc sort data=results126 ;
by nbr;
run;
/*Following code ensures that we use each 6 digit number once*/
data final(keep=nbr);
set results126;
by nbr;
if first.nbr;
run;
/*In case we want to know what they are...*/
data Used;
merge a6 final(in=in);
by nbr;
if in;
run;
[此贴子已经被作者于2009-5-19 1:27:44编辑过]