📜  在矩阵中查找模式的方向

📅  最后修改于: 2022-05-13 01:57:23.694000             🧑  作者: Mango

在矩阵中查找模式的方向

给定一个字符矩阵和一个模式,找出矩阵中模式的方向。换句话说,查找模式是否在水平或垂直方向上出现在矩阵中。在尽可能短的时间内实现这一目标。

Input:
mat[N][N] = { {'a', 'b', 'c', 'd', 'e'},
              {'f', 'g', 'h', 'i', 'j'},
              {'k', 'l', 'm', 'n', 'o'},
              {'p', 'q', 'r', 's', 't'},
              {'u', 'v', 'w', 'x', 'y'}};
pattern = "pqrs";

Output: Horizontal

我们强烈建议您最小化您的浏览器并首先自己尝试。
一个简单的解决方案是针对每一行和每一列,使用朴素模式搜索算法来查找模式在矩阵中的方向。每一行的朴素模式搜索算法的时间复杂度为 O(NM),其中 N 是矩阵的大小,M 是模式的长度。因此,该解决方案的时间复杂度将是O(N*(NM)) ,因为 N 行和 N 列中的每一者都需要 O(NM) 时间。

我们能做得更好吗?
这个想法是对每一行和每一列使用 KMP 模式匹配算法。 KMP 匹配算法将最坏情况改进为 O(N + M)。 KMP 搜索的总成本与字符串和模式的字符数成线性关系。对于长度为 M 的 N x N 矩阵和模式,此解决方案的复杂度将为O(N*(N+M)) ,因为 N 行和 N 列中的每一列都将花费 O(N + M) 时间。

C++
// C++ program for finding orientation of the pattern
// using KMP pattern searching algorithm
#include
using namespace std;
#define N 5
 
// Used in KMP Search for preprocessing the pattern
void computeLPSArray(char *pat, int M, int *lps)
{
    // length of the previous longest prefix suffix
    int len = 0;
    int i = 1;
 
    lps[0] = 0; // lps[0] is always 0
 
    // the loop calculates lps[i] for i = 1 to M-1
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;
            lps[i++] = len;
        }
        else // (pat[i] != pat[len])
        {
            if (len != 0)
            {
                // This is tricky. Consider the example
                // AAACAAAA and i = 7.
                len = lps[len - 1];
 
                // Also, note that we do not increment i here
            }
            else // if (len == 0)
            {
                lps[i++] = 0;
            }
        }
    }
}
 
int KMPSearch(char *pat, char *txt)
{
    int M = strlen(pat);
 
    // create lps[] that will hold the longest
    // prefix suffix values for pattern
    int *lps = (int *)malloc(sizeof(int)*M);
    int j = 0; // index for pat[]
 
    // Preprocess the pattern (calculate lps[] array)
    computeLPSArray(pat, M, lps);
 
    int i = 0; // index for txt[]
    while (i < N)
    {
        if (pat[j] == txt[i])
        {
            j++;
            i++;
        }
        if (j == M)
        {
            // return 1 is pattern is found
            return 1;
        }
         
        // mismatch after j matches
        else if (i < N && pat[j] != txt[i])
        {
            // Do not match lps[0..lps[j-1]] characters,
            // they will match anyway
            if (j != 0)
                j = lps[j - 1];
            else
                i = i + 1;
        }
    }
    free(lps); // to avoid memory leak
     
    // return 0 is pattern is not found
    return 0;
}
 
// Function to find orientation of pattern in the matrix
// It uses KMP pattern searching algorithm
void findOrientation(char mat[][N], char *pat)
{
    // allocate memory for string containing cols
    char *col = (char*) malloc(N);
 
    for (int i = 0; i < N; i++)
    {
        // search in row i
        if (KMPSearch(pat, mat[i]))
        {
            cout << "Horizontal" << endl;
            return;
        }
 
        // Construct an array to store i'th column
        for (int j = 0; j < N; j++)
            col[j] = *(mat[j] + i);
 
        // Search in column i
        if (KMPSearch(pat, col))
            cout << "Vertical" << endl;
    }
 
    // to avoid memory leak
    free(col);
}
 
