Задать вопрос
@Sp1keazyYT

Почему не работает код PHP, работающий со словарём (код в описании)?

Добрый вечер.
Имеется следующий код:
<?php
	$length = $_GET['length'];
	$proto = $_GET['proto'];
	$dead = $_GET['dead'];
	$live = str_replace("*", "", $proto);

	// загрузить соответствующий словарь в $dict
	$dict = file("wordlist/" . $length . "_letters.txt", FILE_IGNORE_NEW_LINES);
	$words = array();

	// цикл по каждому слову в словаре
	foreach($dict as $word){
		$flag = true;
		// проверка, что слово соответствует маске
		for($i=0; $i<strlen($proto); $i++){
			if($proto[$i] == "*"){			// подстановка
				for($j=0; $j<strlen($live); $j++){
					if($word[$i] == $live[$j]){		// disallow a*** matching abba
						$flag = false;
						continue 3;
					}
				}
				continue;
			}
			if($proto[$i] == $word[$i]){	// correct, go to next letter
				continue;
			} else{							// incorrect
				$flag = false;
				continue 2;
			}
		}
		
		if($flag){
			array_push($words, $word);
		}

	}// конец цикла foreach
	unset($word);

	$deadWords = array();

	//удаляем слова с исключёнными буквами
	foreach ($words as $word){
		for ($i=0; $i < strlen($dead); $i++) { 
			if(strpos($word, $dead[$i]) !== false){
				error_log("adding " . $word . " to deadWords");
				array_push($deadWords, $word);
				continue 2;
			}
		}
		
	}
	unset($word);

	$words = array_values(array_diff($words, $deadWords));

	$alphabet = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
	$letters = array_fill_keys(str_split($alphabet), 0);

	// проверка каждой букве на наличие в слове
	foreach($words as $word){
		// проверить каждую букву в каждом слове
		for($i=0; $i<26; $i++){
			if(strpos($word,$alphabet[$i]) !== false){
				$letters[ $alphabet[$i] ]++;
			}
		}
	}// конец цикла foreach
	unset($word);

	arsort($letters, SORT_NUMERIC);

	// нормализуйте числа к размеру слов
	$num_words = count($words);
	foreach($letters as $l => $v){
		$letters[$l] = $letters[$l] / $num_words;
	}


	//удалить буквы с нулевой вероятностю
	foreach($letters as $l=>$v){
		if($v == 0 || $v == 1){
			$letters = array_diff($letters, array($l=>$v));
		}
	}
	unset($l);

	$ret = array("words"=>$words, "letters"=>$letters);
	var_dump($ret);
	//echo json_encode($ret);


Алгоритм:
0) вводим переменные:
- $length = $_GET['length'];
- $proto = $_GET['proto'];
- $dead = $_GET['dead'];
- $live = str_replace("*", "", $proto);
1) подключаем текстовый словарь,
2) запускаем цикл по каждому слову в словаре:
- проверяем, что слово соответствует маске вида **а*с (пример)
3) убираем слова с исключёнными буквами (переменная $dead)
4) проверяем каждую букву на наличие в слове
5) нормализуем числа к размеру слов
6) убираем буквы с нулевой вероятностью
7) выводим массив $ret с возможными словами words и буквами letters

Далее делаю примерный запрос:
".../lookup.php?length=6&proto=а*а*ас&dead=м"
То есть длина слова должна быть 6 символов, маска а*а*ас и исключаем из слова букву "м". По идее должно быть минимум слово "ананас" судя по маске слова и буквы, но вместо этого, даже если не задавать никаких GET запросов в ссылке, выводится только это:
4AkyQXlSoR6P4m.png
Не могу никак понять, в чём может быть проблема. Помогите пожалуйста!
  • Вопрос задан
  • 234 просмотра
Подписаться 1 Простой 10 комментариев
Пригласить эксперта
Ответы на вопрос 2
SagePtr
@SagePtr
Еда - это святое
Кодировка не та, как минимум. А во-вторых, функции для однобайтных кодировок (типа strlen) неправильно работают с многобайтными кодировками, нужно вместо них использовать функции из mbstring (например, strlen заменить на mb_strlen и так далее).
Также мы можем только гадать, какая же кодировка в файле letters.txt, тоже есть вероятность, что не та.
Ответ написан
slo_nik
@slo_nik Куратор тега PHP
Добрый вечер.
А Вас не смущает такая картина при запуске кода?
5cbf57d1d92db335585221.png
Это первое.
Второе, при работе с многобайтными кодировками используйте соответствующие функции.
Например, Вы используете strlen(), а надо использовать mb_strlen()
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы