typescript ES6中的二进制模式匹配(pattern,s)作为字符串

m0rkklqb  于 2023-01-27  发布在  TypeScript
关注(0)|答案(5)|浏览(131)

给定两个字符串pattern和s,第一个字符串pattern只包含符号0和1,第二个字符串s只包含小写英语字母。
假设pattern匹配s的子字符串s[l..r],前提是满足以下3个条件:
1.它们具有相等的长度;
1.对于模式中的每个0,子串中的对应字母是元音;
1.对于每个1 in模式,对应的字母是辅音。任务是计算与pattern匹配的s的子串的数目。
注:这里我们定义元音为aeiouy,其他字母都是辅音。
我不是在挑战这里的任何人,我已经尝试了不同的方法,但无法实现。这个问题是问在代码信号测试评估最近。

wfsdck30

wfsdck301#

以下是我解决这个问题的方法。
将所有0替换为pattern中的匹配元音的正则表达式,将1替换为pattern中的非元音(检查输入之后),并将其用作s上的正则表达式(具有重叠),可以帮助我们满足需求集。

function matchOverlap(input, re) {
  var r = [],
    m;
  // prevent infinite loops
  if (!re.global) re = new RegExp(
    re.source, (re + '').split('/').pop() + 'g'
  );
  while (m = re.exec(input)) {
    re.lastIndex -= m[0].length - 1;
    r.push(m[0]);
  }
  return r;
}

function algorithm(pattern, s) {
  const VOWELS = 'aeiouy'

  if (pattern.match('[^01]'))
    throw new Error('only 0 and 1 allowed in pattern')
  else if (s.match('[^a-z]'))
    throw new Error('only a-z allowed in s')

  const generatedRegex = new RegExp(
    pattern
      .replace(/0/g, `[${VOWELS}]`)
      .replace(/1/g, `[^${VOWELS}]`),
    'g')

  console.log("GENERATED REGEX:", generatedRegex)

  const matches = matchOverlap(s, generatedRegex)
  console.log("MATCHES:", matches)
  return matches.length
}


console.log("FINAL RESULT: " + algorithm('101', 'wasistdas'))

// the following throws error as per the requirement
// console.log(algorithm('234234', 'sdfsdf'))
// console.log(algorithm('10101', 'ASDFDSFSD'))

使用的matchOverlap函数取自this answer

jdg4fx2g

jdg4fx2g2#

您可以先检查长度,然后使用正则表达式检查测试中的辅音是否符合模式和计数。

function getCount(pattern, s) {
    if (pattern.length !== s.length) return false;
    const regExp = /^[^aeiouy]$/;
    let count = 0;
    
    for (let i = 0; i < pattern.length; i++) {
        if (+regExp.test(s[i]) === +pattern[i]) count++;
    }
    return count;
}

console.log(getCount('010', 'ama'));
jtjikinw

jtjikinw3#

你应该把输入字符串转换成二进制格式。

function convertToBinary(source) {
  var vowels = 'aeiouy'
  var len = source.length
  var binaryStr = ''
  for (i = 0; i < len; i++) {
    binaryStr += vowels.includes(source[i]) ? '0' : '1'
  }
  return binaryStr
}

function isMatch(txt, pattern) {
  return txt === pattern
}

function findMatches(source, pattern) {
  var binaryString = convertToBinary(source)
  var result = []
  var patternLen = pattern.length
  for (var i = 0; i < binaryString.length - patternLen; i++) {
    if (isMatch(binaryString.substr(i, patternLen), pattern)) {
      result.push(source.substr(i, patternLen))
    }
  }
  return result
}

var text = 'thisisaresultoffunction'
var pattern = '1011'

console.log(findMatches(text, pattern))

其结果

[ "sult", "toff", "func" ]
cvxl0en2

cvxl0en24#

这是一个蛮力C#版本

int binaryPatternMatching(string pattern, string s) {
    int count = 0;
    char[] vowel = {'a', 'e', 'i', 'o', 'u', 'y'};
    for(int i=0; i<=(s.Length - pattern.Length); i++){
        int k=i;
        bool match = true;
        bool cTM = true;
        int j=0;
        
        while(match == true && j < pattern.Length){
            if(pattern[j] == '0')
            {
                if(vowel.Contains(s[k])){
                    cTM = true;
                }
                else{
                    cTM = false;
                }
            }
            else
            {
                if(!vowel.Contains(s[k])){
                    cTM = true;
                }
                else{
                    cTM = false;
                }
            }
            k += 1;
            j += 1;
            
            match = (match && cTM);
        }
        if(match){
            count += 1;
        }
    }
    return count;
}

可以被优化

t1qtbnec

t1qtbnec5#

明白了!再看看这个question
正则表达式库比环更强大

import regex as re
   
def pattern_finder(pattern,source):
    
    vowels = ['aeouiy'] 

    # using list comprehension to build the regular expression
    reg_ex = "".join(['[aeiouy]' if num=='0' else '[^aeiouy]' for num in pattern ])
   
    #finding overlapped patterns
    matches = re.findall(reg_ex, source, overlapped=True)
   
    
    return len(matches)

相关问题