Daily-Interview-Question icon indicating copy to clipboard operation
Daily-Interview-Question copied to clipboard

第 71 题: 实现一个字符串匹配算法,从长度为 n 的字符串 S 中,查找是否存在字符串 T,T 的长度是 m,若存在返回所在位置。

Open ZodiacSyndicate opened this issue 5 years ago • 62 comments

const find = (S, T) => {
  if (S.length < T.length) return -1
  for (let i = 0; i < S.length; i++) {
    if (S.slice(i, i + T.length) === T) return i
  }
  return -1
}

ZodiacSyndicate avatar May 10 '19 01:05 ZodiacSyndicate

// 因为 T 的 length 是一定的,所以在循环S的的时候 ,循环当前项 i 后面至少还有 T.length 个元素
const find = (S, T) => {
  if (S.length < T.length) return -1;
  for (let i = 0; i < S.length - T.length ; i++) {
      if (S.substr(i, T.length) === T) return i ;
  };
  return -1;
};

jjeejj avatar May 10 '19 01:05 jjeejj

const find = (S,T) => S.indexOf(T)

keiseiTi avatar May 10 '19 02:05 keiseiTi

var position = [];

const find = (S, T) => {
	if (S.length < T.length) {
		position.push(-1);
	} else {
		for (let i = 0; i < S.length; i++) {
			if (S.slice(i, i + T.length) === T) {
				position.push(i);
			}
		}
	}
}

find(S,T);

sgzhm4444 avatar May 10 '19 02:05 sgzhm4444

// 方法一:
const find = (S, T) => S.search(T)

// 方法二:
const find = (S, T) => {
  const matched = S.match(T) 
  return matched ? matched.index : -1 
}

JayZangwill avatar May 10 '19 03:05 JayZangwill

var find = function(S,T){

  if(T.length > S.length) return -1;
    
  let index = S.indexOf(T);
  let count = [];

  while(index != -1){
    count.push(index);
    index = S.indexOf(T,index + T.length);
   }

    return count;

}

indexOf 可以直接返回字符串所在的位置,但同时是否需要考虑,如果T在S中重复出现的,需要将两个位置都展示出来?

Vdan123 avatar May 10 '19 03:05 Vdan123

我的核心思想是使用 split,假设未匹配到返回-1

let findIndex = (S, T) => {
  let index = -1
  if (!T.length || T.length > S.length) return index // T 为空字符串或 T 的长度大于 S 均直接返回-1
  const arr = S.split(T)
  if (arr.length > 1) index = arr[0].length
  return index
}

findIndex('FishPlusOrange', 'Plus') // 4
findIndex('FishPlusOrange', 'sulP') // -1

需要注意的是,在以上算法中,如果字符串 S 中存在多个字符串 T,仅返回第一个的位置

FishPlusOrange avatar May 10 '19 04:05 FishPlusOrange

function e(s, t){
  let reg = new RegExp(t, 'g');
  let tArray = [];
  let result = [];
  while((tArray = reg.exec(s)) !== null){
     result.push(tArray.index);
  }
  
  return result;
}

kingstone3 avatar May 10 '19 04:05 kingstone3

function Test(s, t){ if(s.length < t.length){ return -1; }else{ return s.indexOf(t); } }

FounderIsShadowWalker avatar May 10 '19 05:05 FounderIsShadowWalker

用了API的是不是不太体面?

  getIndexOf = function (s, t) {
    let n = s.length;
    let m = t.length;
    if (!n || !m || n < m) return -1;
    for (let i = 0; i < n; i++) {
      let j = 0;
      let k = i;
      if (s[k] === t[j]) {
        k++; j++;
        while (k < n && j < m) {
          if (s[k] !== t[j]) break;
          else {
            k++; j++;
          }
        }
        if (j === m) return i;
      }
    }
    return -1;
  }

image image

LiuMengzhou avatar May 10 '19 05:05 LiuMengzhou

我的核心思想是使用 split,假设未匹配到返回-1

let findIndex = (S, T) => {
  if (!T.length || T.length > S.length) return -1 // T 为空字符串或 T 的长度大于 S 均直接返回-1
  return S.split(T)[0].length
}

findIndex('FishPlusOrange', 'Plus') // 4

需要注意的是,在以上算法中,如果字符串 S 中存在多个字符串 T,仅返回第一个的位置

