简体   繁体   中英

Does .NET have an equivalent for Python's issubset method?

UPDATE:

As @Blender pointed out in Python set('aab').issubset(set('abb')) == True . For my situation this needs to return false. The number of each character needs to be taken into account.


Basically I have two strings and I would like to determine if one is a subset of another. Example:

String A: abcd
String B: dbace
String A is a subset of string B

Characters can be in any order and there can be repeating numbers of characters. I had tried ordering the strings and then using String.StartsWith, but this does not work in certain situations. Example:

String A: abcdd
string B: abbcdd
Ordering these and using StartsWith returns false because string B has two "b"s

I did some looking around and found Python's issubset method which appears to do what I want, so I'm curious if anyone has come across its equivalent in .NET (or an effective method someone has come up with on their own).

NOTE: I am looking for subsets, not anagrams.

There's nothing built-in that I know of that behaves as you want it. Strictly speaking, this isn't a real subset as it should be doing set comparisons as it is in Python (where every item in a set is unique) but it should be simple to cook one up.

public static bool IsSubsetOf<TSource>(this IEnumerable<TSource> lhs, IEnumerable<TSource> rhs)
{
    // O(m+n)
    var contents = rhs.ToList();
    foreach (var item in lhs)
    {
        if (!contents.Remove(item))
            return false;
    }
    return true;
}
"aab".IsSubsetOf("abb");      // false
"foo".IsSubsetOf("food");     // true
"foo".IsSubsetOf("goof");     // true
"bar".IsSubsetOf("barf");     // true
"abcd".IsSubsetOf("dbace");   // true
"abcdd".IsSubsetOf("abbcdd"); // true

If you want true set mechanics, it is just as simple.

public static bool IsTrueSubsetOf<TSource>(this IEnumerable<TSource> lhs, IEnumerable<TSource> rhs)
{
    return new HashSet<TSource>(lhs).IsSubsetOf(rhs);
}

I think the best solution is to sort both of them and check the subset by Contains method.

new String(A.OrderBy(o=> o)).Contains(new String(B.OrderBy(o=>o)))

UPDATE:

new String(A.OrderBy(o=> o)
            .Distinct())
     .Contains(new String(B.OrderBy(o=>o)
                           .Distinct()))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM