我这里有40000多词库成语,想利用sqlserver来编写成语接龙,让这条龙很长,网上好象有能接到5000多个词的龙了.
下面有一个vb编写的程序,不过看不懂,似乎蛮经典的,有人能解释吗?或者提一些你们关于成语接龙的想法.能提供思路的一定给分,谢谢了!'stack类模块代码:Option Compare Database
Option Explicit
Dim StackColl As New CollectionPublic Property Get Count() As Variant
Count = StackColl.Count
End PropertyPublic Sub Push(Var As Variant)
StackColl.Add (Var)
End SubPublic Function fetch() As Variant
fetch = StackColl.Item(StackColl.Count)
StackColl.Remove (StackColl.Count)
End FunctionPublic Property Get AllString() As Variant
Dim strItem As Variant
For Each strItem In StackColl
AllString = AllString & "'" & strItem & "',"
Next
End Property'Form_接龙模块代码:Option Compare Database
Option ExplicitPrivate Sub 命令0_Click()
Me.显示接龙 = GetLink(Me.选择成语, Me.接龙长度)
End SubPublic Function GetLink(StartWord As String, Lenth As Integer) As String
Dim MaxLen As Integer, i As Integer
Dim objStackA As New stack
Dim objStackB As New stack
Dim EndWord As String
Dim rst As Recordset
Randomize
objStackB.Push StartWord
Do While MaxLen < Lenth And objStackB.Count > 0
StartWord = objStackB.fetch
Set rst = CurrentDb().OpenRecordset("Select CM from cy where Head='" & Right(StartWord, 1) & "' AND CM Not In (''," & objStackA.AllString & ")" & IIf(Int(2 * Rnd) = 0, "", " Order by CM Desc"))
If Not rst.EOF Then
Do While objStackA.Count > 0
EndWord = objStackA.fetch
If Right(EndWord, 1) = Left(StartWord, 1) Then
objStackA.Push EndWord
Exit Do
End If
Loop
objStackA.Push StartWord
If objStackA.Count > MaxLen Then
GetLink = objStackA.AllString
MaxLen = objStackA.Count
End If
Do While Not rst.EOF
objStackB.Push rst![CM]
rst.MoveNext
Loop
End If
Loop
End Function
下面有一个vb编写的程序,不过看不懂,似乎蛮经典的,有人能解释吗?或者提一些你们关于成语接龙的想法.能提供思路的一定给分,谢谢了!'stack类模块代码:Option Compare Database
Option Explicit
Dim StackColl As New CollectionPublic Property Get Count() As Variant
Count = StackColl.Count
End PropertyPublic Sub Push(Var As Variant)
StackColl.Add (Var)
End SubPublic Function fetch() As Variant
fetch = StackColl.Item(StackColl.Count)
StackColl.Remove (StackColl.Count)
End FunctionPublic Property Get AllString() As Variant
Dim strItem As Variant
For Each strItem In StackColl
AllString = AllString & "'" & strItem & "',"
Next
End Property'Form_接龙模块代码:Option Compare Database
Option ExplicitPrivate Sub 命令0_Click()
Me.显示接龙 = GetLink(Me.选择成语, Me.接龙长度)
End SubPublic Function GetLink(StartWord As String, Lenth As Integer) As String
Dim MaxLen As Integer, i As Integer
Dim objStackA As New stack
Dim objStackB As New stack
Dim EndWord As String
Dim rst As Recordset
Randomize
objStackB.Push StartWord
Do While MaxLen < Lenth And objStackB.Count > 0
StartWord = objStackB.fetch
Set rst = CurrentDb().OpenRecordset("Select CM from cy where Head='" & Right(StartWord, 1) & "' AND CM Not In (''," & objStackA.AllString & ")" & IIf(Int(2 * Rnd) = 0, "", " Order by CM Desc"))
If Not rst.EOF Then
Do While objStackA.Count > 0
EndWord = objStackA.fetch
If Right(EndWord, 1) = Left(StartWord, 1) Then
objStackA.Push EndWord
Exit Do
End If
Loop
objStackA.Push StartWord
If objStackA.Count > MaxLen Then
GetLink = objStackA.AllString
MaxLen = objStackA.Count
End If
Do While Not rst.EOF
objStackB.Push rst![CM]
rst.MoveNext
Loop
End If
Loop
End Function
应该说简单的算法很容易想到,但是最简单的算法是不现实的.因为需要太久了,否则我也不会贴上来,我想理解上面vb的算法,然后写成sql版,多谢了!
objStackA和objStackB分别存储什么的?
If objStackA.Count > MaxLen Then
GetLink = objStackA.AllString
MaxLen = objStackA.Count
End If
又是在做什么方面的比较呢?
一直循环
直到达到你要求的成语数 或者 未达到要求的数量但查询完毕 后返回至于优化
写成SQL过程或者函数其实效率上差别不大
应该从算法上去改进
一直循环
直到达到你要求的成语数 或者 未达到要求的数量但查询完毕 后返回
-----------------------------------------
这样简单的做是达不到比较长的龙的,一般一百多个成语,但是该vb程序可以达到len=2000个龙.我觉得这个不一般的,有一定的算法在里面,而且他在生成上百个成语时速度也理想.其实就是希望大家能讨论一下算法,我觉得达到最优的,最长的龙可能不现实,不知道有什么算法能逼近这样的龙呢?
我现在做成了一个,蛮长的了.
http://topic.csdn.net/u/20071031/16/986e63a4-f1cd-4927-94d1-c5dbab3c8650.html
大家看看,继续讨论一下算法吧.我的算法一定不是最优的.