这里有个vb的,做大数量的主要是防止溢出,我在以前那个固顶的帖子里是直接用的2进制运算的,Oct()函数,最大可到 11 位的八进制字符,在大就溢出了
'窗体中需两个Text、两个Label、一个Command
Option Explicit
Private mlngAllNumCount As Long, mlngGetNumCount As Long
Private mblnCancelProc As Boolean, mlngCurResultCount As Long
Private mastrOneResult() As String
Private mlngFileNo As Long, mstrResultFile As String
Private Sub Form_Load()
Command1.Caption = "处理"
mstrResultFile = App.Path & "\1.txt" '存放输出结果的文件,结果多时,不要尝试用记事本打开!会死机的。
End Sub
Private Sub Form_Unload(Cancel As Integer)
mblnCancelProc = True
End Sub
Private Sub Command1_Click()
Dim t As Single, i As Long
If Command1.Caption = "处理" Then
mlngAllNumCount = Text1.Text '数字总个数
mlngGetNumCount = Text2.Text '每组要取的数字个数
i = Zhuhe(mlngAllNumCount, mlngGetNumCount)
If i = 0 Then
MsgBox "结果太多,请不要尝试了!"
Exit Sub
End If
Label2.Caption = i
t = Timer
mblnCancelProc = False '中断处理的标志
Command1.Caption = "停止"
mlngCurResultCount = 0 '已产生出的组合总数
ReDim mastrOneResult(1 To mlngGetNumCount)
mlngFileNo = FreeFile
Open mstrResultFile For Output As #mlngFileNo
ListNum 1, 1
Close #mlngFileNo
Label1.Caption = mlngCurResultCount
Command1.Caption = "处理"
Me.Caption = Timer - t
Else
mblnCancelProc = True
End If
End Sub
Private Function Zhuhe(AllNum As Long, GetNum As Long) As Long
'算组合总数的过程,为防溢出,而做了特别设计
'只要结果总数在20亿以内,都不会溢出的
'太大的数不太可能会完成穷举,本程序也就不做尝试了
'接近溢出的上限列举:65536取2、2345取3、477取4、193取5、110取6
'75取7、58取8、49取9、40取10、39取11、37取12、35取13、34取15、33取16等
Dim i As Long, j As Long, k As Long, colget As Collection
Dim m As Long, n As Long, Num(1) As Long
On Error GoTo fail
Num(0) = 1
Set colget = New Collection '保存分母中的所有乘数(GetNum!)
For i = GetNum To 2 Step -1
colget.Add i
Next
For i = AllNum To AllNum - GetNum + 1 Step -1 '分子中所有乘数循环相乘
'让两个乘数尽可能与分母约分
Num(1) = i
For k = 0 To 1
m = colget.Count
If m > 0 Then
n = m
For j = 1 To m
If j > n Then Exit For
If Num(k) Mod colget(j) = 0 Then
Num(k) = Num(k) \ colget(j)
colget.Remove j
n = n - 1
j = j - 1
End If
Next
End If
Next
Num(0) = Num(0) * Num(1) '分子中的两个乘数分别约去分母再相乘,可防中间过程的溢出
Next
Zhuhe = Num(0)
Exit Function
fail:
End Function
Private Sub ListNum(ByVal Start As Long, ByVal Level As Long)
Dim i As Long
If mblnCancelProc Then Exit Sub
For i = Start To mlngAllNumCount - mlngGetNumCount + Level
mastrOneResult(Level) = i
If Level < mlngGetNumCount Then '是否到了最底层
ListNum i + 1, Level + 1 '没到底,递归啦,这是本过程的核心,很简单哟
Else
Print #mlngFileNo, Join(mastrOneResult, vbTab) '递归到最深层,就可以输出了
mlngCurResultCount = mlngCurResultCount + 1
If mlngCurResultCount Mod &H2000& = 0 Then
Label1.Caption = mlngCurResultCount '显示实际找出了多少组数字
DoEvents
End If
End If
Next
End Sub
顶一下,以下是我研究出来的代码,虽然可以实现,但如果数字多了之后,效率会大打折扣,超时15个,每多一个计算机就会响应好长时间,太大了干脆就死在那了。我在想用递归是否可以实现,如果递归实现效率是否会好些,或用其他算法。
<%
Server.script_Timeout = 999
str = "01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23"
arr = Split(str,",")
length = UBound(arr) + 1
For i = 0 To length
For j = i + 1 To length-1
For n = j + 1 To length-1
For w = n + 1 To length-1
For e = w + 1 To length-1
For r = e + 1 To length-1
my_String = my_String & arr(i)&" "&arr(j)&" "&arr(n)&" "&arr(w)&" "&arr(e)&" "&arr(r) & "<br>"
Next
Next
Next
Next
Next
Next
teststr = Split(my_String,"<br>")
Response.Write(UBound(teststr))
%>
<script language=vbs>
test:sub test()
dim aryTest
aryTest=split("01,02,03,04,05,06,07,08,09,00",",")
dim i
for i=0 to 99
document.write join(GetRndString(aryTest)) & "<br>"
next
end sub
function GetRndString(byval arystrIn)
randomize
dim intBound,intTmpBound
dim intSelectedPosition
dim i
for i=0 to intBound
intSelectedPosition=cint(rnd*intTmpBound)
arystrOut(i)=arystrIn(intSelectedPosition)
arystrIn(intSelectedPosition)=arystrIn(intTmpBound)
if intTmpBound>0 then intTmpBound=intTmpBound-1
next