@FishPlusOrange image

LiuMengzhou avatar May 10 '19 05:05 LiuMengzhou

我的核心思想是使用 split,假设未匹配到返回-1

let findIndex = (S, T) => {
  if (!T.length || T.length > S.length) return -1 // T 为空字符串或 T 的长度大于 S 均直接返回-1
  return S.split(T)[0].length
}

findIndex('FishPlusOrange', 'Plus') // 4

需要注意的是,在以上算法中,如果字符串 S 中存在多个字符串 T,仅返回第一个的位置

你这种方法没有考虑S不存在T的情况,按你这种方法如果不存在的话,返回的是S的长度

Tangjj1996 avatar May 10 '19 05:05 Tangjj1996

@LiuMengzhou @Tangjj1996 感谢提醒,已经改正

FishPlusOrange avatar May 10 '19 06:05 FishPlusOrange

请问下这题主要考什么?为啥indexOf不行?

goodwinfame avatar May 10 '19 08:05 goodwinfame

// 因为 T 的 length 是一定的,所以在循环S的的时候 ,循环当前项 i 后面至少还有 T.length 个元素
const find = (S, T) => {
  if (S.length < T.length) return -1;
  for (let i = 0; i < S.length - T.length ; i++) {
      if (S.substr(i, T.length) === T) return i ;
  };
  return -1;
};

循环条件要改成这样吧

i < S.length - T.length + 1

cheungkin24 avatar May 13 '19 07:05 cheungkin24

我觉得是考KMP算法吧

LiuL0703 avatar May 15 '19 14:05 LiuL0703

var S, T;
var next = [];

// 预计算next数组
function getNext() {
	let k = -1,
		j = 0;
	next[0] = -1;
	while (j < len_t) {
		if (k == -1 || T[j] == T[k]) {
			++j;
			++k;
			next[j] = k;
		} else k = next[k];
	}
}

// 返回子串首次出现的位置
function KMP_Index() //T是模式串,S是 主串 
{
	let i = 0,
		j = 0;
	getNext();
	while (j < len_t && i < len_s) {
		if (j == -1 || T[j] == S[i]) {
			i++;
			j++;
		} else j = next[j];
	}
	if (j == len_t) {
		return i - len_t;
	} else return -1;
}

//返回子串出现的次数
function KMP_Count() {
	let ans = 0;
	let i = 0,
		j = 0;

	getNext();
	for (i = 0; i < len_s; i++) {
		while (j > 0 && T[j] != S[i]) {
			j = next[j];
		}
		if (T[j] == S[i]) j++;
		if (j == len_t) {
			ans++;
			j = next[j];
		}
	}
	return ans;
}

S = "123454321";
T = "0"
len_s = S.length;
len_t = T.length;

//KMP_Index()如果为-1则没有匹配
console.log(`主串为${S},模式串为${T},模式串首次出现的位置为${KMP_Index()},出现的次数为${KMP_Count()}`);

image

本质上为KMP算法或者KMP的优化,只要理解next数组的意义和推导,字符串匹配的题目万变不离其宗。

