поиск похожих слов

Impuls95

Новичок
поиск похожих слов

Здравствуйте, помогите пожалуйста вот в чем:
имеется тексовый файл с примерно таким содержанием:
----------
Привет, как твои дела?
привет тебе тоже, дела мои отлично!
----------
Необходимо сделать так, что бы скрипт подсчетал сколько раз в данном тексте встретились одинаковые слова (в данном случае: привет и дела )?
 

fixxxer

К.О.
Партнер клуба
Так похожих, или одинаковых?
Эти две задачи различаются по сложности порядка на три.
 

Impuls95

Новичок
fixxxer
извеняюсь за неточность в теме сообщения, меня интересует одинаковые слова!
 

Bred Vilchec

Новичок
Хм, делов-то.
1. Читашь файл в массив
2. Циклом проходишь по всем ячейкам массива
3. Рег. выражением разбиваешь каждую строку на слова, при этом разделителем служат знаки препинания и пробельные символы.
4. Создаешь ассоциативный массив, ключ которого - слово, значение ячейки - число повторений этого слова в массиве.
5. Если слово присутствует среди ключей массива - инкриминируешь соответствующую ячейку, если нет - добавляешь слово в ключи массива.
6. echo $words_array["дела"]; //Выводит 2

может и не самый лучший, но вполне практичный способ.
 

Silex

unitecsys
Можно еще и так, только шаблоны замены для str_replace прдберешь сам в зависимости от текста, и чтение из файла тоже добавишь сам.
PHP:
<?

$string = "Привет, как твои дела? привет тебе тоже, дела мои отлично!";
$array = explode(" ", str_replace(array(',', '-', ':', '.', ';', '!', '?'), '', $string));
print_r(array_count_values ($array)); 

?>
 

Impuls95

Новичок
Bred Vilchec
Ну для кого-то делов-то...
А я например, где-то 60% понял слов которых ты написал :)
Можно по подробнее?...
 

Silex

unitecsys
Impuls95
Мы не ищем легких путей? Посмотреть в РУССКОМ мануале описание приведенных функций в коде из ТРЕХ СТРОК и почитать там же или на Деталях о чтении из файла - тоже слишком просто для тебя?
 

Silex

unitecsys
Impuls95

И я о том же. Выбрать более трудоемкий и менее производительный вариант, чтобы потом еще и расспрашивать о нем, сознавшись, что 60% неподвластны для понимания... В добрый путь :)
 

Impuls95

Новичок
Silex
Все путем, почти разобрался с твоим вариантом (что бы работало как мне нужно)
 

IBSN

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

-~{}~ 14.09.04 18:50:

Мне как всегда делать нечего :) Вот сырой примерчик
PHP:
$string = 'one two three one three four one five';
$array_words = explode(" ", $string);
$count = count($array_words);
$array_words_unique = Array();

for($i=0; $i<$count; $i++)
{
	if(array_key_exists($array_words[$i], $array_words_unique))
		$array_words_unique[$array_words[$i]] += 1;
	else
		$array_words_unique[$array_words[$i]] = 1;
}

print_r($array_words_unique);
 

Bred Vilchec

Новичок
Impuls95
Если не понимаешь большую часть моих слов - дорога в ман, учебники и форумы.

Silex
Ничего личного, но, если честно, мне от такого кода становится не по себе. Ну не могу я читать и обдумывать по нескольку операторов в строке. Думаю, не я один. Ну разве сложно было вставить пару-тройку "лишних" переменных?
Или ТРИ строки кода важней?

IBSN
respect
 

Impuls95

Новичок
Bred Vilchec я же чайник, значит и объяснять надо как чайнику(который на плите :)

IBSN Огромное спасибо тебе !!! я тут немного переработал твой код, теперь я полностью доволен :))
Вот что у меня получилось:

$string = 'one two three one three four one five';
$array_words = explode(" ", $string);
$count = count($array_words);
$array_words_unique = Array();

for($i=0; $i<$count; $i++)
{
if(array_key_exists($array_words[$i], $array_words_unique))
$array_words_unique[$array_words[$i]] += 1;
else
$array_words_unique[$array_words[$i]] = 1;
}

foreach ($array_words_unique as $key => $value) echo "Слово: $key встречается: $value <br>";
 

Bred Vilchec

Новичок
Impuls95

