Recursive function to match a string against a wildcard pattern

泪湿孤枕 提交于 2019-12-03 12:23:55

Here's some Python "psudocode" that may help

def samePattern(s1,s2):
    if s2 == "*" or s1 == s2: return True
    if s1 == "": return False
    if s1[0] == s2[0]: return samePattern(s1[1:], s2[1:])
    if s2[0] == "*": return samePattern(s1, s2[1:]) or samePattern(s1[1:], s2)
    return False

Here is a rough guide for converting the code

s[0] = the first character
s[1:] = the string minus the first character

The problem with your current approach is that it doesn't consider all the possible substrings that a * can match. For example, samePattern("ababababab", "a*b") should return true; the * can match all but the first and last letter of the string, but your code assumes that since the following letter is b, the * matches the empty string.

I suggest thinking of samePattern as "consuming" its two input strings as it looks for a match. At each step, samePattern should only need to look at the first character of each string to decide whether a match at the first character is possible, and if so make a recursive call to check the rest of the string. The trick will be knowing what to do when you reach a * in the pattern string, since it may or may not be used to match the first character in s1. You shouldn't need to look at the rest of the string to decide what to do.

Since this is homework, I'll leave figuring out the details of what happens there to you, but hopefully this gets you thinking down the right path.

Here is sample solution written in c#. Sorry for lack of comments but I didn't have time for them :/ If you will still need them tomorrow then I can write some, but I hope You will grab the idea.

 public static bool CompareString(string s1, string s2, bool wildCard)
 {
        // Both strings are empty
        if ((s1.Length == 0) && (s2.Length == 0)) return true;

        // Second string is empty and there is wildCard character
        if (s2.Length == 0 && wildCard) return true;

        //First string is empty. Answer will be true only if all characters in second string are *.
        if (s1.Length == 0 && s2.Length > 0 && s2[0] == '*')
        {
            string newS2 = s2.Remove(0, 1);
            return CompareString(s1, newS2, true);
        }

        // One of the strings is empty, and second one is not.
        if (s1.Length * s2.Length == 0) return false;

        if (wildCard)
        {
            string newS1 = s1.Remove(0, 1);
            if (CompareString(newS1,s2,true) || CompareString(newS1,s2,false))
            {
                return true;
            }
        }
        else
        {
            if (s2[0] == '*')
            {
                string newS2 = s2.Remove(0,1);
                if (CompareString(s1,newS2,true) || CompareString(s1,newS2,false))
                {
                    return true;
                }
            }
            else
            {
                if (s1[0] == s2[0])
                {
                    string newS1 = s1.Remove(0,1);
                    string newS2 = s2.Remove(0,1);
                    return CompareString(newS1,newS2,false);
                }
                else
                {
                    return false;
                }
            }
        }
        return false;
    }

When dealing with algorithms like this, it often pays to break the problem into small chunks in your head.

Since you're string parsing, consider the solution on a character-by-character basis. Furthermore, since you have no control over the actual size of these strings, constrain yourself to considering only the first character of the string at any given time. (well - with one exception)

Once you've determined that the characters you're dealing with warrant further investigation into the rest of the string, toss them away; keeping them around only adds complexity, so why bother? (Conversely, if the characters flat out mismatch, you're done - right?)

Of course, this is a recursion on strings, so you'll have to have a couple of conditions governing failure/success that deal with the overall state of the strings - but those aren't the meat of the problem - check the state of the string at the top of your function, and move on.

I have an algorithm that I whipped up (11 lines of code, plus braces) that I can post if you want a full solution - but I wasn't sure by your message if you wanted to be given the algorithm, or just pointers.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!