Недавно подкинули задачку: Чем короче решение - тем лучше. Решил её вот так: PHP: <? $str1 = "abcd 01234 87 01235"; function work($text) { $result = ''; $prev = 0; $valid = true; $convmap = array(0x80, 0xFFFF, 0, 0xFFFF); $words = explode(" ",$text); foreach ($words as $word) { for ($i = 0, $c=mb_strlen($word); $i < $c; $i++) { $mb_char = mb_substr($word, $i, 1); $cur =(mb_ereg("&#(\\d+);", mb_encode_numericentity($mb_char, $convmap, "UTF-8"), $match))? $match[1] : ord($mb_char); if ($prev - $cur != -1 && $prev != 0) $valid = false; $prev = $cur; } if ($valid) $result .= $word . " "; $valid = true; $prev = 0; } return $result; } echo work($str1) . '<br/>'; Стало интересно, а кто как ещё сможет решить?
писал ночью, хотел спать, на компе PHP 5.2. Мне главное суть решения передать. А там ещё тюнинг возможен. Друг сделал решение гораздо короче.
Неинтересно, решается одним проходом по строке, никакого деление на массив слов даже ненадо, знай храни начало последовательности (prev), а непорядочный символ запускает проверку now-prev > 1, и все
function ordUTF8($c, $index = 0, &$bytes = null) { $len = strlen($c); $bytes = 0; if ($index >= $len) return false; $h = ord($c{$index}); if ($h <= 0x7F) { $bytes = 1; return $h; } else if ($h < 0xC2) return false; else if ($h <= 0xDF && $index < $len - 1) { $bytes = 2; return ($h & 0x1F) << 6 | (ord($c{$index + 1}) & 0x3F); } else if ($h <= 0xEF && $index < $len - 2) { $bytes = 3; return ($h & 0x0F) << 12 | (ord($c{$index + 1}) & 0x3F) << 6 | (ord($c{$index + 2}) & 0x3F); } else if ($h <= 0xF4 && $index < $len - 3) { $bytes = 4; return ($h & 0x0F) << 18 | (ord($c{$index + 1}) & 0x3F) << 12 | (ord($c{$index + 2}) & 0x3F) << 6 | (ord($c{$index + 3}) & 0x3F); } else return false; } с PHP.NET
Осталось только доработать под utf-8 . PHP: <?php function ord_sort($array) { if (!is_array($array)) { return FALSE; } $array_new = array(); foreach ($array as $value) { $array_new[] = ord($value); } natsort($array_new); for ($i = 0; $i < count($array_new); $i++) { if ($i == 0) {continue;} if ($array_new[$i] - $array_new[$i - 1] != 1) {return FALSE;} } $array = array(); foreach ($array_new as $value) { $array[] = chr($value); } return $array; } $str = "abcd 01234 87 01235"; $list = explode(" ", $str); foreach ($list as $word_old) { $word_temp = strtolower($word_old); $array = str_split($word_temp); //$array = mb_split('/\w/s', $word_temp); if (($array = ord_sort($array)) !== FALSE) { $word_new = implode("", $array); if ($word_temp === $word_new) { echo $word_old. " "; } } } ?>
А это самое сложное - заточить под UTF-8 А есть ещё короче решение! Ну что, никто не может ответить? Или влом?
Короч, задача на два этапа делится, 1) поиск в строке подстроки по алфавиту, это как я полагаю, все понимают, что элементарно, НО 2) функция определения позиции символа в таблице кодировки, а над этим надо подумать, так что кому интересно предлагаю решать именно 2 задачу, сам бы помозговал, но пока некогда
Jampire А то что кодировки совершенно разные, одна двухбайтовая, другая нет, это пох))) И пох что останется лишь оооочень малая часть символов))))