Замечательно!
Это называется "Найдите 10 отличий или Copy/Paste часть вторая".(с)
Поясню:
Кроме замены print_r на foreach тут ничего не изменилось, даже немного ухудшилось (в плане читабельности и табуляции), не говоря уже о том, что на форуме есть такая вещь, как подсветка синтаксиса.
Если что, твой foreach делает то же самое, что и print_r IBSN'a.
Это так, к слову.
Коду IBSNа было бы неплохо еще научиться воспринимать знаки препинания и пробельные символы, а то слова в массиве будут идти в паре с запятыми, точками и прочими ненужными вещами. А так, ИМХО, все ОК.
Если бы ты добавил такую возможность, это действительно была бы переработка (и дополнение).
 

Impuls95

Новичок
Bred Vilchec
:-][
Првавильнее сказать я не переделал, а немножко(!) доделал(подправил) именно так, как мне и нужно было, поэтому я написал весь скрипт (найти 10 отличий...) что и означало, что эта тема может быть уже закрыта и отложена на дальнюю полку этого форума (который служит копилкой знаний) :)
 

SelenIT

IT-лунатик :)
Уважаемые IBSN и Bred Vilchec, не могли бы вы пояснить, почему
PHP:
$count = count($array_words);
$array_words_unique = Array();

for($i=0; $i<$count; $i++)
{
    if(array_key_exists($array_words[$i], $array_words_unique))
        $array_words_unique[$array_words[$i]] += 1;
    else
        $array_words_unique[$array_words[$i]] = 1;
}
предпочтительнее такого варианта?
PHP:
$array_words_unique = array_count_values($array_words);
Разве данный цикл делает не то же самое, что "родная" функция?
 

alpine

Новичок
IBSN
А какая проблема с пробелом в коде Silex?!

-~{}~ 14.09.04 22:20:

И как твой код обрабатывает знаки препинания и специальные символы типа "\r\n", "\t" etc ?
 

SelenIT

IT-лунатик :)
Все приведенные до сих пор варианты не учитывали
а) то, что слова могут быть в разном регистре (как в примере из первого поста Impuls95),
б) разнообразие разделителей между словами (на что указал alpine).

Вот пример - тоже сырой, но с учетом этих пунктов:
PHP:
$string = "Привет, как твои дела?\r\nпривет тебе тоже, дела... дела мои отлично!";

/****  само решение     ********/

// все в нижний регистр
$string = strtolower($string);
// выделим слова
// разделитель - один или больше любых символов кроме букв, цифр, '-' или '_'
$words = preg_split("/[^\w-_]+/",$string);
// получаем массив "слово => количество вхождений"
$unique_words = array_count_values($words);

/****  вывод результата   ******/

// отсортируем массив по убыванию встречаемости
arsort($unique_words);

// выведем результат
foreach($unique_words as $word=>$frequency) {
	// если слово встретилось больше одного раза - выводим
	if ($frequency>1) {
		// сформируем строку для вывода
		$output = 'Слово <i>'.$word.'</i> встречается '.$frequency.' раз';
		// допишем окончание для "2 раза", "53 раза" и т.д.
		if ($frequency%10 >= 2 and $frequency%10 <=4 and floor($frequency/10)!=1) $output .= 'а';
		// выведем строчку
		echo $output,'<br>';
	// как только неуникальные слова закончились - прерываем цикл
	} else break;
}
echo 'Остальные слова встречаются по одному разу';
 

Silex

unitecsys
IBSN
Попрошу без скоропалительных выводов, заодно посмотри в словаре значение слова "бред". Если ты ответишь на вопрос
SelenIT, почему использование собственной ф-ции предпочтительнее аналогичной встроенной (array_count_values()), будет тоже неплохо. Мало того, многократный вызов другой ф-ции (array_key_exists()) тоже не прибавит скорости, что на больших объемах будет особенно заметно.

Если у юзера западет пробел, ничего страшного не случится: в результирующем масиве будет элемент с "пустым" ключом и значением, равным кол-ву "промежутков" между пробелами. Отфильтровать его на выводе - не проблема.

Согласен с SelenIT, что нужно было добавить приведение к нижнему регистру - не учел впопыхах. Хотя использовать регулярки для вырезания символов вместо str_replace() - вряд ли лучше.

Мне как всегда делать нечего
вот-вот...
 
Сверху