// Driver Code
int main()
{
    char mat[N][N] = {{'a', 'b', 'c', 'd', 'e'},
                      {'f', 'g', 'h', 'i', 'j'},
                       {'k', 'l', 'm', 'n', 'o'},
                      {'p', 'q', 'r', 's', 't'},
                      {'u', 'v', 'w', 'x', 'y'}};
    char pat[] = "pqrs";
 
    findOrientation(mat, pat);
 
    return 0;
}
 
// This code is contributed by kumar65


C
// C program for finding orientation of the pattern
// using KMP pattern searching algorithm
#include
#include
#include
#define N 5
 
// Used in KMP Search for preprocessing the pattern
void computeLPSArray(char *pat, int M, int *lps)
{
    // length of the previous longest prefix suffix
    int len = 0;
    int i = 1;
 
    lps[0] = 0; // lps[0] is always 0
 
    // the loop calculates lps[i] for i = 1 to M-1
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;
            lps[i++] = len;
        }
        else // (pat[i] != pat[len])
        {
            if (len != 0)
            {
                // This is tricky. Consider the example
                // AAACAAAA and i = 7.
                len = lps[len-1];
 
                // Also, note that we do not increment i here
            }
            else // if (len == 0)
            {
                lps[i++] = 0;
            }
        }
    }
}
 
int KMPSearch(char *pat, char *txt)
{
    int M = strlen(pat);
 
    // create lps[] that will hold the longest prefix suffix
    // values for pattern
    int *lps = (int *)malloc(sizeof(int)*M);
    int j = 0; // index for pat[]
 
    // Preprocess the pattern (calculate lps[] array)
    computeLPSArray(pat, M, lps);
 
    int i = 0; // index for txt[]
    while (i < N)
    {
        if (pat[j] == txt[i])
        {
            j++;
            i++;
        }
        if (j == M)
        {
            // return 1 is pattern is found
            return 1;
        }
        // mismatch after j matches
        else if (i < N && pat[j] != txt[i])
        {
            // Do not match lps[0..lps[j-1]] characters,
            // they will match anyway
            if (j != 0)
                j = lps[j-1];
            else
                i = i+1;
        }
    }
    free(lps); // to avoid memory leak
    // return 0 is pattern is not found
    return 0;
}
 
// Function to find orientation of pattern in the matrix
// It uses KMP pattern searching algorithm
void findOrientation(char mat[][N], char *pat)
{
    // allocate memory for string containing cols
    char *col = (char*) malloc(N);
 
    for (int i = 0; i < N; i++)
    {
        // search in row i
        if (KMPSearch(pat, mat[i]))
        {
            printf("Horizontal\n");
            return;
        }
 
        // Construct an array to store i'th column
        for (int j = 0; j < N; j++)
            col[j] = *(mat[j] + i);
 
        // Search in column i
        if (KMPSearch(pat, col))
            printf("Vertical\n");
    }
 
    // to avoid memory leak
    free(col);
}
 
// Driver program to test above function
int main()
{
    char mat[N][N] =
    {
        {'a', 'b', 'c', 'd', 'e'},
        {'f', 'g', 'h', 'i', 'j'},
        {'k', 'l', 'm', 'n', 'o'},
        {'p', 'q', 'r', 's', 't'},
        {'u', 'v', 'w', 'x', 'y'}
 
    };
    char pat[] = "pqrs";
 
    findOrientation(mat, pat);
 
    return 0;
}


Java
// Java program for finding orientation of the pattern 
// using KMP pattern searching algorithm
import java.io.*;
import java.util.*;
class GFG
{
  public static int N = 5;
 
