Перевести номер телефона в комбинацию букв на клавиатуре телефона

перевести номер телефона в комбинацию букв на клавиатуре телефона

Доброго времени суток! Помогите пожалуйста составить функцию перевода номера телефона в во всевозможную комбинацию букв с клавиатуры телефона. Есть к примеру номер: 2345678 Мне надо составить комбинацию букв с каждой цифрой номера телефона: ну вот так: adgjmpt adgjmpu adgjmpv adgjmqt adgjmqu adgjmqv adgjmrt adgjmru adgjmrv

Все комбинации с клавиатуры могу составить, а вот из номера с клавиатуры не получается. Помогите, плиз.

24 ответа

как записать буквы в виде массивов я знаю. и как всевозможные комбинации тоже(сделал foreach'ами)

а вот как сделать так чтобы исходя из цифр номера телефона сделать комбинации - я не понимаю(

как записать буквы в виде массивов я знаю. и как всевозможные комбинации тоже(сделал foreach'ами)

а вот как сделать так чтобы исходя из цифр номера телефона сделать комбинации - я не понимаю(

UAS написал. У тебя есть многомерный массив, где ключ первого порядка - это цифра от 0 до 9. вложенный массив - массив всевозможных значений. Перебираешь в том же foreach по одному. Хотя, возможно и рекурсивная функция была бы здесь к месту (но и поджирала бы памяти по-больше). У тебя, как я вижу, в любом варианте должны получиться вложенные foreach'и. Сколько цифр - столько вложений foreach.

Ну, я не мегопогромист. НО функцией (+рекурсивной) было бы с точки зрения красоты кода, правильнее. Тогда бы тебе пришлось просто передавать функции номер любой длины. Главное не переусердствовать. :) А-то скормишь 12-значное число и просчет 16млн комбинаций угробит сервер.

Можно поинтересоваться о цели разработки? Не уж-то шалишь и пароль подбираешь? )

Подбирает человек красивые короткие номера, которые соответствуют каким-нибудь словам на клавиатуре. Видел в пиратских фильмах надпись "Звоните нам - наш телефон 1-800-NOCOPIES"? Вот это оно и есть

При рекурсивной функции с подобной глубиной стека (т.е. при большом кол-ве цифр) получишь ошибку. Так что в виду отсутствия оптимизации хвостовой рекурсии (привет, Nemerle:)) в таких случаях надо все только на циклах решать.

Ну я же написал, что с точки зрения красоты ))) Кстати, как в циклах организовывается глубина в данной задаче? читается strlen и. смутно представляю себе алгоритм, который делает вложения с учетом длинны.

Ну просто ты написал, что рекурсивной лучше. Вот я и представил рекурсию с глубиной в 26^(кол-во цифр). В общем, в 8 утра затупил что-то.

Тут по идее все решается множествами вложенных for (т.е. влоб), либо придумать какие-то графы состояний и обернуть все это дело в красивую мат.модель (громко говоря). Код будет яснее, но не факт, что быстрее.

Ну просто ты написал, что рекурсивной лучше. Вот я и представил рекурсию с глубиной в 26^(кол-во цифр). В общем, в 8 утра затупил что-то.

Тут по идее все решается множествами вложенных for (т.е. влоб), либо придумать какие-то графы состояний и обернуть все это дело в красивую мат.модель (громко говоря). Код будет яснее, но не факт, что быстрее.

Странно, я считал 4^коль-во цифр. ведь на одной цифре максимум 4 буквы.

class num2array < private $ret ; private $txt ; private $phone = array ( '1' => array ( '.' , ',' , '?' , '!' , '\'' , '"' , '1' ) , '2' => array ( 'a' , 'b' , 'c' , '2' ) , '3' => array ( 'd' , 'e' , 'f' , '3' ) , '4' => array ( 'g' , 'h' , 'i' , '4' ) , '5' => array ( 'j' , 'k' , 'l' , '5' ) , '6' => array ( 'm' , 'n' , 'o' , '6' ) , '7' => array ( 'p' , 'q' , 'r' , 's' , '7' ) , '8' => array ( 't' , 'u' , 'v' , '8' ) , '9' => array ( 'w' , 'x' , 'y' , 'z' , '9' ) , '0' => array ( ' ' , '0' ) ) ;

