Андрей Д.
1267 сообщений
#16 лет назад
phpmaniac, ага =) Я бы просто название функции вспоминал минуты 2, программированием не занимался приличное время... Хотя изначально я задумал немного не так, мой вариант бы был медленнее раза в 2... Но примерную идею описал я первый ;P

tvv, спасибо, не знал
Сергей Д.
116 сообщений
#16 лет назад
На самом деле, если принимать условия задачи - надо знать, было ли слово а потоке или оно первый раз встретилось, причем, общее количество элементов в потоке неизвестно, то я могу предложить такой вариант...
на вскидку...



class TestWord{

var $words = array();

function test($testWord){

if( $this->words )
{
$this->words++;
return( true );

}
$this->words = 1;
return( false );
}

}



функция test вернет флаг - был ли элемент или нет, а в массиве words - будут частоты ....на данный момент времени... помоему так...
Вадим Т.
3240 сообщений
#16 лет назад
Да, только что проверил, на реальных наборах слов без ссылки действительно где-то на 5% быстрее. Вот это и мне урок, сначала проверять, а потом писать
 Falcon
400 сообщений
#16 лет назад
tvv, ага. Но на коротких дистанциях почему-то отсутствие ссылки помогает. Не знаю в чем уж тут дело. Братья Карамазовы. Один проход (в среднем):

Со ссылкой: 0.077 с.
Без ссылки: 0.072 с.

50 проходов:

Со ссылкой: 1.71 с.
Без ссылки: 1.97 с.

Странная закономерность.
Андрей Д.
1267 сообщений
#16 лет назад
phpmaniac, это из-за памяти наверное (догадки)
 Falcon
400 сообщений
#16 лет назад
Дальше сохраняется это отношение: 500 проходов 16.63/19.34 (те же ~1:1,16). В общем, на маленьких массивах ссылку юзать не надо без необходимости, а на больших надо.
Вадим Т.
3240 сообщений
#16 лет назад
Zionit, phpmaniac, да, тут дело темное. оно наверняка еще и от версии PHP зависит. общее правило (в теории) такое - чем больший объект нужно перетаскивать, тем более выгодно использовать ссылку вместо полного копирования. хотя, возможно, к обработке строк это относится как-то по другому. таких деталей настолько глубоко я не знаю.
Вадим Т.
3240 сообщений
#16 лет назад
SergeD, ну конечно мы не знаем сколько и чего в потоке. Тут мы все немного отвлеклись от темы, и рассматриваем лишь кусок кода про подсчет юников в массиве.

Вообще сеть данной темы форума - про конкурс. Преимущество таких задач, как эта с массивом - довольно просто определить победителя. Задать условие, и набор данных для проверки. У кого быстрее - тот и победил. Нужно продумать оптимальное условие для конкурсной задачи, чтобы и интересно было ребятам поучаствовать, и чтобы был виден уровень участников, и чтобы можно было без особых споров признать кого-то победителем.
Сергей Д.
116 сообщений
#16 лет назад
Я просто хотел этим примером показать что и у простых задач могут быть разные решения. У сложных - тем более.

Но эти задачи должны быть "программистскими" и не требовать знаний из каких то конкретных предметных областей....
 Falcon
400 сообщений
#16 лет назад
tvv, там строки наверняка копируются только при необходимости изменения, а пока только чтение идет, копируется совместно используемый поинтер и увеличивается reference count. Старый трюк. Но всё равно не очень не понятно с PHP-ссылками.

Насчет конкурса - в скорости состязаться, оно, конечно, занятно. Типа как спорт. Но интереснее было бы какую-нибудь качественно осмысленную вещь делать. Интрига больше, да и не критична скорость для PHP...
Георгиевич Владимир
170 сообщений
#16 лет назад
Клуб офф-топеров )))
не забудьте о идее. идея хорошая нужно продвигать.
Александр Л.
473 сообщения
#16 лет назад
Оффтопик
а я по второй странице так понял что конкурс уже начался
Андрей Д.
1267 сообщений
#16 лет назад

$arr = explode(" ", "да нет да нет да нет нет нет почему"); // Входной массив слов
$narr = array();

foreach($arr as $w) !isset($narr) ? $narr = 1 : $narr++;

echo "<pre>";
print_r($narr);
echo "</pre>";

echo "<br>Всего слов: " . count($arr) . ", уникальных: " . count($narr) . ".";


Выводит количество повторений слова
 Falcon
400 сообщений
#16 лет назад
Подчистят...
Денис Захаров
322 сообщения
#16 лет назад
А почему собственно PHP? )) Вот например:
В одном древнем государстве количество денег приравнивалось к длине серебряного бруска. Работник починил дом заказчика за 7 дней, причем в конце каждого дня он требовал по одному дециметру серебра. Хозяин дома, у котрого был брусок серебра длинной 7 дециметров, расплатися с работником, разрезав этот брусок всего 2 раза, и расплачиваясь с работником каждый день. Как он это сделал?

И решения я не знаю ))) но оно точно есть
 Falcon
400 сообщений
#16 лет назад
hobl, вдвое брусок сложил.
Алексей Б.
897 сообщений
#16 лет назад
Втрое, как знак доллара с двумя полосками
Георгиевич Владимир
170 сообщений
#16 лет назад
hobl, первый раз режем на 1, остается 6. оставшиеся 6 режем на 2 и 4.
после первого дня - дал 1 дм. после второго - забрал один, дал 2. после третьего добавил к 2 еще 1. после 4 забрал 3 дал 4...
Андрей З.
57 сообщений
#16 лет назад
Мы тоже готовы выступить в качестве спонсоров с суммой 100$
Денис Захаров
322 сообщения
#16 лет назад
У меня еще несколько есть похожих ))