  // Used in KMP Search for preprocessing the pattern 
  public static void computeLPSArray(char pat[],
                                     int M, int lps[])
  {
 
    // length of the previous longest prefix suffix
    int len = 0; 
    int i = 1;
    lps[0] = 0; // lps[0] is always 0
 
    // the loop calculates lps[i] for i = 1 to M-1
    while(i < M)
    {
      if(pat[i] == pat[len])
      {
        len++; 
        lps[i++] = len;
      }
      else    // (pat[i] != pat[len]) 
      {
        if(len != 0)
        {
 
          // This is tricky. Consider the example 
          // AAACAAAA and i = 7. 
          len = lps[len - 1];
 
          // Also, note that we do not increment i here
        }
        else    // if (len == 0)
        {
          lps[i++] = 0;
        }
      }
    }
 
  }
  public static int KMPSearch(char pat[], char txt[])
  {
    int M = pat.length;
 
    // create lps[] that will hold the longest 
    // prefix suffix values for pattern 
    int[] lps = new int[M];
    int j = 0; // index for pat[]
 
    // Preprocess the pattern (calculate lps[] array) 
    computeLPSArray(pat, M, lps);
 
    int i = 0; // index for txt[]
 
    while(i < N)
    {
      if(pat[j] == txt[i])
      {
        j++;
        i++;
      }
      if(j == M)
      {
 
        // return 1 is pattern is found 
        return 1;
      }
 
      // mismatch after j matches 
      else if(i < N && pat[j] != txt[i])
      {
 
        // Do not match lps[0..lps[j-1]] characters, 
        // they will match anyway 
        if(j != 0)
        {
          j = lps[j - 1];
 
        }
        else
        {
          i = i + 1;
        }
      }
    }
 
    // return 0 is pattern is not found
    return 0;
  }
 
  // Function to find orientation of pattern in the matrix 
  // It uses KMP pattern searching algorithm         
  public static void findOrientation(char mat[][], char pat[])
  {
 
    // allocate memory for string containing cols
    char[] col = new char[N];
    for(int i = 0; i < N; i++)
    {
 
      // search in row i
      if(KMPSearch(pat, mat[i]) == 1)
      {
        System.out.println("Horizontal");
        return;
      }
 
      // Construct an array to store i'th column 
      for(int j = 0; j < N; j++)
      {
        col[j] = mat[j][i];
      }
 
      // Search in column i 
      if(KMPSearch(pat, col) == 1)
      {
        System.out.println("Vertical");
      }           
    }
  }
 
  // Driver Code
  public static void main (String[] args)
  {
    char[][] mat = {
      {'a', 'b', 'c', 'd', 'e'},{'f', 'g', 'h', 'i', 'j'},
      {'k', 'l', 'm', 'n', 'o'},{'p', 'q', 'r', 's', 't'},
      {'u', 'v', 'w', 'x', 'y'}};
    char pat[] = {'p','q','r','s'};
    findOrientation(mat, pat);
  }
}
 
// This code is contributed by avanitrachhadiya2155


Python3
# Python3 program for finding orientation of the pattern
# using KMP pattern searching algorithm
N = 5
 
# Used in KMP Search for preprocessing the pattern
def computeLPSArray(pat, M, lps):
     
    # length of the previous longest prefix suffix
    lenl = 0
    i = 1
 
    lps[0] = 0 # lps[0] is always 0
 
    # the loop calculates lps[i] for i = 1 to M-1
    while (i < M):
        if (pat[i] == pat[lenl]):
            lenl += 1
            lps[i] = lenl
            i += 1
        else: # (pat[i] != pat[lenl])
            if (lenl != 0) :
                 
                # This is tricky. Consider the example
                # AAACAAAA and i = 7.
                lenl = lps[lenl - 1]
 
                # Also, note that we do not increment i here
             
            # if (lenl == 0)
            else:
                lps[i] = 0
                i += 1
 
def KMPSearch(pat, txt):
    M = len(pat)
 
    # create lps[] that will hold the longest
    # prefix suffix values for pattern
    lps = [0] * M
    j = 0 # index for pat[]
 
    # Preprocess the pattern (calculate lps[] array)
    computeLPSArray(pat, M, lps)
 
    # index for txt[]
    i = 0
    while (i < N):
        if (pat[j] == txt[i]):
            j += 1
            i += 1
        if (j == M):
             
            # return 1 is pattern is found
            return 1
 
        # mismatch after j matches
        elif (i < N and pat[j] != txt[i]):
             
            # Do not match lps[0..lps[j-1]] characters,
            # they will match anyway
            if (j != 0):
                j = lps[j - 1]
            else:
                i = i + 1
 
    # to amemory leak
 
    # return 0 is pattern is not found
    return 0
 
