如果有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", ",")

解决方案 »

  1.   

    三层for循环是这样的:
    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个组合数甚至更大呢,那就更麻烦了,这是不用多层循环嵌套的原因。
      

  2.   

    是的,我和你一样,甚至对于createobject能用with我都用with的。可是上面的这种算法要定义3个变量(循环计数器)就是万不得已。正在寻找另外的算法,呼叫vbman等各路高手
      

  3.   

    Private Sub Command1_Click()
        For i = 0 To 9
            y = Format(i, "000")
            DoEvents
            Debug.Print x
        Next i
    End Sub
      

  4.   

    我以前编的一段排列组合字符的程序,只要改变 l 的长度,即可按不通长度组合。Dim j As Long
    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
      

  5.   

    晕,原来你的意思是不用声明,是我说的有点偏差,我意思是不想用那么多变量,如果单单dim那么根本没有多少工作量,主要是for,加入100选50的话,那么得写50个for嵌套语句,也就是必须要用到50个变量(循环计数器),主要是50行for语句不现实。
    楼上的代码貌似用的递归,很久以前见到过谁用这这样方法实现排列组合,不知道数据量太大时会不会堆栈溢出,我仔细研究研究。
      

  6.   

    不错,速度还是挺快的,我稍修改了下使得对于不是单个字符的数组也同样适用。
    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也会很难定位错误。
      

  7.   

    http://blog.csdn.net/vbman2003/archive/2008/04/16/2296394.aspx
    非递归,以前写的,优化过的代码没找着,算是提供一个排列和组合算法的思路吧....
      

  8.   

    排列组合这种算法,效率应该是第一位的,不然某些时候会要死人的,呵呵...
    要按我的看法,最好都不要用vb6来写,用c做最好,效率提高不是一点点...
    以前搜索到许多很有思想的算法,本来有心好好研究一下,后来太忙也就放下了,工作中也几乎没有相应的应用,现在也好象没什么兴致了...
      

  9.   

    VB6也可以递归
    仅供参考#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);
    }
      

  10.   

    用什么递归啊,如果只是3位组合数,一共就10*9*8 = 720组合而已
    你可以先把0-9  10个数的所有3位组合数记录在一个txt里
    然后用的时候直接把10个数放进数组(0-9)里,然后读txt按规则全部转换成你的10个数,就行了