1

选择的水果 ="banana,banana,cherry,kiwi,strawberry"

lookup List<string>

"banana,strawberry" (true)
"strawberry" (true)
"banana,banana,banana" (false)

如果查找中仅与所选项目的一部分完全匹配,则应在结果中选择该项目。

最好的方法是什么?

4

5 回答 5

3

问题只是将每个项目转换为一个袋子,然后测试袋子的密封性:

private IDictionary<string, int> StringToBag(string str)
{
    return str.Split(',').GroupBy(s => s).ToDictionary(g => g.Key, g => g.Count());
}

private bool BagContains(IDictionary<string, int> haystack, IDictionary<string, int> needle)
{
    return needle.All(kv => haystack.ContainsKey(kv.Key) && kv.Value <= haystack[kv.Key]);
}

var bag = StringToBag("banana,banana,cherry,kiwi,strawberry");
bool contained = BagContains(bag, StringToBag("banana,strawberry"));
于 2012-08-23T14:20:57.190 回答
1

如果您的对象是这样初始化的:

string selected = "banana,banana,cherry,kiwi,strawberry";

List<string> lookup = new List<string>()
{
    "banana,strawberry",
    "strawberry",
    "banana,banana,banana"
};

你有一个这样的分组方法:

Dictionary<string, int> ToGroupDictionary(string value)
{
    return value.Split(',')
        .GroupBy(s => s.Trim())
        .ToDictionary(g => g.Key, g => g.Count());
}

你可以像这样测试每个字符串lookup

var selectedDictionary = ToGroupDictionary(selected);

// ["banana", 2]
// ["cherry", 1]
// ["kiwi", 1]
// ["strawberry", 1]

foreach(string test in lookup)
{
    var testDictionary = ToGroupDictionary(test);
    testDictionary.Keys.ToList().ForEach(k =>
        Console.WriteLine(selectedDictionary.ContainsKey(k) && 
            selectedDictionary[k] >= testDictionary[k]));

    // [0] :=
    // ["banana", 1]
    // ["strawberry", 1]
    // true, banana and strawberry exist

    // [1] :=
    // ["strawberry", 1]
    // true, strawberry exists

    // [2] :=
    // ["banana", 3]
    // false, too many bananas
}            
于 2012-08-23T14:09:14.123 回答
0

看一下这个:

    private static void LoadFruits(string Fruit, Dictionary<string, int> FruitDictionary)
    {
        if (FruitDictionary.ContainsKey(Fruit))
            FruitDictionary[Fruit] = FruitDictionary[Fruit] + 1;
        else
            FruitDictionary.Add(Fruit, 1);
    }

    private static bool HasFruit(string Fruit, Dictionary<string, int> FruitDictionary)
    {
        if (FruitDictionary.ContainsKey(Fruit) && FruitDictionary[Fruit] > 0)
        {
            FruitDictionary[Fruit] = FruitDictionary[Fruit] - 1;
            return true;
        }

        return false;
    }

        ...
        List<string> AllThefruits = new List<string>(){"banana" ,"banana","cherry","kiwi","strawberry"};

        Dictionary<string, int> FruitsDictionary = new Dictionary<string, int>();

        List<string> Combination1 = new List<string>() { "banana", "strawberry" }; 
        AllThefruits.ForEach(x => LoadFruits(x, FruitsDictionary));
        bool TestCombination1 = Combination1.All(x => HasFruit(x, FruitsDictionary)); //true
        FruitsDictionary.Clear();

        List<string> Combination2 = new List<string>() { "strawberry" };
        AllThefruits.ForEach(x => LoadFruits(x, FruitsDictionary));
        bool TestCombination2 = Combination2.All(x => HasFruit(x, FruitsDictionary)); //true
        FruitsDictionary.Clear();

        List<string> Combination3 = new List<string>() { "banana", "banana", "banana" };
        AllThefruits.ForEach(x => LoadFruits(x, FruitsDictionary));
        bool TestCombination3 = Combination3.All(x => HasFruit(x, FruitsDictionary)); //false
        FruitsDictionary.Clear();

        List<string> Combination4 = new List<string>() { "banana", "banana" };
        AllThefruits.ForEach(x => LoadFruits(x, FruitsDictionary));
        bool TestCombination4 = Combination4.All(x => HasFruit(x, FruitsDictionary)); //true

但是,我不确定这是否是最佳解决方案。

于 2012-08-23T13:51:10.090 回答
0
public static bool CheckCombination(List<string> values, List<string> combinations)
{
    var valuesLookup = values.ToLookup(x => x);

    return CheckCombination(valuesLookup, combinations);
}

public static bool CheckCombination(ILookup<string, string> valuesLookup, List<string> combinations)
{
    foreach (var combination in combinations.GroupBy(x => x))
    {
        if (valuesLookup.Contains(combination.Key) &&
            valuesLookup[combination.Key].Count() < combination.Count())
            return false;
    }
    return true;
}
于 2012-08-23T14:13:30.117 回答
0

未经测试,但这是否可行:

string fr = "banana,banana,cherry,kiwi,strawberry";
    IList<string> selFr = fr.Split(new string[] { "," }, StringSplitOptions.None);
    IList<string> look = new List<string>();
    // Add the lookup values to the "look" list here...
    IList<string> res = new List<string>();
    foreach (string lookupStr in look) {
        foreach (string f in selFr) {
            if (lookupStr.Contains(f)) {
                  res.Add(lookupStr);
                  continue;
            }
        }
     }
  return res;
于 2012-08-23T14:15:18.557 回答