不限单词数的完全组合函数

问题的提出和使用要素

近期一直使用VBA写程序,很多数据比对的地方需要把N个单词进行完全乱序的自由组合。用了很多循环之类的算法,但那都是在组合单词数已知的情况下进行,而且代码冗长又繁琐。
于是,在摸索了很久之后,终于想出了利用字典和递归算法的结合,写出了不受单词数限制的自由组合函数。

太兴奋了,忍不住发个博,跟大家分享。

备注(这是重点):

这个函数是在VBA里写的,但这不重要。
1、字典对象在现在的很多语言系统里都有,用法基本相同(参考的C#),就是一些细节的写法不同而已。
2、算法本身不受编程语言的限制。所以说,这个函数几乎可以移植到任何程序语言中去。

调用该函数的过程

非常简单

Sub test()
    '设置一个字典,用于存储初值和结果
    Set Dic_Rst = CreateObject("Scripting.Dictionary")
    '给字典赋初值
    Dic_Rst("A B C D E") = 0
    '调用函数,结果就存在该字典中
    Set Dic_Rst = ComposeWords(Dic_Rst)
End Sub

递归函数代码

也超级简单,不算格式、注释的话,连函数头尾,23行
注意:函数本身也是对象类型

Function ComposeWords(ByVal Dic_Rst As Object) As Object
	'把字典中的最后一个Key提取出来
    Last = Dic_Rst.Count - 1
    StrArr = Dic_Rst.Keys()(Last)
    tempArr = Split(StrArr)	'拆分单词(默认空格分隔)
    
    '递归思路:把每个单词提出来,分别做一次正向、一次反向组合"A B" "B A"
    For Each FirstStr In tempArr
    	'除第一词FirstStr 之外,其余全部当成第二词对待。
        SndStr = Application.Trim(Replace(StrArr, FirstStr, ""))
        
        '递归中的递归:如果上面提取出来的“B”字串也是由多单词组成的,
        '则重复一次递归的计算过程,把结果放在内层递归字典中
        If InStr(SndStr, " ") Then
            Set Dic_Snd = CreateObject("Scripting.Dictionary")
            Dic_Snd(SndStr) = 0
            Set d_SndStr = ComposeWords(Dic_Snd)
        Else
            Set d_SndStr = CreateObject("Scripting.Dictionary")
            d_SndStr(SndStr) = 0
        End If
        
        '内层递归完成。无论它有几种组合,
        '都用来和第一个提取词FirstStr 做正/反组合
        For Each k2 In d_SndStr.Keys
            tempCps1 = k2 + " " + FirstStr
            tempCps2 = FirstStr + " " + k2
            
            '存储组合结果(这里利用了字典的不重复和快速的特性)
            If Not Dic_Rst.exists(tempCps1) Then Dic_Rst(tempCps1) = 0
            If Not Dic_Rst.exists(tempCps2) Then Dic_Rst(tempCps2) = 0
        Next
        
    Next
    '本次递归结束并赋值
    Set ComposeWords = Dic_Rst
End Function

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值