(附上很早之前做的这个算法的PPT链接。。。 http://note.youdao.com/noteshare?id=91749237e787b4aa0b246336ea0c1137 )

ZhangMingZhao1 avatar May 15 '19 15:05 ZhangMingZhao1

const find = (S, T) => {   const indexList = [];   if(S.length < T.length) return -1;   for(let i = 0; i <= S.length - T.length; i++) {     if(S.slice(i, i + T.length) === T) indexList.push(i)    }   return indexList.length? indexList : -1; }

ckjie avatar Jun 24 '19 13:06 ckjie


//  考查indexOf
const includeString = (parent, child) => parent.indexOf(child);

console.log( includeString('hello, my name is dorsey', 'dorsey') );

dorseysen avatar Jun 27 '19 09:06 dorseysen

搜索了一下KMP算法: https://zh.wikipedia.org/wiki/%E5%85%8B%E5%8A%AA%E6%96%AF-%E8%8E%AB%E9%87%8C%E6%96%AF-%E6%99%AE%E6%8B%89%E7%89%B9%E7%AE%97%E6%B3%95

// 应该...没有bug吧^^
function getIndex (S, T) {
  const n = S.length;
  const m = T.length;
  if (n < m) {
    return -1;
  }
  if (n === m) {
    return S === T ? 0 : -1;
  }

  const start = T[0];
  const end = T[m - 1];
  let i = 0;

  while (i < n) {
    if (n - i < m) {
      return -1;
    }

    const currS = S[i];
    const currSEnd = S[i + m - 1];
    let mathing = true;

    if (currS !== start || currSEnd !== end) {
      i++;
      continue;
    }

    let j = 0;
    let step = 0;

    while (j < m) {
      const currS = S[i + j];
      const currSEnd = S[i + j + m - 1];
      const isEnd = j === m - 1;

      if (mathing) {
        const currW = T[j];
        mathing = currS === currW;

        if (mathing && isEnd) {
          return i
        }
      }
      
      if (!mathing && step !== 0) {
        break;
      }

      if (j > 0 && step === 0) {
        if (isEnd) {
          step = m;
        }
        if (currS === start && currSEnd === end) {
          step = j;
        }
      }
      j++;
    }
    i += step || 1;
  }

  return -1;
}

dongj0316 avatar Jun 27 '19 10:06 dongj0316

var a='abcdefghijkl'
var b='ghi'
var aL=a.length;
var bL=b.length;

function indexOf(str,item){
	for(var i=0;i<=aL-bL;i++){
		if(str.slice(i,bL+i)==item){
			return i
		}
	}
}

console.log(indexOf(a,b))
function idnexOf(a,b){
	var reg=new RegExp(`${b}`,'gi');
	var c=reg.exec(a);
	console.log(c ? c.index : -1)
}

var a = 'abcdefghijkl'
var b = 'jkl'
idnexOf(a,b)

libin1991 avatar Jul 09 '19 16:07 libin1991

image

xyxiao001 avatar Jul 12 '19 06:07 xyxiao001

function findStr(str, f){ var reg = new RegExp(f, 'g'); return reg.exec(str).index; };

hudie09143672 avatar Jul 12 '19 07:07 hudie09143672

呃,String.prototype.indexOf的功能不就是干这个的么?

qiannianchong25 avatar Jul 26 '19 13:07 qiannianchong25

// 因为 T 的 length 是一定的,所以在循环S的的时候 ,循环当前项 i 后面至少还有 T.length 个元素
const find = (S, T) => {
  if (S.length < T.length) return -1;
  for (let i = 0; i < S.length - T.length ; i++) {
      if (S.substr(i, T.length) === T) return i ;
  };
  return -1;
};

image 这里S.length - T.length有点小错误,应该改为S.length

dengshangli avatar Jul 29 '19 12:07 dengshangli

const strA = "qwertyuiopasfghjkasdflzxcvbnm";

const strB = "asdf";

function findStr(str1, str2) {
    const len = str2.length;
    const indexArr = [];
    str1.split("").forEach((v, i) => {
        if (v === str2[0]) indexArr.push(i);
    });
    let result;
    if (!indexArr.length) return "不存在相同的字符串";
    indexArr.forEach(idx => {
        result = str1.slice(idx, idx + len) === str2 ? idx : null;
    });
    return result;
}

console.log(findStr(strA, strB));

ZYSHINee avatar Jul 30 '19 03:07 ZYSHINee

// 因为 T 的 length 是一定的,所以在循环S的的时候 ,循环当前项 i 后面至少还有 T.length 个元素
const find = (S, T) => {
  if (S.length < T.length) return -1;
  // 包含多个该元素
  let ilist = []
  for (let i = 0; i < S.length - T.length ; i++) {
      if (S.substr(i, T.length) === T) ilist.push(i);
  };
  let _returnIndex = ilist.length < 1 ? -1 : ilist
  return _returnIndex;
};

Stevendwy avatar Aug 01 '19 06:08 Stevendwy

最高票的答案写的很好,不过还是不知道为啥不能用indexOf?因为面试题用indexOf太low了么?还是考察点不在这上

SpengF avatar Aug 02 '19 03:08 SpengF

const find = (S,T) => S.indexOf(T)

这个实现的有问题?

montage-f avatar Aug 02 '19 08:08 montage-f

最高票的答案写的很好,不过还是不知道为啥不能用indexOf?因为面试题用indexOf太low了么?还是考察点不在这上

我也想知道这个问题, 难道indexOf 不能实现?

montage-f avatar Aug 02 '19 08:08 montage-f

最高票的答案写的很好,不过还是不知道为啥不能用indexOf?因为面试题用indexOf太low了么?还是考察点不在这上

我也想知道这个问题, 难道indexOf 不能实现?

这里题目考的是算法实现,不是api运用

Xu-Angel avatar Aug 20 '19 05:08 Xu-Angel

/* KMP的优化算法 (寻找匹配字符串的前缀与后缀最大公共长度,该值仅仅与匹配字符串相关)*/

function index(string, searchString) {
  let next = getLongestPS(searchString);
  let i = 0,
      j = 0;
  while (i <= (string.length - 1) && j <= (searchString.length - 1)) {
      if (string[i] === searchString[j]) {
          i++;
          j++;
      } else {
          // 注意当不匹配时,并不移动字符串,而是移动匹配字符串。(回溯)
          if (j == 0) {
            // 当匹配字符串和字符串第一位不匹配时。继续向后移动字符串。
              i++;
          } else {
              j = next[j];
          }
      }
  }
  if (j > searchString.length - 1) {
      return i - searchString.length;
  }
  return -1;
}


/*
* longestPS
* 求一段字符串的前缀与后缀的最大公共长度;
* */
function getLongestPS(searchString) {
  let i = 0;
  let next = [0];
  let j = 1;
  while (j < searchString.length) {
      if (searchString[i] == searchString[j]) {
          next[j] = i + 1;
          i++;
          j++;
      } else {
          if (i == 0) {
              next[j] = 0
              j++;
          } else {
              i = next[i - 1];
          }
      }
  }
  return next;
}

let string = "sdfabasdlfsaslfjslkadadfjlabab";
let searchString = "abab";

console.log(index(string, searchString));
console.log(string.indexOf(searchString));

chengwen-zheng avatar Aug 21 '19 06:08 chengwen-zheng

// 为啥不用,项目开发中难道现成的不用,还写一堆自拟定API?表示无法理解。
function searchIndex(S, T, num = 0) {
  return S.match(new RegExp(T, 'g')).map((_, i) => {
    return (num = S.indexOf(T, num + 1));
  });
}
console.log(searchIndex('Hello World', 'o'));

yaodongyi avatar Sep 10 '19 08:09 yaodongyi

// 因为 T 的 length 是一定的,所以在循环S的的时候 ,循环当前项 i 后面至少还有 T.length 个元素
const find = (S, T) => {
  if (S.length < T.length) return -1;
  for (let i = 0; i < S.length - T.length ; i++) {
      if (S.substr(i, T.length) === T) return i ;
  };
  return -1;
};

There will be bugs if S===T

callmezhenzhen avatar Sep 19 '19 01:09 callmezhenzhen

const find = (S, T) => {
  if (S.length < T.length) return -1
  for (let i = 0; i < S.length; i++) {
    if (S.slice(i, i + T.length) === T) return i
  }
  return -1
}

这样是不是更简单一些呀

const find = (str, t)=> Array.from(str).findIndex((value)=> value === t)  

loycoder avatar Nov 17 '19 14:11 loycoder

这题考的是 KMP 算法:

名词

  • 主串 (文本串)
  • 子串 (模式串)

概念

相比于傻瓜式的字符串匹配,即在遍历主子串时,一旦出现对应位置的字符不匹配,主子串都要回溯后再重新遍历匹配。

其实已匹配过的字符,再去回溯匹配是多余,因为前面的字符已经一一匹配对应了,你再右移后就错位了,肯定不会匹配。

KMP 算法就是为了避免主串回溯,子串右移已匹配的最大位数,来避免明知道不会匹配的无效移位。

原理

  • 给定模式串时,模式串自身的部分匹配数就已知了。也就是最大的前缀和后缀长度。初始化这个位置后,我们就知道当遍历到模式串的一个字符发现与主串不匹配时,直接右移到前缀和后缀一致的位置,也就是公式:
右移数 = 已匹配数 - 最大的部分匹配数
  • 在遍历时,主串不必回溯,主串的回溯是多余的,遍历过一次后就已知与子串是否匹配了。

Jmingzi avatar Nov 23 '19 02:11 Jmingzi

@jjeejj S.length - T.length 无法获取 T处于 S 最后处这种情况,应该改为 S.length - T.length + 1

NARUTOne avatar Dec 04 '19 03:12 NARUTOne

const findStr = (str, t) => {
	if (t.length > str.length) return -1;
	for (let index = 0; index < str.length - t.length + 1; index++) {
		const cur = str.slice(index, index + t.length);
		if (cur === t) {
			return index;
		}
	}
};

console.log(find('asdfg', 'sdf'));

coveyz avatar Jan 06 '20 09:01 coveyz

function search(str, str1) {
    if (str.includes(str1)) {
        return str.indexOf(str1);
    } else {
        return -1;
    }
}

shenxuxiang avatar Feb 05 '20 01:02 shenxuxiang

首先是用了slice的 这个贼简单:

function matching(n, str, m, match){
	if(m>n){
		return -1;
	}

	for(let i = 0; i<n-m+1; i++){
		if(str.slice(i,i+m)===match){
			return i;

		}
	}
	return -1;
}

然后我也记得我本科的时候算法课专门有节课讲了pattern matching 回去找了下课件果然是KMP 我结合了阮老师的这个http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 下面是我KMP的写法:

function partialMatchTable(str, n){
	let res = [0];
	let k = 0;
	for(let i=1; i<n; i++){
		while(k>0&&str[k]!==str[i]){
			k = res[k-1];
		}
		if(str[k]===str[i]){
			k += 1
		}
		res.push(k);

	}
	return res;

}

function KMP(n, str, m, match){
        if(m>n) return -1;
	let index = 0;
	let table = partialMatchTable(match, n);
        console.log(table);
	while(index<n){
		let same = 0;
		let index2 = 0;
		while(str[index+index2]===match[index2]&&index2<m){
			same += 1;
			index2 += 1;
		}
		if(same===m){
			return index;
		}
        if(same===0){
        	index += 1;
        }else{
        	index += same - table[same-1];
        }

	}
	return -1;
}

console.log(KMP(15, "ABDCABABDCABDCB", 7, "ABDCABD")) 

结果在这里哈: Screen Shot 2020-03-05 at 11 05 03 PM

欢迎指正!!

SerinaJingyiLu avatar Mar 05 '20 15:03 SerinaJingyiLu

// 因为 T 的 length 是一定的,所以在循环S的的时候 ,循环当前项 i 后面至少还有 T.length 个元素
const find = (S, T) => {
  if (S.length < T.length) return -1;
  for (let i = 0; i < S.length - T.length ; i++) {
      if (S.substr(i, T.length) === T) return i ;
  };
  return -1;
};

@jjeejj

匹配到最后下标时候,find('123456','456') 为 -1,正确的值应该3; for (let i = 0; i < S.length - T.length ; i++) 中的i < S.length - T.length 少了👆的情况,改为i <= S.length - < T.length即可

dleged avatar Mar 20 '20 03:03 dleged

//  使用KMP实现  KMP 原理就是 减少text 串的 重复遍历 一次结束 时间复杂度O(m + n)

function KMP(pattern, text) {
  let n = pattern.length
  let m = text.length
  // 计算pattern 的prefix 数组
  let arr = new Array(n).fill(0)
  let i = 0
  let j = 1
  while (j < n) {
    if (pattern[i] === pattern[j]) {
      arr[j] = i + 1
      i ++ 
      j ++ 
    } else if (i === 0) {
      j ++
    } else {
      i = arr[i - 1]
    }
  }
  // 进行 比较查找
  let h = 0
  let k = 0
  let count = 0
  while (k < n) {
    if (text[h] === pattern[k]) {
      h ++
      k ++
      count ++ 
    } else if (k !== 0) {
      k = arr[k - 1] 
      count = 0
    } else {
      h ++
      count = 0
    }
  }

  if (count === n) {
    return h - n
  }
}

let text = 'acbacbabcbcabcabcbcabca' // 11
let pattern = 'abcabcb'
console.log(KMP(pattern, text))

litokele2018 avatar Mar 25 '20 09:03 litokele2018

const findStr = (str, t) => {
	if (t.length > str.length) return -1;
	for (let index = 0; index < str.length - t.length + 1; index++) {
		const cur = str.slice(index, index + t.length);
		if (cur === t) {
			return index;
		}
	}
};

coveyz avatar Apr 22 '20 06:04 coveyz

function findIdxs(S, T) {
  if (S.length < T.length) return []
  var reg = new RegExp(T, 'g')
  var arr = []
  do {
    var str = reg.exec(S)
    if (str && str.index > 0) {
      arr.push(str.index)
    }
  } while (str && str.index > 0);

  return arr
}
var S = 'hkjhkabclkkabcjk'
var T = 'abc'
console.log(findIdxs(S, T))

wubing0324 avatar May 07 '20 01:05 wubing0324

function searchIndex(s,t){ let i = 0; let j = 0; let idx = -1; while(s.length-i >= t.length - j && j !== t.length){ if(s[i]===t[j]){ if(j==0){ idx = i; } j++; }else{ idx = -1; } i++; } return idx; }

snowBoby avatar May 31 '20 13:05 snowBoby

最高票的答案写的很好,不过还是不知道为啥不能用indexOf?因为面试题用indexOf太low了么?还是考察点不在这上

我觉得是问题是想问 indexof 的实现算法,不是 api 的运用。

jakesamz avatar Jun 13 '20 16:06 jakesamz

// 暴力破解
let text = 'ABABABCABAAABABABABCABAA'
let pattern = 'ABABCABAA'
function findSubString(s, t) {
  const n = s.length
  const m = t.length
  if(m > n) return ''
  if(s === t) return s
  let index = 0
  let i = 0, j = 0
  while(i < n) {
    while (j < m) {
      if(j === m - 1 && s[i] === t[j]) {
        console.log(`找到了匹配的位置索引是:${i - j}`)
        j = 0
        index ++
        i = index
      }
      if(s[i] === t[j]) {
        i++
        j++
      } else {
        j = 0
        index ++
        i = index
      }
    }
  }
}
findSubString(text, pattern)

// KMP算法
let text = 'ABABABCABAAABABABABCABAA'
let pattern = 'ABABCABAA'
function findPrefixTable (pattern) {
  let prefixTable = [0]
  let m = pattern.length
  let preLen = 0
  let i = 1
  while (i < m) {
    if(pattern[i] === pattern[preLen]) {
      preLen++
      prefixTable[i] = preLen
      i++
    } else {
      if(preLen > 0) {
        preLen = prefixTable[preLen - 1]
      } else {
        prefixTable[i] = preLen
        i++
      }
    }
  }
  return prefixTable
}
function movePreFixTable(prefixTable) {
  const temp = prefixTable
  temp.unshift(-1)
  temp.pop()
  return temp
}

function kmpSearch(text, pattern) {
  let n = text.length
  let m = pattern.length
  let i = 0, j = 0
  let prefixTable = movePreFixTable(findPrefixTable(pattern))
  while (i < n) {
    if(j === m - 1 && text[i] === pattern[j]) {
      console.log(`找到了匹配的位置索引是:${i - j}`)
      j = prefixTable[j]
    }
    if(text[i] === pattern[j]) {
      i++
      j++
    } else {
      j = prefixTable[j]
      if(j === -1) {
        i++
        j++
      }
    }
  }
}
kmpSearch(text, pattern)

xueshuai avatar Jun 26 '20 12:06 xueshuai

// 因为 T 的 length 是一定的,所以在循环S的的时候 ,循环当前项 i 后面至少还有 T.length 个元素
const find = (S, T) => {
  if (S.length < T.length) return -1;
  for (let i = 0; i < S.length - T.length ; i++) {
      if (S.substr(i, T.length) === T) return i ;
  };
  return -1;
};

for循环里的i应该小于S.length-T.length+1吧。您看看,是我理解错了还是您漏写了

xiaofangnihao avatar Jul 17 '20 09:07 xiaofangnihao

简单点的: 1、'abcde'.indexOf('bc'); 2、'abcde'.search('bc'); 3、'abcde'.match('bc'); 4、for循环查找m位是否相等

89466598946659 avatar Aug 23 '20 09:08 89466598946659

function findStr(S, T) {
  let currentIndex = 0
  let patch = []
  let reg = new RegExp(T)
  while(match = reg.exec(S)) {
    patch.push(match.index+ currentIndex)
    let index = match.index + T.length
    S = S.slice(index)
    currentIndex = index
  }
  return patch
}
findStr(S,T)

Gcalolin avatar Aug 27 '20 10:08 Gcalolin

一行搞定,注意要先判断S是否完整包含T,使用includes即可

```javascript
function findStr(S, T){
  return S.includes(T) ? S.indexOf(T) : -1
}

测试

const S1 = 'abcdefg', T1 = 'cde', T2 = 'fgh'
console.log(findStr(S1, T1)) // 2
console.log(findStr(S1, T2)) // -1

orime avatar Jan 30 '21 09:01 orime

调用API的话就search方法

function findIndex(str, target) {
            return str.search(target);
        }

滑动窗口方法:

function findIndex(str, target) {
            let need = {}, window = {};
            for (let item of target) {
                window[item] = 0;
                need[item] ? (need[item]++) : (need[item] = 1);
            }
            let left = 0, right = 0;
            let valid = 0; // 表示窗口中满足need条件的字符个数,如果valid等于need的大小,说明窗口已经满足条件,目标子串已全部覆盖
            let needLen = Object.keys(need).length;
            while (right < str.length) {
                // c是即将移入窗口的字符
                let c = str[right];
                // 右移窗口
                right++;
                // 进行窗口内数据的一系列更新
                if (need[c]) { // 如果即将移入窗口的字符是有效字符
                    window[c]++;
                    // 如果窗口内命中字符出现次数和需求中一样,有效标记++
                    if (window[c] === need[c]) {
                        valid++;
                    }
                }
                // 判断左侧窗口是否要收缩
                while (right - left >= target.length) {
                    if (valid === needLen) {
                        return left;
                    }
                    // 将要移出窗口的字符
                    let d = str[left];
                    left++;
                    // 移出窗口所导致的一系列数据更新
                    if (need[d]) {
                        if (need[d] === window[d]) {
                            valid--;
                        }
                        window[d]--;
                    }
                }
            }
            return str[left] === target[0] ? left : -1;
        }

ghost avatar Feb 23 '21 11:02 ghost

`function isExitF(total, small) { let isExit = false let left = 0 let right = small.length
while (right <= total.length) { let currentStr = total.substring(left, right) console.log(currentStr) if (currentStr === small) { return true } else { left += 1 right += 1 } }

return isExit

}`

shuai4983958 avatar Mar 03 '21 09:03 shuai4983958

/**
 * 字符串匹配,从长度为 n 的字符串 S 中,查找是否存在字符串 T,T 的长度是 m,若存在返回所在位置
 * 遍历 S,找出 S 和 T 第一个字符相同的位置 i,比较 i 到 i + T.length 这部分字符串是否 === T;如果不相同,则继续下一个字符;当遍历到 S 剩下的字符串长度小于 T 的长度,则退出循环
 */
function find(S, T) {
    for (let i = 0; i <= S.length - T.length; i++) {
        if (S[i] !== T[0]) {
            continue;
        }
        if (S.slice(i, i + T.length) === T) return i + 1;
    }
    return -1;
}

console.log(find('sjdjsds', 'sds'));

xiaocongWang avatar Apr 27 '21 04:04 xiaocongWang

应用正则应该是最简单的 S.match(eval('/'+T+'/')).index

haiyangzhishengs avatar Jul 07 '21 02:07 haiyangzhishengs

考虑性能的话 kmp 才是正解

hdsuperman avatar Nov 18 '21 10:11 hdsuperman

let str1 = "hellomasd,asdasdasdan";
let str2 = "asdasdasdan";
let fun = (base, target) => {
  let conditionLen = base.length - target.length;
  for (let i = 0; i <= conditionLen; i++) {
    if (base[i] == target[0]) {
      let j = 1;
      while (j < target.length) {
        if (target[j] == base[i + j]) j++;
        else break;
      }
      if (j == target.length) return i;
    }
  }
  return -1;
};
console.log(fun(str1, str2));

Four-Names avatar Feb 24 '22 09:02 Four-Names

请问下这题主要考什么?为啥indexOf不行?

你用indexOf,面试官会问你有没有其他解法,直到KMP结束😢

yuerdev avatar Jun 28 '22 09:06 yuerdev

function foo(target, fragment){ const frag = target.split(fragment) if (frag.length >= 2){ return frag[0].length } return -1 }

Lxming1 avatar Aug 08 '22 11:08 Lxming1

您的邮件已收到!O(∩_∩)O!--------Pan

89466598946659 avatar Aug 08 '22 11:08 89466598946659