2011-06-08 85 views
1

我正在使用程序,請參閱此處:Visual Basic Regular Expression Question。我輸入字母,程序從列表中返回所有可能的組合。我想改變這行代碼...Linq從列表中獲取單詞

Dim result = fruits.Where(Function(fruit) Not fruit.Except(letters).Any()) 

如果我有這樣的名單:

Dim fruit as List(Of string) from {"apple","orange","pear","banana"} 

我輸入「papler」,那麼它會返回「蘋果」和「梨」,但如果我輸入「apler」,那麼它會返回「梨」。這個想法是返回所有的單詞,這些單詞可以由輸入的字母組成,而不需要複製任何單個字母。如何優化這個Linq代碼?

+0

Boggle anybody? – IAbstract 2011-06-08 21:46:06

+0

這是一種Boggle,除了這將返回所有可能的單詞。 – Cobold 2011-06-08 21:48:05

+0

你是否分析了你的應用程序,並將這一行LINQ識別爲瓶頸?我不明白你爲什麼需要優化這一行代碼。 – 2011-06-08 21:48:12

回答

1

這可能是清潔的,但它的工作原理:

Dim fruits As New List(Of String) From { "apple", "orange", "pear", "banana" } 
Dim input As String = "a,p,l,e,r" 
dim inputLetters = from letter in input.Replace(",", "") group by letter into Group select group.first, Group.Count 

dim result = fruits.where(
    function(fruit) 
     dim fruitcounts = from letter in fruit group by letter into Group select group.first, group.count 
     dim res = from fc in fruitcounts, inputs in inputletters where fc.first = inputs.first andalso fc.count <= inputs.count select fc.first 
     return res.count = fruit.count 
    end function 
    ) 

編輯 - 我的條款去掉了一些不必要的訂單,並再次簡化了分組

編輯 - 後一些更多的思考,這裏有一個版本,有更多的線條,但更清晰和更好的因素:

Sub Main 

    Dim fruits As New List(Of String) From { "apple", "orange", "pear", "banana" } 
    Dim input As String = "a,p,l,e,r" 

    dim matchingFruits = from fruit in fruits where CanBeMadeFrom(fruit, input) 

End Sub 

Function StringToFrequencyTable(input as string) as Dictionary(of Char, Integer) 

    dim freqTable = from letter in input 
        group by letter into Group 
        select letter, Group.Count() 

    return freqTable.ToDictionary(function(g) g.Letter, function(g) g.Count) 

end function 

Function CanBeMadeFrom(candidate as string, letters as string) as boolean 

    dim inputLetters = StringToFrequencyTable(letters.replace(",", "")) 
    dim IsCharInFrequencyTable = function(x) (from entry in inputLetters where entry.Key = x.Key andalso entry.Value >= x.Value).Any() 

    return StringToFrequencyTable(candidate).All(IsCharInFrequencyTable) 

end function 

如果我做了其他任何事情,我會使CanBeMadeFrom和StringToFrequencyTable成爲擴展方法。