根据javascripty

时间:2018-07-03 19:39:13

标签: javascript string

今天在JavaScript技术采访中有人问我这个问题,但我失败了,但仍然找不到解决方案。我想出的问题和解决方案如下。我通过了一些测试用例,但是代码仍然不能在每种情况下都起作用。如果有人可以帮助我有效地解决问题,我将不胜感激。


系统会为您提供一个字符串输入,由大小写不同的字母组成。

这些字母应根据大小写彼此配对。例如,字母“ N”与字母“ a”按此顺序形成“匹配对”。

规则:

  1. 首字母必须大写。
  2. 每个大写字母后必须跟小写字母或任何大写字母。
  3. 当大写字母后跟小写字母时,这两个字母被视为“匹配对,因此可以从进一步的匹配考虑中忽略。”
  4. 如果这些规则中的任何一个被破坏,或者遇到了一个小写字母,但没有与其最不匹配的左邻居创建“匹配对”,则该字母和所有后续字母均被视为“不匹配”。

输出:您的方法应返回最后一个匹配的小写字母的从零开始的索引;如果不存在对,则返回-1。

限制:0 < input length < 10,000个字符最佳方法的运行时间为O(输入长度​​)。

样本输入#1

ABba

样品输出#1

3

这是我所做的,但是它不适用于每个测试用例;

function stringMatch(str){

  let word=str.split("")
  let lastIndex;

  if (word[0]===word[0].toUpperCase()){
    for(let i=0;i<word.length;i++){
      if(word[i]===word[i].toUpperCase()){
        if(word[i].toLowerCase()===word[i+1] || word[i+1]===word[i+1].toUpperCase() ){
          lastIndex=i
        }
        else{
          return -1
        }
      }
      else{
        lastIndex=i
      }

    }
    return lastIndex
  }

}

2 个答案:

答案 0 :(得分:1)

一个很好的方法是使用一个包含大写字母的堆栈。堆栈的下一个元素应始终是您要匹配的下一个小写字母。

遍历字符串,对于每个字母(如果大写),将其压入堆栈并继续。如果是小写字母,则从堆栈中弹出一个并进行比较。如果匹配,则将索引设置为最后匹配的索引,然后继续操作;如果不匹配,则返回最后匹配的索引。

const isUpper = (l) => l === l.toUpperCase()

function findUnmatchedIndex(str)  {
    let stack = []
    let lastMatch = -1
    for (let i = 0; i < str.length; i++) {
        let letter = str[i]
        if (isUpper(letter)) {
            stack.push(letter);
            continue;
        }
        let next = stack.pop()
        if (next !== letter.toUpperCase()) return lastMatch
        lastMatch = i
    }
    return lastMatch

}

console.log(findUnmatchedIndex('ABba'))
console.log(findUnmatchedIndex('ABCcDEedFeGHi'))
console.log(findUnmatchedIndex('ABCbDEedFeGHi'))

答案 1 :(得分:0)

没有更多的测试用例,对此我不确定。但这看起来可能符合要求。

const isLower = (c) => 'a' <= c && c <= 'z'
const final = (stack) => stack[stack.length - 1]
const initial = (stack) => stack.slice(0, stack.length - 1)

const check = (str) => str.split('').reduce(
  ({lastIndex, failed, stack}, c, idx) => 
    failed
    ? {lastIndex, failed, stack}  // one reason not to do this with reduce.
    : isLower(c)
      ? c === final(stack)
        ? {lastIndex: idx, failed, stack: initial(stack)}  
        : {lastIndex, failed: true, stack}
      : {lastIndex, failed, stack: stack.concat(c.toLowerCase())},
  {lastIndex: -1, failed: false, stack: []}
).lastIndex


console.log(check('ABba'))