20.02.2011, 14:36
|
Профессор
|
|
Регистрация: 14.12.2009
Сообщений: 155
|
|
Matre,
Дело не в браузерах, дело в алгоритме. Он работает неверно. Проверьте на любых примерах. Например:
String.prototype.index = function (str) {
var j = -1, c = false, L1 = this.length, L2 = str.length - 1;
for (var i = 0; i < L1; i++) {
if (str.charAt(0) === this.charAt(i))
c = true, j = i;
if (c && i === j + L2)
return j;
if (c && str.charAt(i) != this.charAt(i + j))
c = false;
}
return j;
};
// Где ищем
var s = 'A';
// Что ищем
var t = 'AB';
alert([
'В строке "' + s + '"',
'ищем "' + t + '"',
'и находим: ' + s.index(t), // Должно быть -1, показывает 0
'хотя там быть не должно: ' + s.indexOf(t) // Показывает -1
].join('\n'));
|
|
20.02.2011, 14:56
|
|
⊞ Развернуть
|
|
Регистрация: 11.01.2010
Сообщений: 1,810
|
|
рони,
String.prototype.index = function (c) {
for (var a = -1, d = this.length, b = 0; b < d; b++) {
if(c.length > d) return a;
a++;
a = c.charAt(a) === this.charAt(b) ? a : c.charAt(0) === this.charAt(b) ? 0 : -1;
if (a == c.length - 1) return b - c.length + 1
}
return a
};
var s1 = 'aababaO_o',
l1 = 'abaO', l2 = 'abac', l3 = 'aa', l4 = 'O_o';
alert( [
[s1.index(l1), s1.indexOf(l1)]
].join('\n') )
Matre, вполне нормальный. Причем точно такие же результаты будут у других пользователей.
А вот алгоритм у Вас кривой.
Принимая во внимание то, что все известные алгоритмы поиска подстроки требуют либо предварительной обработки данных, либо работают дольше, чем за O(n), маловероятно, что существует алгоритм, позволяющий "с места", без подготовки найти заданную подстроку в строке за один просмотр исходной строки.
|
|
20.02.2011, 15:19
|
|
Матрос
|
|
Регистрация: 04.04.2008
Сообщений: 6,246
|
|
Сообщение от B@rmaley.e><e
|
Принимая во внимание то, что все известные алгоритмы поиска подстроки требуют либо предварительной обработки данных, либо работают дольше, чем за O(n), маловероятно, что существует алгоритм, позволяющий "с места", без подготовки найти заданную подстроку в строке за один просмотр исходной строки.
|
http://algolist.manual.ru/search/esearch/kmp.php
Работает за линию от входных данных.
Но условие задачи было не обеспечить определенную сложность алгоритма, а использовать только один цикл.
Сделать из группы вложенных циклов, или из группы подряд идущих циклов, один единственный - вполне решаемая задача, хотя и из разряда "никогда так не делай"
|
|
20.02.2011, 15:48
|
Профессор
|
|
Регистрация: 16.03.2010
Сообщений: 1,618
|
|
Я бы реализовал вот так:
String.prototype.index = function(x){
var i1, i2, l1 = this.length, l2 = x.length;
for(i1 = 0; i1 < l1; i1++)
if(this[i1] === x[0])
for(i2 = 0; i2 <= l2; i2++){
if(i2 === l2) return i1;
if(this[i1 + i2] === x[i2]) continue;
break;
};
return -1;
};
var s1 = 'aababaO_o',
l1 = 'abaO', l2 = 'abac', l3 = 'aa', l4 = 'O_o';
alert( [
[s1.index(l1), s1.indexOf(l1)],
[s1.index(l2), s1.indexOf(l2)],
[s1.index(l3), s1.indexOf(l3)],
[s1.index(l4), s1.indexOf(l4)]
].join('\n') );
|
|
20.02.2011, 16:11
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,123
|
|
Ещё вариант ...
String.prototype.index = function (c) {
for (var a = -1, d = this.length, b = 0; b < d; b++) {
if (c.length > d) break;
a++;
if (c.charAt(a) !== this.charAt(b)) {
b -= a;
a = -1
}
if (a == c.length - 1) return b - c.length + 1
}
return a
};
var s1 = 'aababaO_o',
l1 = 'abaO', l2 = 'abac', l3 = 'aa', l4 = 'O_o';
alert( [
[s1.index(l1), s1.indexOf(l1)]
].join('\n') )
// Где ищем
var s = 'A';
// Что ищем
var t = 'AB';
alert([
'В строке "' + s + '"',
'ищем "' + t + '"',
'и находим: ' + s.index(t), // Должно быть -1, показывает 0
'хотя там быть не должно: ' + s.indexOf(t) // Показывает -1
].join('\n'));
var s1 = 'aababaO_o',
l1 = 'aba', l2 = 'abac', l3 = 'aa', l4 = 'O_o';
alert( [
[s1.index(l1), s1.indexOf(l1)],
[s1.index(l2), s1.indexOf(l2)],
[s1.index(l3), s1.indexOf(l3)],
[s1.index(l4), s1.indexOf(l4)]
].join('\n') )
|
|
20.02.2011, 16:18
|
|
Профессор
|
|
Регистрация: 25.05.2010
Сообщений: 511
|
|
Sweet, можно только один цикл использовать.
|
|
20.02.2011, 16:25
|
Профессор
|
|
Регистрация: 16.03.2010
Сообщений: 1,618
|
|
Сообщение от Vulkan
|
можно только один цикл использовать.
|
А мне захотелось использовать два! Хотя, конечно, можно еще было бы вместо for воспользоваться while, или вообще без циклов...
|
|
20.02.2011, 16:27
|
|
⊞ Развернуть
|
|
Регистрация: 11.01.2010
Сообщений: 1,810
|
|
Сообщение от Gvozd
|
Сделать из группы вложенных циклов, или из группы подряд идущих циклов, один единственный - вполне решаемая задача
|
Как Вы собрались объединять, например, это?
var arr = [3,4,5,6,7,8,9,0,1 /* and so on */], s = 0;
for(var i =0, length = arr.length; i < length; ++i){ // предварительные вычисления
s += arr[i];
}
for(var i = 0, length = arr.length; i < length; ++i){ // самое то.
arr[i] = (arr[i] / s * 100).toFixed(2) + '%';
}
alert([s, arr].join('\n'));
Сомневаюсь, что КМП можно записать одним циклом.
P.S. Грязные "хаки" вида
function indexOf(haystack, needle){
var n = haystack.length,
m = needle.length;
var i = 0, j = 0, offset = 0;
for(var k = 0, length = n * m; k < length; ++k){
i = k / m | 0;
j = k % m;
if(haystack[i + offset] != needle[j]){
offset = 0;
k += m - j - 1;
} else {
++offset;
if(j == m - 1) return i;
}
}
return -1;
}
var s1 = 'aababaO_o',
l1 = 'abaO', l2 = 'abac', l3 = 'aa', l4 = 'O_o';
alert( [
[indexOf(s1, l1), s1.indexOf(l1)],
[indexOf(s1, l2), s1.indexOf(l2)],
[indexOf(s1, l3), s1.indexOf(l3)],
[indexOf(s1, l4), s1.indexOf(l4)],
[indexOf(s1, 'a'), s1.indexOf('a')]
].join('\n') );
не рассматриваем.
|
|
20.02.2011, 17:02
|
Профессор
|
|
Регистрация: 14.12.2009
Сообщений: 155
|
|
Эта задача не требует хаков, или дополнительных циклов. Задача действительно решается в один цикл. Не надо городить огород:
String.prototype.hasAt = function(needle, pos)
{
var i = Math.min(this.length, Math.max(0, Number(pos) || 0));
var j;
var found;
for ( ; i < this.length; i++) {
if ( found ) {
if ( i - j == needle.length ) {
return j;
}
found = this.charAt(i) == needle.charAt(i - j);
} else {
found = this.charAt(i) == needle.charAt(0);
if ( found ) {
j = i;
}
}
}
return found && this.length - j == needle.length
? j
: -1;
};
Для "чистоты" эксперимента следовало бы заменить Math.min/Math.max соответствующими проверочными условиями, чтобы позиция начала поиска не выходила за пределы строки. Но это не существенно.
Последний раз редактировалось with-love-from-siberia, 20.02.2011 в 17:04.
|
|
20.02.2011, 17:34
|
|
⊞ Развернуть
|
|
Регистрация: 11.01.2010
Сообщений: 1,810
|
|
String.prototype.hasAt = function(needle, pos)
{
var i = Math.min(this.length, Math.max(0, Number(pos) || 0));
var j;
var found;
for ( ; i < this.length; i++) {
if ( found ) {
if ( i - j == needle.length ) {
return j;
}
found = this.charAt(i) == needle.charAt(i - j);
} else {
found = this.charAt(i) == needle.charAt(0);
if ( found ) {
j = i;
}
}
}
return found && this.length - j == needle.length
? j
: -1;
};
var s1 = 'aababababaO_o',
l1 = 'ababaO';
alert( [
[s1.hasAt(l1), s1.indexOf(l1)]
].join('\n') );
Кто еще верит, что все так просто?
|
|
|
|