考試大計算機等級站整理:
有從10個不同的數(shù)中取出7個,如何求出所有組合?
初看這個問題,確實不太好下手,雖然我們理解這個問題很容易,但要讓計算機“理解”可得花點功夫了。
先分析:首先想到,如果由10個元素中的7個組成一個序列,并且這7個元素互不相等,這就比較接近于正解了;然后考慮,組合中7元素是不分先后的,我們?nèi)绾翁蕹嘤嗟臄?shù)據(jù)呢(如四選二中(1,3)與(3,1)是相同解)?
我們可以在編程時作一種限定,7個元素的排列順序滿足我們的一個規(guī)定,這樣,就可以依據(jù)相同位置的值不能相同來排除不正確的解。
這樣我們的第一個解呼之欲出了:可以利用數(shù)組來進行選取,不同的數(shù)組下標順序就代表了不同的解,而且我們約定這個下標序列必須是升序,這就利于我們排除冗余值。
在本文中,約定這10個數(shù)是如下形式的數(shù)組,并且已經(jīng)賦值。計算的結果在一個TMemo控件中顯示。
var
Value:array[1..10] of integer;
解法一、
按鈕1的點擊事件處理。
procedure TForm1.Button1Click(Sender: TObject);
var
idx1,idx2,idx3,idx4,idx5,idx6,idx7: integer;
tmpStr:string;
begin
Memo1.Lines.Clear;
for idx1:=1 to 4 do
for idx2:=idx1+1 to 5 do
for idx3:=idx2+1 to 6 do
for idx4:=idx3+1 to 7 do
for idx5:=idx4+1 to 8 do
for idx6:=idx5+1 to 9 do
for idx7:=idx6+1 to 10 do
begin
tmpStr:=IntToStr(idx1)+' '+IntToStr(idx2)+' '+IntToStr(idx3)
+' '+IntToStr(idx4)+' '+IntToStr(idx5)+' '+IntToStr(idx6)
+' '+IntToStr(idx7) ;
Memo1.Lines.Add(tmpStr);
end;
end;
解中只顯示了下標的組合,實際應用把下標改為Value數(shù)組即可:tmpStr:=IntToStr(Value[idx1])+' '+IntToStr(Value[idx2])+...; 。
這個解的一個亮點就是每一個循環(huán)變量的初值都是它前一個變量加1;這就保證后一個下標一定不等于前一個下標,請體會一下為什么循環(huán)控制變量的終值為4~10。
解法二、
中學的數(shù)學教材中就講到C(10,7)=C(10,3),這個很好理解,從10中選7,剩下3個,所有選七的組合完成,也就是所有選三的組合完成,反之亦然。
按鈕2的點擊事件處理:
procedure TForm1.Button2Click(Sender: TObject);
var
idx1,idx2,idx3,idx4: integer;
tmpStr:string;
begin
Memo1.Lines.Clear;
for idx1:=1 to 8 do
for idx2:=idx1+1 to 9 do
for idx3:=idx2+1 to 10 do
begin
tmpStr:='';
for idx4:=1 to 10 do
if (idx4<>idx1) and (idx4<>idx2) and (idx4<>idx3) // 加入一個元素
then tmpStr:=tmpStr+IntToStr(Value[idx4])+' ';
Memo1.Lines.Add(tmpStr);
end;
end;
這個解是十選三,然后顯示剩下的七個,是不是有點意思呢?
以上加入元素的判斷可以改寫為:
if ((idx1+100)*(idx2+100)*(idx3+100) mod (idx4+100) >0 )
請體會一下同余理論的運用,這里利用了101到110這十個數(shù)中任一個數(shù)都不被其它三個數(shù)的乘積整除的特性。
有從10個不同的數(shù)中取出7個,如何求出所有組合?
初看這個問題,確實不太好下手,雖然我們理解這個問題很容易,但要讓計算機“理解”可得花點功夫了。
先分析:首先想到,如果由10個元素中的7個組成一個序列,并且這7個元素互不相等,這就比較接近于正解了;然后考慮,組合中7元素是不分先后的,我們?nèi)绾翁蕹嘤嗟臄?shù)據(jù)呢(如四選二中(1,3)與(3,1)是相同解)?
我們可以在編程時作一種限定,7個元素的排列順序滿足我們的一個規(guī)定,這樣,就可以依據(jù)相同位置的值不能相同來排除不正確的解。
這樣我們的第一個解呼之欲出了:可以利用數(shù)組來進行選取,不同的數(shù)組下標順序就代表了不同的解,而且我們約定這個下標序列必須是升序,這就利于我們排除冗余值。
在本文中,約定這10個數(shù)是如下形式的數(shù)組,并且已經(jīng)賦值。計算的結果在一個TMemo控件中顯示。
var
Value:array[1..10] of integer;
解法一、
按鈕1的點擊事件處理。
procedure TForm1.Button1Click(Sender: TObject);
var
idx1,idx2,idx3,idx4,idx5,idx6,idx7: integer;
tmpStr:string;
begin
Memo1.Lines.Clear;
for idx1:=1 to 4 do
for idx2:=idx1+1 to 5 do
for idx3:=idx2+1 to 6 do
for idx4:=idx3+1 to 7 do
for idx5:=idx4+1 to 8 do
for idx6:=idx5+1 to 9 do
for idx7:=idx6+1 to 10 do
begin
tmpStr:=IntToStr(idx1)+' '+IntToStr(idx2)+' '+IntToStr(idx3)
+' '+IntToStr(idx4)+' '+IntToStr(idx5)+' '+IntToStr(idx6)
+' '+IntToStr(idx7) ;
Memo1.Lines.Add(tmpStr);
end;
end;
解中只顯示了下標的組合,實際應用把下標改為Value數(shù)組即可:tmpStr:=IntToStr(Value[idx1])+' '+IntToStr(Value[idx2])+...; 。
這個解的一個亮點就是每一個循環(huán)變量的初值都是它前一個變量加1;這就保證后一個下標一定不等于前一個下標,請體會一下為什么循環(huán)控制變量的終值為4~10。
解法二、
中學的數(shù)學教材中就講到C(10,7)=C(10,3),這個很好理解,從10中選7,剩下3個,所有選七的組合完成,也就是所有選三的組合完成,反之亦然。
按鈕2的點擊事件處理:
procedure TForm1.Button2Click(Sender: TObject);
var
idx1,idx2,idx3,idx4: integer;
tmpStr:string;
begin
Memo1.Lines.Clear;
for idx1:=1 to 8 do
for idx2:=idx1+1 to 9 do
for idx3:=idx2+1 to 10 do
begin
tmpStr:='';
for idx4:=1 to 10 do
if (idx4<>idx1) and (idx4<>idx2) and (idx4<>idx3) // 加入一個元素
then tmpStr:=tmpStr+IntToStr(Value[idx4])+' ';
Memo1.Lines.Add(tmpStr);
end;
end;
這個解是十選三,然后顯示剩下的七個,是不是有點意思呢?
以上加入元素的判斷可以改寫為:
if ((idx1+100)*(idx2+100)*(idx3+100) mod (idx4+100) >0 )
請體會一下同余理論的運用,這里利用了101到110這十個數(shù)中任一個數(shù)都不被其它三個數(shù)的乘積整除的特性。