Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Алгоритм поиска подстроки (https://javascript.ru/forum/misc/40783-algoritm-poiska-podstroki.html)

рони 20.08.2013 00:57

devote,
function strpos(substring, string) {
    return string.split(substring).length === 2;
}
alert(strpos('привет', 'привет мир! привет'));

devote 20.08.2013 01:03

рони,
у меня не совсем правильный вариант, нужно не равенство ставить, а больше одного.. так как вхождений подстроки может быть больше, что-то типо:
function strpos(substring, string) {
    return string.split(substring).length > 1;
}
alert(strpos('привет', 'привет мир! привет'));

zilker 20.08.2013 01:04

danik.js,
твой код не найдет 'lala' в 'lal111lala', т.к. выдаст false после первого неудачного захода во вложенный цикл.
devote,
да, твой второй вариант более компактный, но он найдет 'lala' в 'lal'

devote 20.08.2013 01:08

Цитата:

Сообщение от zilker
но он найдет 'lala' в 'lal'

исправимо, совсем небольшими правками:
function strpos(substring, string) {
    var index = 0, subindex = 0;
    var subStrLen = substring.length;
    var strLen = string.length;
    while(subindex < subStrLen && index < strLen) {
        if (substring.charCodeAt(subindex) === string.charCodeAt(index)) {
            subindex++;
        } else {
            index -= subindex;
            subindex = 0;
        }
        index++;
    }
    return subindex && subindex === subStrLen;
}
alert(strpos('привет', 'привет мир!'));
alert(strpos('lala', 'lal'));

zilker 20.08.2013 01:12

Да, так работает как надо. Всем спасибо большое)

devote,
твой код в среднем в 10 раз быстрее моего первоначального...

но только из-за использования charCodeAt

zilker 20.08.2013 01:41

// моя фун-я
function subStr(substring, string) {
	var found = false, k = 1, sbl = substring.length, stl = string.length;
	for(var i = 0; i < stl; i++) {
		if(string.charCodeAt(i) == substring.charCodeAt(0)) {
			for(var j = 1, l = i + 1; j < sbl; j++, l++) if (string.charCodeAt(l)) {
				if(string.charCodeAt(l) == substring.charCodeAt(j)) {
					k++;
				} else {
					k = 1;
					break;
				}
			}
			if(k == sbl) {
				found = true;
				break;
			} else {
				i = l;
			}				
		}
	}
	return found;
}

// фун-я devote
function strpos(substring, string) {
    var index = 0, subindex = 0;
    var subStrLen = substring.length;
    var strLen = string.length;
    while(subindex < subStrLen && index < strLen) {
        if (substring.charCodeAt(subindex) === string.charCodeAt(index)) {
            subindex++;
        } else {
            index -= subindex;
            subindex = 0;
        }
        index++;
    }
    return subindex && subindex === subStrLen;
}


console.time('compare by char codes');
for (var i=0; i<100000; i++) strpos('друг', 'здравствуй, здравствуй, друг мордастый!');
console.timeEnd('compare by char codes');


console.time('compare by char codes2');
for (var j=0; j<100000; j++) subStr('друг', 'здравствуй, здравствуй, друг мордастый!');
console.timeEnd('compare by char codes2');


Хм, но если я применю оптимизацию с charCodeAt в своем коде, он начинает быть быстрее. Я не для пиписькомерства, просто интересно, у меня же вроде вложенный цикл есть :-?

zilker 20.08.2013 10:38

Дзен-трансгуманист,
спасибо за разъяснение.

devote 20.08.2013 11:17

Хотите оптимизации, ну тогда вот ловите.. Думаю ни для кого не секрет что вычитание работает в разы быстрее сложения.
function strpos(substring, string) {
    var substringStartPos = substring.length - 1;
    var subindex = substringStartPos;
    var index = string.length - 1;
    for( ;subindex >= 0 && index >= 0; ) {
        if (substring.charCodeAt(subindex) === string.charCodeAt(index)) {
            subindex--;
        } else if (subindex !== substringStartPos) {
            index += substringStartPos - subindex;
            subindex = substringStartPos;
        }
        index--;
    }
    return substringStartPos && subindex === -1;
}

console.time('compare by char codes');
for (var i=0; i<100000; i++) strpos('друг', 'здравствуй, здравствуй, друг мордастый!');
console.timeEnd('compare by char codes');


Часовой пояс GMT +3, время: 03:57.