Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

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

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

Все комбинации с клавиатуры могу составить, а вот из номера с клавиатуры не получается.
Помогите, плиз.
244
05 апреля 2011 года
UAS
2.0K / / 19.07.2006
Ну и что сложного?
 
Код:
$num2letter = array(
    1 => array('a', 'b', 'c', 'd'),
    2 => array('e', 'f', 'g'),
    ....
);

Ну и дальше циклами перебор делать. Делов на пару строк.
30K
05 апреля 2011 года
EVIL_Source
14 / / 21.01.2008
как записать буквы в виде массивов я знаю.
и как всевозможные комбинации тоже(сделал foreach'ами)

а вот как сделать так чтобы исходя из цифр номера телефона сделать комбинации - я не понимаю(
369
06 апреля 2011 года
Kesano
451 / / 09.10.2007
Цитата: EVIL_Source
как записать буквы в виде массивов я знаю.
и как всевозможные комбинации тоже(сделал foreach'ами)

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



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

13
06 апреля 2011 года
RussianSpy
3.0K / / 04.07.2006
Лучше for вместо foreach - он намного быстрее и foreach тут ни к чему. А так все верно. Только думается мне что автор ждет от нас готового решения.
30K
06 апреля 2011 года
EVIL_Source
14 / / 21.01.2008
Kesano, спасибо! так и сделал.
я просто изначально хтел как функцию написать.чтобы любой длины номер сжирала)
369
07 апреля 2011 года
Kesano
451 / / 09.10.2007
Цитата: EVIL_Source
Kesano, спасибо! так и сделал.
я просто изначально хтел как функцию написать.чтобы любой длины номер сжирала)



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

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

13
07 апреля 2011 года
RussianSpy
3.0K / / 04.07.2006
Цитата: Kesano
Можно поинтересоваться о цели разработки? Не уж-то шалишь и пароль подбираешь? )


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

244
07 апреля 2011 года
UAS
2.0K / / 19.07.2006
Цитата:
НО функцией (+рекурсивной) было бы с точки зрения красоты кода, правильнее.


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

369
07 апреля 2011 года
Kesano
451 / / 09.10.2007
Цитата: UAS
При рекурсивной функции с подобной глубиной стека (т.е. при большом кол-ве цифр) получишь ошибку.
Так что в виду отсутствия оптимизации хвостовой рекурсии (привет, Nemerle:)) в таких случаях надо все только на циклах решать.



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

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

Тут по идее все решается множествами вложенных for (т.е. влоб), либо придумать какие-то графы состояний и обернуть все это дело в красивую мат.модель (громко говоря). Код будет яснее, но не факт, что быстрее.
369
07 апреля 2011 года
Kesano
451 / / 09.10.2007
Цитата: UAS
Ну просто ты написал, что рекурсивной лучше. Вот я и представил рекурсию с глубиной в 26^(кол-во цифр).
В общем, в 8 утра затупил что-то.

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


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

31K
07 апреля 2011 года
homa.andy
6 / / 06.09.2007
Как вы правильно сказали, 4^кц. Другими словами, до 16384 комбинаций для семизначного номера. Куда их выводить-то, как оценивать? Это уж тогда надо сразу словари подключать.
31K
07 апреля 2011 года
homa.andy
6 / / 06.09.2007
Кстати, логичное (пусть и неэффективное) решение — заранее создать все возможные вложенные циклы. Если номер короче, то циклы для последних, отсутствующих цифр будут работать вхолостую, не особо замедляя работу.
277
07 апреля 2011 года
arrjj
1.7K / / 26.01.2011
Код:
<?php

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 />';
?>

Рекурсивно. Максимальная глубина рекурсии равна длине текста.
13
07 апреля 2011 года
RussianSpy
3.0K / / 04.07.2006
2arrjj: у меня ряд вопросов:
1) Зачем тут ООП?
2) Почему ключи 0-9 текстовые, а не числовые
3) Зачем тут foreach?
277
07 апреля 2011 года
arrjj
1.7K / / 26.01.2011
RussianSpy,
1)незачем :) просто накидал на скорую руку.
2)а почему должны быть числовые?
3)А почемубы и нет?
Вот по просьбам трудящихся без ооп и foreach'а
Код:
<?php

$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 />';

?>

//Субьективно - отрабатывают скриты одинаковое время для 10-зачного номера.
13
07 апреля 2011 года
RussianSpy
3.0K / / 04.07.2006
1) Числовые потому что строковые тут не нужны.
2) На будущее - count лучше вынести за пределы цикла иначе при каждой итерации вновь и вновь эта конструкция будет вызываться
 
Код:
$cnt = sizeof($arr);
for($i=0; $i<$cnt; $i++)
{  
/* БЛОК КОДА */
}

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

Код правильный, но пахнет немного. Вам нужно прокачать знания касающиеся оптимизации.
277
07 апреля 2011 года
arrjj
1.7K / / 26.01.2011
RussianSpy,
1) да помоему без разницы
2) согласен, поэтому изначально и делал с ооп, чтобы все переменные, нужные только для данной задачи были внутри класса а не в глобале или статике

Да, это говнокод. Но это рабочее решение задачи, которая мне нафиг ненужна:) А оптимизации нет предела....
278
07 апреля 2011 года
Alexander92
1.1K / / 04.08.2008
А вот решение без рекурсии:

Код:
<?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/>';
 }
 ?>
277
07 апреля 2011 года
arrjj
1.7K / / 26.01.2011
Alexander92, очень медленно работает.
Код:
<?php

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)
{

$this->txt=$text;
$this->ret=array();
$this->len=strlen($text);
$this->skit_happens('',0);
return $this->ret;
}

}



$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 />";

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

Такой отрабатывает у мя на ноуте в среднем за 1.03 сек (без ооп - с постоянным вычислением strlen и count в среднем за 1.55 сек). А вариант Александа в среднем за 13.8 сек.
А заменив в варианте Александра конструкции вида intval($number_string{$j}) на $number_string[$i] скорость возросла до 7 секунд:)
278
07 апреля 2011 года
Alexander92
1.1K / / 04.08.2008
[QUOTE=arrjj]
А заменив в варианте Александра конструкции вида intval($number_string{$j}) на $number_string[$i] скорость возросла до 7 секунд
[/QUOTE]
Ну это уже вопросы к конкретному языку PHP. :)

А вообще, насчет скорости работы, - мне сдается, что без рекурсии вряд ли можно получить что-то существенно быстрее. Нам ведь нужно реализовать полный перебор, а перебор по определению - операция медленная.
277
07 апреля 2011 года
arrjj
1.7K / / 26.01.2011
Вот "оптимизированный" вариант кода Александра:
Код:
<?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'));

 $number_string = '0501234567';

$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 />";
 ?>

Отрабатывает теперь в среднем за 2.2 сек:)
278
07 апреля 2011 года
Alexander92
1.1K / / 04.08.2008
Ok, убедили. :) Хотя я за оптимизацией не гонялся, писал собственно алгоритм.
369
07 апреля 2011 года
Kesano
451 / / 09.10.2007
Красавцы. Много накодили. Я так не умею. Но очень буду стремиться )
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог