搜索所有组合

时间:2012-08-23 13:46:02

标签: c# regex

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

lookup List<string>

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

如果查找中只有部分选定项目存在完全匹配,则应在结果中选择该项目。

最好的方法是什么?

5 个答案:

答案 0 :(得分: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"));

答案 1 :(得分: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
}            

答案 2 :(得分: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

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

答案 3 :(得分: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;
}

答案 4 :(得分: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;