Given a pattern and a string s, find if s follows the same pattern.

Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in s.

Example 1:

Input: pattern = "abba ", s = "dog cat cat dog " Output: true

Example 2:

Input: pattern = "abba ", s = "dog cat cat fish " Output: false

Example 3:

Input: pattern = "aaaa ", s = "dog cat cat dog " Output: false

Constraints:

  • 1 <= pattern.length <= 300
  • pattern contains only lower-case English letters.
  • 1 <= s.length <= 3000
  • s contains only lowercase English letters and spaces ' '.
  • s does not contain any leading or trailing spaces.
  • All the words in s are separated by a single space.

Note: This problem is from LeetCode.
Compiled
Executed
Correct
program main
    implicit none

    character(len=*), parameter :: pattern = "abba "
    character(len=*), parameter :: s1 = "dog cat cat dog "
    character(len=*), parameter :: s2 = "dog cat cat fish "
    character(len=*), parameter :: s3 = "dog cat cat dog"

    logical :: result1, result2, result3

    result1 = follows_pattern(pattern, s1)
    result2 = follows_pattern(pattern, s2)
    result3 = follows_pattern(pattern, s3)

    write (*,*) result1
    write (*,*) result2
    write (*,*) result3

contains

    function follows_pattern(pattern, s) result(result)
        implicit none
        character(len=*), intent(in) :: pattern
        character(len=*), intent(in) :: s
        integer :: i, j, k
        logical :: result

        result = .false.

        ! Check if the length of the pattern and the input string are equal
        if (len(trim(pattern)) /= len(trim(s))) return

        ! Check if the pattern and the input string have the same number of words
        do i = 1, len(trim(pattern))
            if (index(trim(pattern), ' ') /= index(trim(s), ' ')) return
        end do

        ! Check if there is a bijection between each letter in the pattern and a non-empty word in the input string
        do i = 1, len(trim(pattern))
            k = index(trim(pattern), ' ')
            do j = 1, len(trim(s))
                if (trim(s)(j:j) == trim(pattern)(i:i)) then
                    if (trim(s)(k+1:) /= '') then
                        result = .true.
                        exit
                    end if
                end if
            end do
        end do

    end function follows_pattern

end program main
Compiled
Executed
Correct
! This script solves the problem of finding if a string follows a pattern.
! The pattern is given as a string, and the string to be checked is given as another string.
! The program should output "true" if the string follows the pattern, and "false" otherwise.

! Declare variables
integer :: i, j, k, l, m
character(len=300) :: pattern, s
character(len=3000) :: temp
logical :: found

! Read input from stdin
read(*,*) pattern
read(*,*) s

! Initialize variables
i = 1
j = 1
k = 1
l = 1
m = 1
found = .false.

! Check if the pattern is a palindrome
if (pattern(1:i) == pattern(len(pattern):-1:-1)) then
    ! The pattern is a palindrome, so we can use it to check if the string follows the pattern
    do while (j <= len(s))
        ! Check if the current character in the string matches the current character in the pattern
        if (s(j:j) == pattern(i:i)) then
            ! The current character in the string matches the current character in the pattern, so we move on to the next character in the string
            j = j + 1
            i = i + 1
        else
            ! The current character in the string does not match the current character in the pattern, so we move on to the next character in the pattern
            i = i + 1
        end if
        ! Check if we have reached the end of the pattern
        if (i > len(pattern)) then
            ! We have reached the end of the pattern, so we are done
            found = .true.
            exit
        end if
    end do
else
    ! The pattern is not a palindrome, so we need to use it to check if the string follows the pattern
    do while (j <= len(s))
        ! Check if the current character in the string matches the current character in the pattern
        if (s(j:j) == pattern(i:i)) then
            ! The current character in the string matches the current character in the pattern, so we move on to the next character in the string
            j = j + 1
            i = i + 1
        else
            ! The current character in the string does not match the current character in the pattern, so we move on to the next character in the pattern
            i = i + 1
        end if
        ! Check if we have reached the end of the pattern
        if (i > len(pattern)) then
            ! We have reached the end of the pattern, so we are done
            found = .true.
            exit
        end if
    end do
end if

! Output the result
if (found) then
    write(*,*) "true"
else
    write(*,*) "false"
end if

end
🌐 Data from online sources
def word_pattern(pattern, s):
    words = s.split()
    if len(pattern) != len(words):
        return False

    char_map, word_map = {}, {}
    for c, word in zip(pattern, words):
        if c not in char_map and word not in word_map:
            char_map[c] = word
            word_map[word] = c
        else:
            if char_map.get(c) != word or word_map.get(word) != c:
                return False

    return True
1. First, split the string 's' into words array based on the space-delimited words.
  1. Check if the length of the pattern and words array is the same, otherwise return false.
  2. Create two maps (hash tables/dictionaries) - one for storing the mapping from a pattern character to a word, and the other for mapping from a word to a pattern character.
  3. Iterate through the pattern and the words array simultaneously using a loop.
  4. If a pattern character and word are not in the respective maps, save the corresponding mapping in both maps.
  5. If they exist, compare the mappings; if they differ, immediately return false.
  6. After the loop is completed, if there is no mismatch, return true.
🌐 Data from online sources
#include <string>
#include <unordered_map>
#include <sstream>
using namespace std;

bool wordPattern(string pattern, string s) {
    unordered_map<char, string> char_map;
    unordered_map<string, char> word_map;
    stringstream ss(s);

    int i = 0;
    for (string word; ss >> word; ++i) {
        if (i == pattern.size()) return false;
        char c = pattern[i];
        if (char_map.count(c) == 0 && word_map.count(word) == 0) {
            char_map[c] = word;
            word_map[word] = c;
        } else {
            if (char_map[c] != word || word_map[word] != c) return false;
        }
    }

    return i == pattern.size();
}
1. First, split the string 's' into words array based on the space-delimited words.
  1. Check if the length of the pattern and words array is the same, otherwise return false.
  2. Create two maps (hash tables/dictionaries) - one for storing the mapping from a pattern character to a word, and the other for mapping from a word to a pattern character.
  3. Iterate through the pattern and the words array simultaneously using a loop.
  4. If a pattern character and word are not in the respective maps, save the corresponding mapping in both maps.
  5. If they exist, compare the mappings; if they differ, immediately return false.
  6. After the loop is completed, if there is no mismatch, return true.