7重循环不就完事了吗
for i1:=1 to 25 do
for i2:=i1+1 to 26 do
for i3:=i2+1 to 27 do
for i4:=i3+1 to 28 do
for i5:=i4+1 to 29 do
for i6:=i5+1 to 30 do
for i7:=i6+1 to 31 do
还是没搞清楚
for i1:=1 to 25 do
for i2:=i1+1 to 26 do
for i3:=i2+1 to 27 do
for i4:=i3+1 to 28 do
for i5:=i4+1 to 29 do
for i6:=i5+1 to 30 do
for i7:=i6+1 to 31 do
还是没搞清楚
比如:a,b,c,d,e,d 中每次取3个的所有排列数(顺序有关)、所有组合(顺序无关)数;
你只是把所有的情况罗列出来而已,没有给出具体情况的算法
者也是我请教各位的地方
这样判断的速度太慢了,你再想一想吧,算法越快越好
begin
for i2 := i1 + 1 to 26 do
begin
for i3 := i2 + 1 to 27 do
begin
for i4 := i3 + 1 to 28 do
begin
if (i4 - i1 = 3) then continue; // 4数相邻,跳过
for i5 := i4 + 1 to 29 do
begin
if (i5 - i2 = 3) then continue; // 4数相邻,跳过
for i6 := i5 + 1 to 30 do
begin
if (i6 - i3 = 3) then continue; // 4数相邻,跳过
for i7 := i6 + 1 to 31 do
begin
if (i7 - i4 = 3) then continue; // 4数相邻,跳过
if i3-i1<>2 then
if i4-i2<>2 then
if i5-i3<>2 then
if i6-i4<>2 then
if i7-i5<>2 then break;
输出i1~i7
end;
end;
end;
end;
end;
end;
end;
谢谢,你的算法和我的算法不一样,我试一试你的算法先,在下不胜感激。我用listbox可以分段显示。
123
124
125
126234
235
236345
346456当最低位为m(也既6)时,回溯。
126-》234
236-》345
346-》456由此,只要用一个向量(数组)存放要回溯的数即可。
最初,为123,每回溯一次,各个数都加一。当最高位为
m-n+1(4)时,结束。亦用递归实现。
当m,n变化时,当然不能用循环,宜用递归。但当m,n固定时,或都比较小时,可以用循环。
用递归的效率不会比循环的好。
ConstToNum=10
ConstGetNum=4
ConstGetSame=2
PrivateSubForm_Load()
Dims(0ToGetNum-1)AsLong
Text1=""
GetNumsToNum,GetNum,GetSame,s
EndSub
SubGetNums(yAsLong,ByRefmAsLong,ByRefnAsLong,s()AsLong)
Ify-n>0ThenGet11,y-n+1,m-n+1,m,n,s
EndSub
SubGet1(xAsLong,ByRefyAsLong,zAsLong,ByRefmAsLong,ByRefnAsLong,s()AsLong)
Ifz=0ThenGet2s,m,n:ExitSub
DimiAsLong
Fori=xToy-2*z+2
s(z-1)=i
Get1i+2,y,z-1,m,n,s
Next
EndSub
SubGet2(s()AsLong,ByRefmAsLong,ByRefnAsLong)
DimiAsLong,jAsLong,kAsLong
Fori=0Tom-n
Forj=0Tom-n
Ifi<jThen
MyPrints(j)&vbTab
ElseIfi=jThen
Fork=n-1To0Step-1
MyPrints(j)+k&vbTab
Next
Else'Ifi>jThen
MyPrints(j)+n-1&vbTab
EndIf
Next
MyPrintvbCrLf
Next
EndSub
SubMyPrint(sAsString)
Text1=Text1+s
EndSub'为了程序好看,我在Get1中用了递归。若x、y、z确定,用多重循环来写,一定可以快许多。
SubGet1x(s()AsLong)
Dimi1AsLong,i2AsLong,i3AsLong
Fori1=1To5
s(2)=i1
Fori2=i1+2To7
s(1)=i2
Fori3=i2+2To9
s(0)=i3
Get2s,4,2
Nexti3,i2,i1
EndSub
好算法! 我的问题在加分
不错呀,我给你们加分
看了一下你的程序,递归算法挺难看懂的,basic又不熟,思路是不是这样的:
m个数n个连续,先构造m-n+1个不连续的数(在数组s中),再依次使每个数成为n个连续,并把比这个数大的数上移n个位置。(我没理解错吧)
但你这样做,无法找到,类似(1,2,4,5)这样的组合,或者(1,2,3,5,6)-5数3连续这样的组合。
还能改进吗?
我弄了一个算10(1...10中),4(取出个数),2(相同)的。有点烂, 速度应该还行Sub Get1x(s() As Long)
Dim i1 As Long, i2 As Long, i3 As Long
For i1 = 1 To 5
s(2) = i1
For i2 = i1 + 2 To 7
s(1) = i2
For i3 = i2 + 2 To 9
s(0) = i3
Get2x s, 1
Next i3, i2, i1
i1 = -1
For i2 = i1 + 2 To 6
s(1) = i2
For i3 = i2 + 2 To 8
s(0) = i3
Get2x s, 2
Next i3, i2
End SubSub Get2x(s() As Long, ByRef d As Long)
Dim i1 As Long, i2 As Long
Dim j As Long, k As Long
Select Case d
Case 1
For i1 = 0 To 2
For j = 0 To 2
If i1 < j Then
MyPrint s(j) & vbTab
ElseIf i1 = j Then
For k = 1 To 0 Step -1
MyPrint s(j) + k & vbTab
Next
Else 'If i1 > j Then
MyPrint s(j) + 1 & vbTab
End If
Next
MyPrint vbCrLf
Next
Case 2
For i1 = 0 To 0: For i2 = i1 + 1 To 1
For j = 0 To 1
If i2 < j Then
MyPrint s(j) & vbTab
ElseIf i2 = j Then
For k = 1 To 0 Step -1
MyPrint s(j) + k & vbTab
Next
ElseIf i1 < j Then
MyPrint s(j) + 1 & vbTab
ElseIf i1 = j Then
For k = 1 To 0 Step -1
MyPrint s(j) + 1 + k & vbTab
Next
Else 'If i1 > j Then
MyPrint s(j) + 2 & vbTab
End If
Next
MyPrint vbCrLf
Next i2, i1
End Select
End Sub
提个建议:要做就做通用的,用递归;若是m,n指定的情况,不如m重循环,既简单,速度又快。
#define TONUM 10
#define GETNUM 6
#define GETSAME 3
#if GETNUM - GETSAME + 1 > 6 //make error
FILE *fp;
#endif
#if GETNUM / GETSAME > 3 //make error
FILE *fp;
#endifint im[4][7], i6m[4];
int in[4][4];FILE *fp;void MyPrint(int s)
{
fprintf(fp, "%d\t", s);
printf("%d\t", s);
}void MyPrint(char* s)
{
fprintf(fp, "%s", s);
printf("%s", s);
}void Get2x(int *s, int d)
{
int i1, i2, i3, j, k;
switch (d)
{
case 1:
for (i1 = 0; i1 <= in[1][1]; i1++)
{
for (j = 0; j <= in[1][1]; j++)
if (i1 < j)
MyPrint (s[j]);
else if (i1 == j)
for (k = GETSAME - 1; k + 1; k--)
MyPrint (s[j] + k);
else //if (i1 > j)
MyPrint (s[j] + GETSAME - 1);
MyPrint ("\r\n");
}
break;
case 2:
for (i2 = 0; i2 <= in[2][2]; i2++)
for (i1 = i2 + 1; i1 <= in[2][1]; i1++)
{
for (j = 0; j <= in[2][1]; j++)
if (i1 < j)
MyPrint (s[j]);
else if (i1 == j)
for (k = GETSAME - 1; k + 1; k--)
MyPrint (s[j] + k);
else if (i2 < j)
MyPrint (s[j] + GETSAME - 1);
else if (i2 == j)
for (k = GETSAME - 1; k + 1; k--)
MyPrint (s[j] + k + GETSAME - 1);
else
MyPrint (s[j] + (GETSAME - 1) * 2);
MyPrint ("\r\n");
}
break;
case 3:
for (i3 = 0; i3 <= in[3][3]; i3++)
for (i2 = i3 + 1; i2 <= in[3][2]; i2++)
for (i1 = i2 + 1; i1 <= in[3][1]; i1++)
{
for (j = 0; j <= in[3][1]; j++)
if (i1 < j)
MyPrint (s[j]);
else if (i1 == j)
for (k = GETSAME - 1; k + 1; k--)
MyPrint (s[j] + k);
else if (i2 < j)
MyPrint (s[j] + GETSAME - 1);
else if (i2 == j)
for (k = GETSAME - 1; k + 1; k--)
MyPrint (s[j] + k + GETSAME - 1);
else if (i3 < j)
MyPrint (s[j] + (GETSAME - 1) * 2);
else if (i3 == j)
for (k = GETSAME - 1; k + 1; k--)
MyPrint (s[j] + k + (GETSAME - 1) * 2);
else
MyPrint (s[j] + (GETSAME - 1) * 3);
MyPrint ("\r\n");
}
}
}inline void Get1xCall(int *s, int d)
{
int i1, i2, i3, i4, i5, i6;
for (i6 = i6m[d]; i6 <= im[d][6]; i6++)
{
s[5] = i6;
for (i5 = i6 + 2; i5 <= im[d][5]; i5++)
{
s[4] = i5;
for (i4 = i5 + 2; i4 <= im[d][4]; i4++)
{
s[3] = i4;
for (i3 = i4 + 2; i3 <= im[d][3]; i3++)
{
s[2] = i3;
for (i2 = i3 + 2; i2 <= im[d][2]; i2++)
{
s[1] = i2;
for (i1 = i2 + 2; i1 <= im[d][1]; i1++)
{
s[0] = i1;
Get2x (s, d);
}
}
}
}
}
}
}void Get1x(int *s)
{
int i;
for (i = 1; i <= GETNUM / GETSAME; i++)
{
Get1xCall(s , i);
}
}int main(int argc, char* argv[])
{
int s[6];
int i, j;
for (i = 1; i <= GETNUM / GETSAME; i++)
{
im[i][1] = TONUM - (GETSAME - 1) * i;
for (j = 2; j <= 6; j++)
if (j > GETNUM - (GETSAME - 1) * i)
im[i][j] = 1 + (-j + GETNUM - (GETSAME - 1) * i) * 2;
else
im[i][j] = im[i][j - 1] - 2;
i6m[i] = (im[i][6] <= 0)? im[i][6]: 1;
for (j = 1; j <= i; j++)
in[i][j] = GETNUM - (GETSAME - 1) * i - j;
}
printf("Hello World!\n");
fp = fopen( "e:\\fprintf.txt", "w" );
Get1x(s);
fclose(fp);
return 0;
}