2011-06-08 59 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成为扩展方法。