# Function to find orientation of pattern in the matrix
# It uses KMP pattern searching algorithm
def findOrientation(mat, pat):
     
    # allocate memory for string containing cols
    col = ['a'] * (N)
 
    for i in range(N):
         
        # search in row i
        if (KMPSearch(pat, mat[i])):
            print("Horizontal")
            return
 
        # Construct an array to store i'th column
        for j in range(N):
            col[j] = mat[j][i]
 
        # Search in column i
        if (KMPSearch(pat, col)):
            print("Vertical")
 
# Driver Code
mat=[['a', 'b', 'c', 'd', 'e'],
    ['f', 'g', 'h', 'i', 'j'],
    ['k', 'l', 'm', 'n', 'o'],
    ['p', 'q', 'r', 's', 't'],
    ['u', 'v', 'w', 'x', 'y']]
pat= "pqrs"
 
findOrientation(mat, pat)
 
# This code is contributed by Mohit kumar 29


C#
// C# program for finding orientation of
// the pattern using KMP pattern searching
// algorithm
using System;
 
class GFG{
     
public static int N = 5;
 
// Used in KMP Search for preprocessing the pattern 
public static void computeLPSArray(char[] pat,
                                   int M, int[] lps)
{
     
    // Length of the previous longest
    // prefix suffix
    int len = 0;
    int i = 1;
     
    // lps[0] is always 0
    lps[0] = 0;
     
    // The loop calculates lps[i]
    // for i = 1 to M-1
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++; 
            lps[i++] = len;
        }
        else    // (pat[i] != pat[len]) 
        {
            if (len != 0)
            {
                 
                // This is tricky. Consider the
                // example AAACAAAA and i = 7. 
                len = lps[len - 1];
                 
                // Also, note that we do not
                // increment i here
            }
             
            // If (len == 0)
            else    
            {
                lps[i++] = 0;
            }
        }
    }
}
 
public static int KMPSearch(char[] pat, char[] txt)
{
    int M = pat.Length;
     
    // Create lps[] that will hold the longest 
    // prefix suffix values for pattern 
    int[] lps = new int[M];
    int j = 0; // index for pat[]
     
    // Preprocess the pattern
    // (calculate lps[] array) 
    computeLPSArray(pat, M, lps);
    int i = 0; // index for txt[]
     
    while (i < N)
    {
        if (pat[j] == txt[i])
        {
            j++;
            i++;
        }
        if (j == M)
        {
             
            // Return 1 is pattern is found 
            return 1;
        }
         
        // Mismatch after j matches
        else if (i < N && pat[j] != txt[i])
        {
             
            // Do not match lps[0..lps[j-1]]
            // characters, they will match anyway
            if (j != 0)
            {
                j = lps[j - 1];
            }
            else
            {
                i = i + 1;
            }
        }
    }
     
    // Return 0 is pattern is not found
    return 0;
}
 
// Function to find orientation of pattern
// in the matrix. It uses KMP pattern
// searching algorithm
public static void findOrientation(char[,] mat,
                                   char[] pat)
{
     
    // Allocate memory for string
    // containing cols
    char[] col = new char[N];
    for(int i = 0; i < N; i++)
    {
         
        // Allocate memory for string
        // containing rows
        char[] row = new char[mat.GetLength(1)];
        for(int j = 0; j < mat.GetLength(1); j++)
        {
            row[j] = mat[i, j];
        }
         
        // Search in row i
        if (KMPSearch(pat, row) == 1)
        {
            Console.WriteLine("Horizontal");
            return;
        }
         
        // Construct an array to store
        // i'th column
        for(int j = 0; j < N; j++)
        {
            col[j] = mat[j,i];
        }
         
        // Search in column i 
        if (KMPSearch(pat, col) == 1)
        {
            Console.WriteLine("Vertical");
        }
    }
}
 
// Driver Code
static public void Main()
{
    char[,] mat = { { 'a', 'b', 'c', 'd', 'e' },
                    { 'f', 'g', 'h', 'i', 'j' },
                    { 'k', 'l', 'm', 'n', 'o' },
                    { 'p', 'q', 'r', 's', 't' },
                    { 'u', 'v', 'w', 'x', 'y' } };
    char[] pat = {'p','q','r','s'};
     
    findOrientation(mat, pat);
}
}
 
//  This code is contributed by rag2127


Javascript


输出:

Horizontal