Моя идея заключается в создании словаря, который отображает каждый элемент в первоначальном списке, как часто это происходит. Затем я итеративно уменьшаю каждый элемент, соответствующий одному в под-списке, до тех пор, пока одно из значений не достигнет нуля, после чего я вернусь к числу полных итераций.
public static int CountSubsets<T>(this IList<T> list, IList<T> subList)
{
var grouped = list.GroupBy(t => t).ToDictionary(t => t.Key, t => t.Count());
int count = 0;
while (RemoveSubset(grouped, subList))
count++;
return count;
}
private static bool RemoveSubset<T>(Dictionary<T, int> dict, IList<T> subList)
{
foreach (T item in subList)
{
if (dict.ContainsKey(item) && dict[item] > 0)
dict[item]--;
else
return false;
}
return true;
}
Не обязательно самое эффективное или изящное решение, но оно должно работать.
Редактировать: Вот причудливый, но, вероятно, более медленный способ сделать это. Я очень доволен этим:
public static int CountSubsets2<T>(this IList<T> list, IList<T> subList)
{
var main = list.GroupBy(t => t).ToDictionary(t => t.Key, t => t.Count());
var sub = subList.GroupBy(t => t).ToDictionary(t => t.Key, t => t.Count());
return sub.Select(t => main.ContainsKey(t.Key) ? main[t.Key]/t.Value : 0).Min();
}
Причина, по которой вы получаете downvoted, состоит в том, что вы не продемонстрировали, что пытались решить проблему самостоятельно. Отправьте свою лучшую попытку, и мы можем вам помочь. –
У меня возникают проблемы с повторением значений с помощью Intersect. – user2757243
Эта проблема на самом деле не проста. –