private function skit_happens ( $tmp , $pos ) < foreach ( $this -> phone [ $this -> txt [ $pos ] ] as $zz ) < $ttt = $tmp . $zz ; if ( $pos + 1 < strlen ( $this -> txt ) ) $this -> skit_happens ( $ttt , $pos + 1 ) ; else $this -> ret [ ] = $ttt ; > >

public function run ( $text ) < $this -> txt = $text ; $this -> ret = array ( ) ; $this -> skit_happens ( '' , 0 ) ; return $this -> ret ; >

$a = new num2array ( ) ; $b = $a -> run ( '123456' ) ;

for ( $i = 0 ; $i < count ( $b ) ; $i ++ ) echo $b [ $i ] . '<br />' ; ?>

$phone = array ( '1' => array ( '.' , ',' , '?' , '!' , '\'' , '"' , '1' ) , '2' => array ( 'a' , 'b' , 'c' , '2' ) , '3' => array ( 'd' , 'e' , 'f' , '3' ) , '4' => array ( 'g' , 'h' , 'i' , '4' ) , '5' => array ( 'j' , 'k' , 'l' , '5' ) , '6' => array ( 'm' , 'n' , 'o' , '6' ) , '7' => array ( 'p' , 'q' , 'r' , 's' , '7' ) , '8' => array ( 't' , 'u' , 'v' , '8' ) , '9' => array ( 'w' , 'x' , 'y' , 'z' , '9' ) , '0' => array ( ' ' , '0' ) ) ;

function skit_happens ( $text , $tmp , $pos ,& $arr ) < global $phone ; for ( $i = 0 ; $i < count ( $phone [ $text [ $pos ] ] ) ; $i ++ ) < $ttt = $tmp . $phone [ $text [ $pos ] ] [ $i ] ; if ( $pos + 1 < strlen ( $text ) ) skit_happens ( $text , $ttt , $pos + 1 , $arr ) ; else $arr [ ] = $ttt ; > >

skit_happens ( '123456' , '' , 0 , $b ) ;

for ( $i = 0 ; $i < count ( $b ) ; $i ++ ) echo $b [ $i ] . '<br />' ;

То же самое касается strlen($text) - зачем вы ее вызываете на каждой итерации? До входа в цикл один раз вычисляем длину и все.

Код правильный, но пахнет немного. Вам нужно прокачать знания касающиеся оптимизации.

RussianSpy, 1) да помоему без разницы 2) согласен, поэтому изначально и делал с ооп, чтобы все переменные, нужные только для данной задачи были внутри класса а не в глобале или статике

Да, это говнокод. Но это рабочее решение задачи, которая мне нафиг ненужна:) А оптимизации нет предела.

А вот решение без рекурсии:

<?php $num2letter = array ( 2 => array ( 'a' , 'b' , 'c' ) , 3 => array ( 'd' , 'e' , 'f' ) , 4 => array ( 'g' , 'h' , 'i' ) , 5 => array ( 'j' , 'k' , 'l' ) , 6 => array ( 'm' , 'n' , 'o' ) , 7 => array ( 'p' , 'q' , 'r' , 's' ) , 8 => array ( 't' , 'u' , 'v' ) , 9 => array ( 'w' , 'x' , 'y' , 'z' ) ) ;

$number_string = '2345678' ; $len = strlen ( $number_string ) ;

$current_letter = array ( ) ; for ( $i = 0 ; $i < $len ; $i ++ ) $current_letter [ ] = 0 ;

while ( $current_letter [ 0 ] < count ( $num2letter [ intval ( $number_string < 0 >) ] ) ) < $str = '' ; for ( $i = 0 ; $i < $len ; $i ++ ) < $str .= $num2letter [ intval ( $number_string < $i >) ] [ $current_letter [ $i ] ] ; if ( $i == $len - 1 ) < $current_letter [ $i ] ++; for ( $j = $i ; $j > 0 ; $j -- ) < if ( $current_letter [ $j ] >= count ( $num2letter [ intval ( $number_string < $j >) ] ) ) < $current_letter [ $j ] = 0 ; if ( $j > 0 ) $current_letter [ $j - 1 ] ++; > > > > echo $str . '<br/>' ; > ?>

