📌  相关文章
📜  在不使用正则表达式的情况下匹配模式和字符串

📅  最后修改于: 2021-05-24 20:55:36             🧑  作者: Mango

给定一个字符串,找出是否字符串遵循特定图案或没有不使用任何正则表达式。

例子:

Input: 
string - GraphTreesGraph
pattern - aba
Output: 
a->Graph
b->Trees

Input: 
string - GraphGraphGraph
pattern - aaa
Output: 
a->Graph

Input: 
string - GeeksforGeeks
pattern - GfG
Output: 
G->Geeks
f->for

Input: 
string - GeeksforGeeks
pattern - GG
Output: 
No solution exists

我们可以借助Backtracking解决此问题。对于模式中的每个字符,如果以前没有看到过该字符,我们将考虑所有可能的子字符串,然后递归查看它是否导致解决方案。我们维护一个映射,该映射存储映射到模式字符的子字符串。如果以前看到过模式字符,我们将使用地图中存在的相同子字符串。如果找到解决方案,则对于模式中的每个不同字符,我们将使用我们的地图打印映射到该字符串。

以下是上述想法的C++实现–

// C++ program to find out if string follows
// a given pattern or not
#include 
using namespace std;
  
/*  Function to find out if string follows a given
    pattern or not
  
    str - given string
    n - length of given string
    i - current index in input string
    pat - given pattern
    m - length of given pattern
    j - current index in given pattern
    map - stores mapping between pattern and string */
bool patternMatchUtil(string str, int n, int i,
                    string pat, int m, int j,
                    unordered_map& map)
{
    // If both string and pattern reach their end
    if (i == n && j == m)
        return true;
  
    // If either string or pattern reach their end
    if (i == n || j == m)
        return false;
  
    // read next character from the pattern
    char ch = pat[j];
  
    // if character is seen before
    if (map.find(ch)!= map.end())
    {
        string s = map[ch];
        int len = s.size();
  
        // consider next len characters of str
        string subStr = str.substr(i, len);
  
        // if next len characters of string str
        // don't match with s, return false
        if (subStr.compare(s))
            return false;
  
        // if it matches, recurse for remaining characters
        return patternMatchUtil(str, n, i + len, pat, m,
                                            j + 1, map);
    }
  
    // If character is seen for first time, try out all
    // remaining characters in the string
    for (int len = 1; len <= n - i; len++)
    {
        // consider substring that starts at position i
        // and spans len characters and add it to map
        map[ch] = str.substr(i, len);
  
        // see if it leads to the solution
        if (patternMatchUtil(str, n, i + len, pat, m,
                                          j + 1, map))
            return true;
  
        // if not, remove ch from the map
        map.erase(ch);
    }
  
    return false;
}
  
// A wrapper over patternMatchUtil()function
bool patternMatch(string str, string pat, int n, int m)
{
    if (n < m)
    return false;
  
    // create an empty hashmap
    unordered_map map;
  
    // store result in a boolean variable res
    bool res = patternMatchUtil(str, n, 0, pat, m, 0, map);
  
    // if solution exists, print the mappings
    for (auto it = map.begin(); res && it != map.end(); it++)
        cout << it->first << "->" << it->second << endl;
  
    // return result
    return res;
}
  
// Driver code
int main()
{
    string str = "GeeksforGeeks", pat = "GfG";
  
    int n = str.size(), m = pat.size();
  
    if (!patternMatch(str, pat, n, m))
        cout << "No Solution exists";
  
    return 0;
}

输出:

f->for
G->Geeks