Алгоритм, представленный имеет сложность (1 + n - (1)) + (1 + n - (2)) + (1 + n - (3)) + ... + (1 + n - (n-1)) = (n-1)*(1 + n) - (n)(n-1)/2 = (n^2 + n - 2)/2
, которая является О (п).
Таким образом, было бы лучше использовать объект для сопоставления и запоминания символов для проверки уникальности или дубликатов. Предполагая максимальный размер данных для каждого символа, этот процесс будет алгоритмом O(n)
.
function charUnique(s) {
var r = {}, i, x;
for (i=0; i<s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
В крошечном тестовом случае функция действительно работает в несколько раз быстрее.
Обратите внимание, что строки JavaScript определяются как последовательности из 16-разрядных целых значений без знака. http://bclary.com/2004/11/07/#a-4.3.16
Следовательно, мы по-прежнему можем реализовать один и тот же базовый алгоритм, но используя гораздо более быстрый поиск массива, а не поиск объектов. Результат примерно в 100 раз быстрее.
var charRepeats = function(str) {
for (var i = 0; i <= str.length; i++) {
for (var j = i + 1; j <= str.length; j++) {
if (str[j] == str[i]) {
return false;
}
}
}
return true;
}
function charUnique(s) {
var r = {},
i, x;
for (i = 0; i < s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charUnique2(s) {
var r = {},
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charCodeUnique(s) {
var r = [],
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s.charCodeAt(i);
if (r[x])
return false;
r[x] = true;
}
return true;
}
function regExpWay(s) {
return /(.).*\1/.test(s);
}
function timer(f) {
var i;
var t0;
var string = [];
for (i = 32; i < 127; i++)
string[string.length] = String.fromCharCode(i);
string = string.join('');
t0 = new Date();
for (i = 0; i < 10000; i++)
f(string);
return (new Date()) - t0;
}
document.write('O(n^2) = ',
timer(charRepeats), ';<br>O(n) = ',
timer(charUnique), ';<br>optimized O(n) = ',
timer(charUnique2), ';<br>more optimized O(n) = ',
timer(charCodeUnique), ';<br>regular expression way = ',
timer(regExpWay));
Вы можете добавить некоторые примеры данных, которые будут проверены и ожидаемые результаты? –
Что в этом случае считается строкой? например предложение или слово? И что считается «повторением»? Многочисленные вхождения? Или две буквы рядом друг с другом? – jerdiggity
Возможный дубликат [Повторяющиеся символы в середине строки] (http://stackoverflow.com/questions/28736790/repeating-characters-in-the-middle-of-a-string) –