如果有10个数字,0~9,那么它们两两组合的情况如下:Private Sub Form_Load()
Dim v
v = Split("0,1,2,3,4,5,6,7,8,9", ",")
Dim i%, j%
For i = 0 To UBound(v)
debug.Print getResult(v, i)
Next
End SubPrivate Function getResult(v, start As Integer) As String
Dim i%, s$
For i = start + 1 To UBound(v)
s = s & v(start) & "," & v(i) & vbTab
Next
getResult = s
End Function但是如果是10个数字0~9求它们的三个的组合数有什么好点的算法呢?(除了三层for循环的方法)
0,1,2
0,1,3
0,1,4
.
.
.
789
应该共有120组结果。ps:
v = Split("0,1,2,3,4,5,6,7,8,9", ",")只是为方便举例,可能是杂乱的无序的其他情况,例如:
v = Split("21,3,53,64,63,2,42,87,22,23,11,89,67,90,33,56", ",")
Dim v
v = Split("0,1,2,3,4,5,6,7,8,9", ",")
Dim i%, j%
For i = 0 To UBound(v)
debug.Print getResult(v, i)
Next
End SubPrivate Function getResult(v, start As Integer) As String
Dim i%, s$
For i = start + 1 To UBound(v)
s = s & v(start) & "," & v(i) & vbTab
Next
getResult = s
End Function但是如果是10个数字0~9求它们的三个的组合数有什么好点的算法呢?(除了三层for循环的方法)
0,1,2
0,1,3
0,1,4
.
.
.
789
应该共有120组结果。ps:
v = Split("0,1,2,3,4,5,6,7,8,9", ",")只是为方便举例,可能是杂乱的无序的其他情况,例如:
v = Split("21,3,53,64,63,2,42,87,22,23,11,89,67,90,33,56", ",")
解决方案 »
- 如何读取数据库表的个数,vb+ado
- 【非技术贴】成星的、成钻的、盼望成星成钻的,请把你们业余的软件作品在这里Show一下,让大家开开眼界。
- MM求助:关于用VB打包的问题~~
- 如何保存数据流文件?如何播放数据流文件?小女子泣血求救,送100分
- 日期显示不全!!
- 请问怎样将一个Enabled=False的TextBox控件中的字颜色(ForeColor属性)改变.谢谢
- 请问朋友们用什么软件做安装程序包
- 如何解开MHT文件中的图片,还有网页?
- 请教高手
- Private Sub Winsock_ConnectionRequest(ByVal requestID As Long)的问题
- sql用SUM后字段名变了?
- 急,急.... vb 添加注册表项
Private Sub Command1_Click()
Dim intMax%, intStart%
Dim i1%, i2%, i3%, c%
intStart = 0
intMax = 9
For i1 = intStart To intMax - 2
For i2 = i1 + 1 To intMax - 1
For i3 = i2 + 1 To intMax - 0
c = c + 1
Debug.Print i1 & "," & i2 & "," & i3
Next
Next
Next
Debug.Print "一共输出记录" & c & "条!"
End Sub这样太麻烦了,得定义三个变量,如果是7个组合数甚至更大呢,那就更麻烦了,这是不用多层循环嵌套的原因。
For i = 0 To 9
y = Format(i, "000")
DoEvents
Debug.Print x
Next i
End Sub
Dim buff() As String
Dim l As Integer '排列长度
Dim ss As VariantPublic Sub C排列()
Dim s As Variant, i As Long, t As Long
j = 1 'buff()位置
l = 3 '排列长度=3
ss = Split("0,1,2,3,4,5,6,7,8,9", ",")
ReDim buff(1 To 120)
Make_CString UBound(ss), ""
End SubPrivate Sub Make_CString(ByVal n As Long, ByVal ls As String)
Dim t As String
For i = n To 0 Step -1
t = ls & ss(i)
If Len(t) = l Then
buff(j) = t
j = j + 1
Else
Make_CString i - 1, t
End If
Next i
End Sub
楼上的代码貌似用的递归,很久以前见到过谁用这这样方法实现排列组合,不知道数据量太大时会不会堆栈溢出,我仔细研究研究。
Dim l As Integer '长度
Dim ss As VariantPublic Sub C组合()
Dim s As Variant, i As Long, t As Long
l = 6 '长度=3
ss = Split("21,3,53,64,63,2,42,87,22,23,11,89,67,90,33,56", ",")
Make_CString UBound(ss), ""
End SubPrivate Sub Make_CString(ByVal n As Long, ByVal ls As String)
Dim t$, i&
For i = n To 0 Step -1
t = ls & ss(i) & ","
If UBound(Split(t, ",")) = l Then
Debug.Print t
Else
Make_CString i - 1, t
End If
Next
End Sub
再放段时间,看看有没有其他好办法了。建议大家写代码尽量显式声明,有时因为没有要求强制变量声明会带入很多隐藏的bug,即使发现bug也会很难定位错误。
非递归,以前写的,优化过的代码没找着,算是提供一个排列和组合算法的思路吧....
要按我的看法,最好都不要用vb6来写,用c做最好,效率提高不是一点点...
以前搜索到许多很有思想的算法,本来有心好好研究一下,后来太忙也就放下了,工作中也几乎没有相应的应用,现在也好象没什么兴致了...
仅供参考#include <stdio.h>
#include <stdlib.h>
#define MAX_NUM 26
int comb[MAX_NUM];
int c1,c2;
void combination(int m, int n)
{
int i, j;
for (i = m; i >= n; i--){
comb[n] = i; /* 选择当前的“头”元素 */
if (n > 1){
/* 进入下一次更小的组合问题 */
combination(i - 1, n - 1);
}else{
/* 满了需要的组合数,输出 */
for (j = comb[0]; j > 0; j--){
printf("%c", 65+c1-comb[j]);
}
printf("\n");
}
}
return;
}
int main(int argc, char *argv[])
{
if (argc<3) {
printf("%s 组合下标 组合上标\n",argv[0]);
return 0;
}
c1=atoi(argv[1]);
if (c1<1||26<c1) {
printf("1<=组合下标<=26\n");
return 0;
}
c2=atoi(argv[2]);
if (c2<1||c1<c2) {
printf("1<=组合上标<=组合下标\n");
return 0;
}
comb[0]=c2;
combination(c1, c2); /* C(4, 2) */
return 0;
}#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int m;//记录字符串长度
int n;//记录字符串中的字符种类数
char map[256];//记录是哪几种字符
int count[256];//记录每种字符有多少个
int stack[1000];//递归用的栈,并记录当前生成的排列
void Make_Map(char *str) {//统计字符串的相关信息
int s[256];
int i;
memset(s,0,sizeof(s));
memset(count,0,sizeof(count));
m=strlen(str);
while(*str) {
s[*str]++;
str++;
}
n=0;
for (i=0;i<256;i++)
if (s[i]) {
map[n]=i;
count[n]=s[i];
n++;
}
}
void Find(int depth) {//递归式回溯法生成全排列
if (depth==m) {
int i;
for (i=0;i<depth;i++) putchar(map[stack[i]]);
putchar('\n');
} else {
int i;
for (i=0;i<n;i++)
if (count[i]) {
stack[depth]=i;
count[i]--;
Find(depth+1);
count[i]++;
}
}
}
void main(int argc,char**argv) {
if (argc<2) {
printf("%s 要产生全排列的字符串\n",argv[0]);
return;
}
Make_Map(argv[1]);
Find(0);
}
你可以先把0-9 10个数的所有3位组合数记录在一个txt里
然后用的时候直接把10个数放进数组(0-9)里,然后读txt按规则全部转换成你的10个数,就行了