class num2array < private $ret ; private $txt ; private $len ; private $phone = array ( 1 => array ( '.' , ',' , '?' , '!' , '\'' , '"' , '1' ) , 2 => array ( 'a' , 'b' , 'c' , '2' ) , 3 => array ( 'd' , 'e' , 'f' , '3' ) , 4 => array ( 'g' , 'h' , 'i' , '4' ) , 5 => array ( 'j' , 'k' , 'l' , '5' ) , 6 => array ( 'm' , 'n' , 'o' , '6' ) , 7 => array ( 'p' , 'q' , 'r' , 's' , '7' ) , 8 => array ( 't' , 'u' , 'v' , '8' ) , 9 => array ( 'w' , 'x' , 'y' , 'z' , '9' ) , 0 => array ( ' ' , '0' ) ) ;

private function skit_happens ( $tmp , $pos ) < $a = $this -> phone [ $this -> txt [ $pos ] ] ; $b = $pos + 1 ; $c = count ( $a ) ; for ( $i = 0 ; $i < $c ; $i ++ ) < $ttt = $tmp . $a [ $i ] ; if ( $b < $this -> len ) $this -> skit_happens ( $ttt , $b ) ; else $this -> ret [ ] = $ttt ; > >

public function run ( $text )

$a = new num2array ( ) ;

$time_start = microtime ( 1 ) ; $b = $a -> run ( '0501234567' ) ; $time_end = microtime ( 1 ) ; $time = $time_end - $time_start ; $counter = count ( $b ) ; echo "Found $counter in $time seconds<br />" ;

[QUOTE=arrjj] А заменив в варианте Александра конструкции вида intval($number_string) на $number_string[$i] скорость возросла до 7 секунд [/QUOTE] Ну это уже вопросы к конкретному языку PHP. :)

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

<?php $num2letter = array ( 1 => array ( '.' , ',' , '?' , '!' , '\'' , '"' , '1' ) , 2 => array ( 'a' , 'b' , 'c' , '2' ) , 3 => array ( 'd' , 'e' , 'f' , '3' ) , 4 => array ( 'g' , 'h' , 'i' , '4' ) , 5 => array ( 'j' , 'k' , 'l' , '5' ) , 6 => array ( 'm' , 'n' , 'o' , '6' ) , 7 => array ( 'p' , 'q' , 'r' , 's' , '7' ) , 8 => array ( 't' , 'u' , 'v' , '8' ) , 9 => array ( 'w' , 'x' , 'y' , 'z' , '9' ) , 0 => array ( ' ' , '0' ) ) ;

$time_start = microtime ( 1 ) ; $len = strlen ( $number_string ) ;

$current_letter = array ( ) ; $ff = array ( ) ; $pp = array ( ) ; for ( $i = 0 ; $i < $len ; $i ++ ) < $current_letter [ ] = 0 ; $ff [ ] = count ( $num2letter [ $number_string [ $i ] ] ) ; $pp [ ] = $num2letter [ $number_string [ $i ] ] ; > $counter = 0 ; $gg = $ff [ $number_string [ 0 ] ] ; $aa = $len - 1 ; while ( $current_letter [ 0 ] < $gg ) < $str = '' ; for ( $i = 0 ; $i < $len ; $i ++ ) < $str .= $pp [ $current_letter [ $i ] ] ;

$current_letter [ $aa ] ++; if ( $current_letter [ $aa ] >= $ff [ $aa ] ) ; for ( $j = $aa ; $j && ( $current_letter [ $j ] >= $ff [ $j ] ) ; $j -- ) < $current_letter [ $j ] = 0 ; $current_letter [ $j - 1 ] ++; >

$counter ++; //echo $str.'<br/>'; > $time_end = microtime ( 1 ) ; $time = $time_end - $time_start ; echo "Found $counter in $time seconds<br />" ; ?>

📎📎📎📎📎📎📎📎📎📎