简体   繁体   English

如何比较两个字符串以检查一个是否包含另一个,而不考虑字符的顺序

[英]How to compare two strings to check if one contains the other, regardless of order of characters

I have two strings, and I need to know if one is contained in the other, completely ignoring the order of the characters of both of them.我有两个字符串,我需要知道一个是否包含在另一个中,完全忽略它们两个字符的顺序。

Example:例子:

            string container = "WWGAAFWW";
            string element = "WA";
            Debug.Log(container.Contains(element));

This gives false, but I need it to be true, because W and A are contained in the container string.这给出了 false,但我需要它是 true,因为 W 和 A 包含在容器字符串中。 I know there is a method to sort lists, but even then, container would become AAFGWWWW and comparing them would still give false.我知道有一种方法可以对列表进行排序,但即使那样,容器也会变成 AAFGWWWW 并且比较它们仍然会给出 false。 Both string could be longer than this example (but not by much, i think).两个字符串都可能比这个例子长(但我认为不会长很多)。 After having checked that, if the second string is contained (the way I intend) I would also need to remove it from the first one, so in the example, I want the end result to be WGAFWWF.检查后,如果包含第二个字符串(按照我的意图),我还需要将其从第一个字符串中删除,因此在示例中,我希望最终结果为 WGAFWWF。 I can't think of a simple way to do this, and I couldn't find any example on how to.我想不出一个简单的方法来做到这一点,我也找不到任何关于如何做的例子。 Any idea?任何的想法?

I am not sure whether it is what you want我不确定这是否是你想要的

After this function, container will remove the element在这个 function 之后,容器将移除该元素

    static bool CCstring(ref string container, string element)
    {
        string temp = container;
        foreach (char c in element)
        {
            if (!container.Contains(c.ToString()))
            {
                container = temp;
                return false;
            }
            else
            {
                container = container.Remove(container.IndexOf(c), 1);
            }
        }
        return true;
    }

you could check this easily using a loop.您可以使用循环轻松检查这一点。 It's a simple way of doing time complexity O(M*N), because it's checking each char of one string into another string.这是实现时间复杂度 O(M*N) 的一种简单方法,因为它会将一个字符串的每个字符检查到另一个字符串中。

private static bool Contains(string container, string element)
{
    foreach (char ch in element)
    {
        if (container.Contains(ch) == false)
        {
            return false;
        }
    }

    return true;
}

The following approach uses a dictionary to track character counts in the container and ensures a corresponding amount are deducted for each character in element.以下方法使用字典来跟踪容器中的字符数,并确保为元素中的每个字符扣除相应的数量。

private static IDictionary<char, int> ExtractDictionaryFromString(string value)
{
    var result = new Dictionary<char, int>();
    foreach (var c in value.ToCharArray())
    {
        if (!result.TryGetValue(c, out int count))
        {
            result.Add(c, 0);
        }

        result[c] = result[c] + 1;
    }

    return result;
}

private static bool IsElementInContainer(ref string container, string element)
{
    var lookup = ExtractDictionaryFromString(container);
    foreach (var c in element.ToCharArray())
    {
        if (!lookup.TryGetValue(c, out int count) || count == 0)
        {
            return false;
        }

        lookup[c] = lookup[c] - 1;
    }

    StringBuilder sb = new StringBuilder();
    foreach (var c in lookup)
    {
        for (int i = 0; i < c.Value; i++)
        {
            sb.Append(c.Key);
        }
    }

    container = sb.ToString();
    return true;
}

This does not require continuous re-parsing of container, which depending on the length of these strings could be expensive.这不需要连续重新解析容器,根据这些字符串的长度,这可能会很昂贵。

Usage:用法:

    string container = "WWGAAFWW";
    string  element = "WA";
    Console.WriteLine(IsElementInContainer(ref container, element));
    Console.WriteLine(container);

Note that the returned version of container is not in a predefined sequence.请注意,返回的容器版本不在预定义的序列中。 If that is important to you, another solution would be more appropriate.如果这对您很重要,那么另一种解决方案会更合适。

A variant of this approach, left to the reader, would be to replace the Dictionary with an ImmutableDictionary equivalent.留给读者的这种方法的一个变体是将 Dictionary 替换为 ImmutableDictionary 等价物。 This would allow you to create the Dictionary object once and pass it to IsElementInContainer instead of regenerating it on each call.这将允许您创建 Dictionary object 一次并将其传递给 IsElementInContainer 而不是在每次调用时重新生成它。

Using LINQ, you could declare the following使用 LINQ,您可以声明以下内容

bool containsAll = container.Except(element.ToCharArray()).Any();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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