Open libin1991 opened 5 years ago
字符串变为数组,用数组方法findIndex去查找。
Object.prototype.sIndexOf = function (char) {
const len = this.length
for (let i = 0; i < len; i++) {
if (this[i] === char) {
return i
}
}
return -1
}
_indexOf( str , arr ) {
if(!arr.length) return;
if(!arr && arr.length < 1) return;
const toArrary = obj => [].slice.call(obj);
let result = -1;
Array.form
? result = Array.from(arr).findIndex(el => el == str)
: result = toArrary(arr).findIndex(el => el == str)
return result;
}
let strData = '123456'
let arrData = [1,2,3];
console.log(_indexOf(1,strData),'strData');
console.log(_indexOf(1,arrData),'arrData');
能使用其它数组api? 能的话,嘿嘿嘿:
const indexOf = (arr, val) => {
return arr.findIndex(item => item === val);
}
function _indexOf(str, reg, fromIndex = 0) { let index = fromIndex; const { length } = str; if (index <= 0) index = 0; if (index >= length) return -1; const arr = str.slice(fromIndex).split(reg); return arr.length > 1 ? arr[0].length + fromIndex : -1 }
看了一圈怎么没人考虑indexOf的第二个起始参数呢?
function indexOf(arr,target,start=0){
if(start<0) start+=arr.length;
if(start>=arr.length) return -1;
for(let i=start;i<arr.length;++i){
if(arr[i]===target) return i;
}
return -1;
}
function indexOf(str, a, start) {
start = start == undefined ? 0 : start;
for (var i = start; i < str.length; i++) {
if (str[i] == a) {
return i;
}
}
return -1;
}
function indexOf(str, serchStr, index) { if(index){ return str.substr(index,).match(serchStr)?str.substr(index,).match(serchStr).index + index :-1 }else{ return str.match(serchStr)?str.match(serchStr).index:-1 } }
Array.prototype.myIndexOf = function(item, start = 0) { const length = this.length; const startPos = start >= 0 ? start : length + start; if (start >= length) return -1; for (let i = startPos; i < length; i++) { if (this[i] === item) return i; } return -1; };
看了一圈怎么没人考虑indexOf的第二个起始参数呢?
因为大家都不咋用这个参数,想不起来了呗
Object.prototype.MyIndexOf = function(str, from=0){
let data = this;
let isArray = Array.isArray(data);
let isString = Object.prototype.toString.call(data) == '[object String]';
if (!isArray && !isString) throw new SyntaxError();
let len = data.length;
if(from >= len) return -1;
for(var i = from; i <len; i++){
if (isString){
let strLen = str.length;
if (data.substr(i, i+strLen) == str){
return i;
}
}
if (isArray && data[i] == str){
return i;
}
}
return -1;
}
"hello world".indexOf('he')
有的写得只能匹配单个字符
function indexOf(str, target){
for(let i = 0; i < str.length; i ++){
let j = 0;
if(str[i] === target[j]){
while(++j<target.length){if(str[i+j] !== target[j]) break;}
if(j === target.length) {return i;}
}
}
return -1;
}
@ghost2113 substr应该换成substring吧
// 暴力匹配 function ViolentMatch(s, p) { var i = 0, j = 0, pLen = p.length, sLen = s.length; while (i < sLen && j < pLen) { if (s[i++] != p[j++]) { i = i - (j - 2) - 1; j = 0; } } return j == pLen ? i - j : -1; }
String.prototype.indexOFS = function (string, start = 0) {
return this.substr(start).match(new RegExp(string)) ? (this.substr(start).match(new RegExp(string)).index + start) : -1
};
function _indexOf(string, target) {
if (typeof string !== 'string') {
throw new Error('string only');
}
let mt = string.match(new RegExp(target))
return mt ? mt.index : -1;
}
使用正则 indexOf('/:>-|+?','/:>-|+?') 这个测试用例应该通不过
indexOf 字符串,数组也能用吧,
function indexOfTest(arrOrString, target, index = 0) {
if(Array.isArray(arrOrString)) {
for(let i = index; i < arrOrString.length; i++) {
if(arrOrString[i] == target) {
return i
}
}
return -1;
}
// 字符串
const newArr = arrOrString.split(target);
if(newArr.length == 1) {
return -1
}
let res = 0;
for(let j = 0; j < newArr.length; j++) {
if(newArr[j] == "" && index == 0) {
return 0
}
if(res > index) {
return res;
}
res += newArr[j].length || 1;
}
return res;
}
function formatIndexof(str, target, index) {
let begin = index || 0;
let end = str.length || 0;
const tLen = target.length
if (begin > end) {
return -1;
}
if (tLen == 1 || Object.prototype.toString.call(str) === '[object Array]') {
for (let i = begin; i < end; i++) {
if (str[i] === target) {
return i
}
}
} else if (tLen > 1) {
for (let i = begin; i < end; i++) {
const temp = str.slice(i, tLen + i);
if (target === temp) {
return i
}
}
}
return -1;
}
@Zhou-Bill
function formatIndexof(str, target, index) { let begin = index; let end = str.length - 1 || 0; if (begin > end) { return -1; } for (let i = begin; i < end; i++) { if (str[i] === target) { return i } } return -1; }
formatIndexof("test", "tes")
这样不是不行吗
function formatIndexof(str, target, index) { let begin = index; let end = str.length - 1 || 0; if (begin > end) { return -1; } for (let i = begin; i < end; i++) { if (str[i] === target) { return i } } return -1; }
formatIndexof("test", "tes")
这样不是不行吗 是有这个问题 ,已经做出修改
好像没说是数组还是字符的indexOf
function arrayIndexOf (array = [], item) {
for (let i = 0; i < array.length; i++) {
if (array[i] === item) {
return i;
}
}
return -1;
}
function stringIndexOf (str = '', subStr) {
if (!subStr) return -1;
for (let i = 0; i < str.length; i++) {
if (str.substr(i, subStr.length) === subStr) {
return i;
}
}
return -1;
}
for循环 这题好像没什么考的意义哦
这题考点在哪啊,没盖特到 ,难道是有什么特别6的写法吗
考点应该是对api的了解,比如入参(val,startIndex),还有返回值startIndex<0和startIndex>this.length,notFound等
const strings = 'abcd123fka'
String.prototype.indexOfFn = function(str, index = 0) {
const string = this.substring(index)
return string.split('').findIndex(item => item === str) + index
}
console.log(strings.indexOfFn('3'))
function indexOf(arr,target,start=0){ if(start<0) start+=arr.length; if(start>=arr.length) return -1; for(let i=start;i<arr.length;++i){ if(arr[i]===target) return i; } return -1; }
indexOf可适用于数组和字符串,共同点是输入参数和返回值相同,不同点是,如果是字符串,那么输入的值会自动转化为string类型(如输入值为number类型时),而数组不会转换
例子: const array = ["1",2,3,4]; const str = "123456"; array.indexOf("1"); // 0 array.indexOf(1); // -1 array.indexOf(2); // 1 str.indexOf(1); // 0 这里自动将number 类型的1转化为了string类型的 "1" str.indexOf("1"); // 0
function indexOf(str, val){
return str.indexOf(val);
}
如此简洁,敢问”还有谁?”
好像没说是数组还是字符的indexOf
function arrayIndexOf (array = [], item) { for (let i = 0; i < array.length; i++) { if (array[i] === item) { return i; } } return -1; } function stringIndexOf (str = '', subStr) { if (!subStr) return -1; for (let i = 0; i < str.length; i++) { if (str.substr(i, subStr.length) === subStr) { return i; } } return -1; }
这是一道LeetCode原题实现strStr
KMP 算法(Knuth-Morris-Pratt 算法)是一个著名的字符串匹配算法,使用空间换时间可以使得时间复杂度下降到$O(N)$。
public class KMP {
private int[][] dp;
private String pattern;
public KMP(String pattern) {
this.pattern = pattern;
int M = pattern.length();
dp = new int[M][256];
dp[0][pattern.charAt(0)] = 1;
int X = 0;
for (int j = 1; j < M; j++) {
for (int c = 0; c < 256; c++) {
dp[j][c] = dp[X][c];
dp[j][pattern.charAt(j)] = j + 1;
X = dp[X][pattern.charAt(j)];
}
}
public int search(String str) {
int M = pattern.length();
int N = str.length();
int j = 0;
for (int i = 0; i < N; i++) {
j = dp[j][str.charAt(i)];
if (j == M) return i - M + 1;
}
return -1;
}
}
复杂度分析
欢迎关注我的[LeetCode]题解(https://github.com/azl397985856/leetcode)
function indexof(str, sub, start=0){
if(start<0) start = 0;
if(sub===''&&start>=str.length) return str.length;
if(sub!==''&&start>=str.length) return -1;
const target = str.slice(start);
return target.search(sub)+start;
}
function indexOf(arr,target,start=0){ if(start<0) start+=arr.length; if(start>=arr.length) return -1; for(let i=start;i<arr.length;++i){ if(arr[i]===target) return i; } return -1; }
indexOf可适用于数组和字符串,共同点是输入参数和返回值相同,不同点是,如果是字符串,那么输入的值会自动转化为string类型(如输入值为number类型时),而数组不会转换
例子: const array = ["1",2,3,4]; const str = "123456"; array.indexOf("1"); // 0 array.indexOf(1); // -1 array.indexOf(2); // 1 str.indexOf(1); // 0 这里自动将number 类型的1转化为了string类型的 "1" str.indexOf("1"); // 0
let str = 'hello wrod' str.indexOf(str,'ll') 直接凉 兄弟
function indexOf(str, val){ return str.indexOf(val); }
如此简洁,敢问”还有谁?”
你赢了
indexOf
有两种:
String.prototype.indexOf()
返回从 fromIndex
处开始搜索第一次出现的指定值的索引,如果未找到,返回 -1
str.indexOf(searchValue [, fromIndex])
// fromIndex 默认值为 0
Array.prototype.indexOf()
返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回 -1
arr.indexOf(searchElement[, fromIndex])
解题思路:正则,字符串匹配
function sIndexOf(str, searchStr, fromIndex = 0){
var regex = new RegExp(`${searchStr}`, 'ig')
regex.lastIndex = fromIndex
var result = regex.exec(str)
return result ? result.index : -1
}
// 测试
var paragraph = 'The quick brown fox jumps over the lazy dog. If the dog barked, was it really lazy?'
var searchTerm = 'dog'
// 测试一:不设置 fromIndex
console.log(sIndexOf(paragraph, searchTerm))
// 40
console.log(paragraph.indexOf(searchTerm));
// 40
// 测试二:设置 fromIndex
console.log(sIndexOf(paragraph, searchTerm, 41))
// 52
console.log(paragraph.indexOf(searchTerm, 41));
// 52
测试成功
解题思路:遍历匹配
function aIndexOf(arr, elem, fromIndex = 0){
if(!elem) return -1
for(let i = fromIndex; i < arr.length; i++) {
if(arr[i] === elem) return i
}
return -1
}
// 测试
var beasts = ['ant', 'bison', 'camel', 'duck', 'bison']
// 测试一:不设置 fromIndex
console.log(aIndexOf(beasts, 'bison'))
// 1
console.log(beasts.indexOf('bison'))
// 1
// 测试二:设置 fromIndex
console.log(aIndexOf(beasts, 'bison', 2))
// 4
console.log(beasts.indexOf('bison', 2))
// 4
测试成功
function indexOf(items, item, fromIndex = 0) {
let isArray = Array.isArray(items);
let isString = Object.prototype.toString.call(items) == '[object String]';
if (!isArray && !isString) throw new SyntaxError();
if(isArray) return sIndexOf(items, item, fromIndex)
else return aIndexOf(items, item, fromIndex)
}
你也可以尝试使用遍历匹配法解决 sIndexOf
问题(正则更简洁),这里不做介绍(和 aIndexOf
差不多的套路,不同的是,String
类型可以一次匹配多个字符)
更过编程算法题可见 JavaScript-Algorithms
function indexOf(str, a, start) { start = start == undefined ? 0 : start; for (var i = start; i < str.length; i++) { if (str[i] == a) { return i; } } return -1; }
只是单字符的
Array.prototype.myIndexOf = function (value, fromIndex) { const len = this.length let index = -1 fromIndex = fromIndex === undefined ? 0 : fromIndex if (fromIndex < 0) { fromIndex = len + fromIndex; fromIndex = fromIndex < 0 ? 0 : fromIndex; } for (let i = fromIndex; i < len; i++) { if (this[i] === value) { index = i; break; } } return index }
indexOf
有两种:String.prototype.indexOf()
返回从
fromIndex
处开始搜索第一次出现的指定值的索引,如果未找到,返回-1
str.indexOf(searchValue [, fromIndex]) // fromIndex 默认值为 0
Array.prototype.indexOf()
返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回
-1
arr.indexOf(searchElement[, fromIndex])
解答
String.prototype.indexOf()
解题思路:正则,字符串匹配
function sIndexOf(str, searchStr, fromIndex = 0){ var regex = new RegExp(`${searchStr}`, 'ig') regex.lastIndex = fromIndex var result = regex.exec(str) return result ? result.index : -1 } // 测试 var paragraph = 'The quick brown fox jumps over the lazy dog. If the dog barked, was it really lazy?' var searchTerm = 'dog' // 测试一:不设置 fromIndex console.log(sIndexOf(paragraph, searchTerm)) // 40 console.log(paragraph.indexOf(searchTerm)); // 40 // 测试二:设置 fromIndex console.log(sIndexOf(paragraph, searchTerm, 41)) // 52 console.log(paragraph.indexOf(searchTerm, 41)); // 52
测试成功
Array.prototype.indexOf()
解题思路:遍历匹配
function aIndexOf(arr, elem, fromIndex = 0){ if(!elem) return -1 for(let i = fromIndex; i < arr.length; i++) { if(arr[i] === elem) return i } return -1 } // 测试 var beasts = ['ant', 'bison', 'camel', 'duck', 'bison'] // 测试一:不设置 fromIndex console.log(aIndexOf(beasts, 'bison')) // 1 console.log(beasts.indexOf('bison')) // 1 // 测试二:设置 fromIndex console.log(aIndexOf(beasts, 'bison', 2)) // 4 console.log(beasts.indexOf('bison', 2)) // 4
测试成功
总结一下
function indexOf(items, item, fromIndex = 0) { let isArray = Array.isArray(items); let isString = Object.prototype.toString.call(items) == '[object String]'; if (!isArray && !isString) throw new SyntaxError(); if(isArray) return sIndexOf(items, item, fromIndex) else return aIndexOf(items, item, fromIndex) }
你也可以尝试使用遍历匹配法解决
sIndexOf
问题(正则更简洁),这里不做介绍(和aIndexOf
差不多的套路,不同的是,String
类型可以一次匹配多个字符)更过编程算法题可见 JavaScript-Algorithms
赞,不过 感觉 SyntaxError 换成 TypeError 是不是更好一点
function mockIndexOf(eles, target, startIndex = 0) {
const dataType = Object.prototype.toString.call(eles);
if (dataType === '[object Array]') {
const len = eles.length;
const _startIndex = startIndex >= 0 ? startIndex : startIndex + len;
return eles.findIndex((v, index) => {
return _startIndex <= index && v === target;
});
}
if (dataType === '[object String]') {
const len = eles.length;
const _startIndex =
startIndex >= 0 ? (startIndex < len ? startIndex : len) : 0;
const result = eles.substr(_startIndex).match(target);
console.log(result, eles.substr(startIndex), target);
return result ? result.index + _startIndex : -1;
}
throw new Error('第一个参数请传入数组或者字符串');
}
mockIndexOf('dsafsa', 'sa')' // 1
mockIndexOf('dsafsa', 'sf')' // -1
兼容实现字符串和数组的 indexOf,针对字符串处理方式不一样:
export function indexOf(arr: string, item: string, fromIndex ? : number): number;
export function indexOf(arr: Array < any > , item: any, fromIndex ? : number): number;
export function indexOf(arr: any, item: any, fromIndex: number = 0) {
let index = -1;
if (typeof arr === 'string') {
const m = item.length
for (let i = fromIndex, len = arr.length - m; i < len; i++) {
if (item === arr.substr(i, m)) {
index = i;
break;
}
}
} else if (arr instanceof Array) {
for (let i = fromIndex, len = arr.length; i < len; i++) {
if (item === arr[i]) {
index = i;
break;
}
}
}
return index;
}
/**
* 字符串
* @param str
* @param target
* @param start
* @returns {number|*}
*/
function strIndexOf(str, target, start = 0){
if (start > str.length) {
return -1;
}
if (start < 0) {
start = 0;
}
for (let i = start; i < str.length; i++) {
let current = str.substring(i, i + target.length);
if (current === target) {
return i;
}
}
return -1;
}
function indexOf(a, b){
var index = a.split(b)[0].length;
return index === a.length ? -1 : index;
}
var a = 'abcbbcddc';
var b = 'bb';
indexOf(a, b); // 3
indexOf(a, '1'); // -1
// 使用startsWith
function indexOf(src: string, slice: string): number {
const _indexOf = (src: string, slice: string, index: number): number => {
if (slice.length === 0 || src.length < slice.length) return -1
return src.startsWith(slice) ? index : _indexOf(src.slice(1), slice, index + 1)
}
return _indexOf(src, slice, 0)
}
// 循环版本
function indexOf2(src: string, slice: string): number {
for (let i = 0; i < src.length && (src.length - i) >= slice.length; ++i) {
if (src.startsWith(slice, i)) return i
}
return -1;
}
const a = 'abcdefghijkl'
const b = 'ghi'
const c = '123'
console.log(indexOf(a, b)) // 6
console.log(indexOf(a, c)) // -1
'123'.search(x)
abc
与cccabcaaa
这种比较,就是从第一个开始,每三个长度为一段进行比较
abc
比较ccc
, abc
比较cca
, abc
比较cab
... 比较笨吧, 可能性能比较差,但是好理解。。 function findIndex(key, obj) {
console.log(`查找的对象${obj}`, `----查找的键值${key}`)
let arr = []
let index = -1 //最后返回查找到的索引
/**********************如果是数组***********************/
if (obj instanceof Array) {
arr = obj
arr.some((i, indexA) => {
if (i == key) {
index = indexA
return true
}
})
}
/**********************如果是字符串***********************/
else if (typeof (obj) === 'string') {
arr = obj.split('')
let keyLen = key.length
for(let i=0;i<=arr.length-keyLen;i++){
if(key === obj.substring(i, i+keyLen)){
index = i
}
}
} else {
return '不符合数据格式'
}
return index
}
console.log(31, findIndex('g', 'abcdefg'))
console.log(32, findIndex(22, [22,33,444]))
/**
*
* @param {string} p
*/
function buildNext(p) {
const m = p.length
const N = []
let t = N[0] = -1
let j = 0
while (j < m -1) {
if (0 > t || p[j] === p[t]) {
j++
t++
// 根据已知信息如果p[j] !== t[i] 如果p[j] === p[t]则p[t]必然失配t[i]所以这次比较可以优化
N[j] = p[j] !== p[t] ? t : N[t]
} else {
t = N[t]
}
}
return N
}
/**
* kmp字符串模式匹配
* @param {string} t
* @param {string} p
*/
function match(t, p) {
let N = buildNext(p)
let i = 0
let j = 0
const n = t.length
const m = p.length
while(j < m && i < n) {
if (0 > j || t[i] === p[j]) {
i++
j++
} else {
j = N[j]
}
}
return j === m ? i - j : -1
}
export function indexOf(s, fromIndex = 0) {
fromIndex = 0 > fromIndex
? this.length + fromIndex > 0
? this.length + fromIndex
: 0
: fromIndex
console.log(fromIndex)
const i = match(this.slice(fromIndex), s)
return i > 0 ? fromIndex + i : i
}
import { indexOf} from '@/dayily-interview/kmp'
describe('kmp.js', () => {
it('match success',() => {
expect(indexOf.call('test success', 'c')).toBe(7)
})
it('match fail',() => {
expect(indexOf.call('test success', 'z')).toBe(-1)
})
it('match success with from index', () => {
expect(indexOf.call('test success', 's', 3)).toBe(5)
})
it('match fail with from index', () => {
expect(indexOf.call('test success', 't', 4)).toBe(-1)
})
it('match success with complex', () => {
expect(indexOf.call('test success', 'ucce', 3)).toBe(6)
})
it('match with negative from index', () => {
expect(indexOf.call('test success', 'ucce', -16)).toBe(6)
})
it('match with negative from index', () => {
expect(indexOf.call('test success', 'ss', -1)).toBe(-1)
})
it('match with negative from index', () => {
expect(indexOf.call('test success', 'ss', -2)).toBe(10)
})
it('match with zero from index', () => {
expect(indexOf.call('test success', 'ss', 0)).toBe(10)
})
})
思路一: 利用正则比对当前字符串找出位置
function indexOf1(str,val){
const reg = new RegExp(${val}
,'gi');
const result = reg.exec(str);
return result?result.index:-1;
}
思路二: 利用字符串截取循环找到符合截取值的位置
function indexOf2(str,val){
const sl = str.length;
const vl = val.length;
for(var i=0;i<=sl-vl;i++){
if(str.slice(i,vl+i)===val){
return i;
}
}
return -1;
}