61

Re: Фільтрація номерів за маскою (задача на 5+)

Оце провіряли? Бо я ще на вашому оптимізованому не дивився.
Mask: abcda
у funivan пропущений телефон [150] => 380666662316

Так це працює.

62 Востаннє редагувалося funivan (03.10.2012 16:15:28)

Re: Фільтрація номерів за маскою (задача на 5+)

Patron i Vo_Vik  у мене це спрацьовує. А має не спрацьовувати. )) Patron поправ код)

if(byMask2("121", "a3a")){
    echo "here";
}

63

Re: Фільтрація номерів за маскою (задача на 5+)

funivan написав:

Patron i Vo_Vik  у мене це спрацьовує. А має не спрацьовувати. )) Patron поправ код)

if(byMask2("121", "a3a")){
    echo "here";
}

СТОП. Я робив лише під буквенні маски.

64

Re: Фільтрація номерів за маскою (задача на 5+)

Replace маска a3a може бути? і якщо може чи а!=3 ?

65

Re: Фільтрація номерів за маскою (задача на 5+)

Vo_Vik написав:

Patron, мені видає помилку у цьому рядку.

 Parse error: syntax error, unexpected '[' in /web/us4/patron.php on line 22
} else if(count(array_keys(str_split($possibility), str_split($possibility)[$i])) == 1){

Я писав цей код в онлайн інтерпритаторі і там чомусь працювало)))

66

Re: Фільтрація номерів за маскою (задача на 5+)

funivan, ні, не може.


Не потрібно так зациклюватись на цій задачі. Вона просто навчальна, для розвитку логіки. Взагалі мабуть більш доцільно було створити якись open-source проект, ніж витрачати час на оптимізацію цієї задачі. Головне, що ми розуміємо, що можна краще, але для цього потрібен час. :)

67

Re: Фільтрація номерів за маскою (задача на 5+)

Не потрібно так зациклюватись на цій задачі.

Це як спорт =) Просто коли вмієш оптимізувати один код і знаєш нюанси в роботі знання пригодяться і в робочому проекті ти використаєш це і зробиш кращий код;)

68

Re: Фільтрація номерів за маскою (задача на 5+)

Тихо-тихо, як це не можливо, а ми вже дописали)) Ще дополіровую покращений варіант)

Ми не зациклюємось, просто задача цікава)

69

Re: Фільтрація номерів за маскою (задача на 5+)

Отже фактично те саме генерування патерну, що і в funivan, тільки враховано те, що цифри можуть бути на початку і в середині маски

"Результати"

funivan time =0.00609993934631 seconds
smart time =0.0399119853973 seconds
Smarter time =0.00767517089844 seconds
Total selected funivan 2 numbers
Total selected smart 1 numbers
Total selected smarter 1 numbers
Mask: a1bcda

Array
(
    [36] => 380931177333
    [59] => 380931576333
)

   

Array
(
    [0] => 380931576333
)

   

Array
(
    [0] => 380931576333
)

"Код"
class NewPhones extends Phones {
    protected $pattern;
    protected function addNumericMask($number,$position) {
    $this->numericMasks[$position] = $number;
  }
    protected function generatePatern() {
        $pattern = array();
        for($i=0;$i<$this->maskLength;$i++) {
            if(array_key_exists($i, $this->numericMasks)) $pattern[$i] ="[".$this->numericMasks[$i]."]";
            else $pattern[$i] = "[0-9]";
            foreach($this->letterMasks as $mask) {
                if ($i>$mask['is'][0])
                    if(in_array($i,$mask['is'])) {
                        $pattern[$i] ="((\\".($mask['is'][0]+1)."))";
                        continue(2);
                    }
                    elseif(in_array($i,$mask['not']))
                        $pattern[$i] = "(?!\\".($mask['is'][0]+1).")".$pattern[$i];
            }
            $pattern[$i] = '('.$pattern[$i].')';
        }
        
        $this->pattern = '/'.implode($pattern).'/U';
    }
    protected function checkNumber($number) {
        if (preg_match($this->pattern, $number, $match)) 
        return str_replace($match[0], '<b>' . $match[0] . '</b>', $number);
        else return false;
    }    
    public function getPhonesByMask ($mask, $numbers) {
        $this->analizeMask($mask);
        $this->generatePatern();
        $goodNumbers = array();
        foreach($numbers as $number) 
                if ($number = $this->checkNumber($number)) $goodNumbers[]=$number;
        return $goodNumbers;
    }    
}

70

Re: Фільтрація номерів за маскою (задача на 5+)

Всього 2 цикли. Думаю швидкість цієї реалізації буде найвищою.

function byMask3($number, $pattern){
        $patternArray = str_split($pattern);
        $number = preg_replace("#[^0-9]#", "", $number);
        while(strlen($possibility = substr($number, 0, strlen($pattern))) >= strlen($pattern)){
            $result = true;
            $possibilityArray = str_split($possibility);
            foreach($patternArray as $key=>$val){
                if(count($keys = array_keys($patternArray, $val)) > 1){
                    if(count($keys) != count(array_keys($possibilityArray, $possibilityArray[$key]))){
                        $result = false;
                        break;
                    }
                    if($possibilityArray[$keys[1]] != $possibilityArray[$key]){
                        $result = false;
                        break;
                    }
                } 
            }
            if($result) { return $possibility; }
            $number = substr($number, 1);
        }
        return false;
    }

РЕЗУЛЬТАТИ:
abb 0676634400
abb 0676633522
abb 0676633644
abb 0678609006
abb 0678608444
abb 0674775771
abb 0679093111
abb 0679155885
abb 0679155991
abb 0675975000
abb 0676637770
abb 0676637337
abb 0676634545
abb 0679093335
abb 0679152003
abb 0679152006
abb 0679152008
abb 0679152009
abb 380934379999
abb 380638347777
abb 380639916666
abb 380931293333
abb 380638873333
abb 380931172222
abb 380935182222
abb 380931177717
abb 380931177776
abb 380931177775
abb 380931177774
abb 380638800777
abb 380931177333
abb 380931177799
abb 380931172233
abb 380634131131
abb 380636227227
abb 380634119411
abb 380639909903
abb 380931288889
abb 380638492000
abb 380931293000
abb 380633709111
abb 380938566111
abb 380635884111
abb 380938106111
abb 380634306111
abb 380931566111
abb 380938155222
abb 380938106222
abb 380938566222
abb 380634331222
abb 380634306222
abb 380931576333
abb 380634219333
abb 380637230333
abb 380636168333
abb 380634101333
abb 380634219444
abb 380931576444
abb 380938045444
abb 380639902444
abb 380934391555
abb 380934124555
abb 380639902555
abb 380935781666
abb 380935137666
abb 380938069666
abb 380636224666
abb 380632775666
abb 380931580666
abb 380638373666
abb 380931575666
abb 380936572777
abb 380938549777
abb 380938549888
abb 380636184888
abb 380938565888
abb 380931565888
abb 380931575888
abb 380635883999
abb 380935137999
abb 380637878999
abb 380931292999
abb 380931172727
abb 380633709070
abb 380639909911
abb 380639909696
abb 380639909797
abb 380639909799
abb 380639909699
abb 380938550003
abb 380938550044
abb 380634331166
abb 380634331188
abb 380634331199
abb 380639909919
abb 380639909959
abb 380931288828
abb 380936556665
abb 380639912424
abb 380633134646
abb 380639916767
abb 380639916868
abb 380636227474
abb 380636228181
abb 380636228787
abb 380637879009
abb 380639912340
abb 380638455544
abb 380638455505
abb 380639912299
abb 380639915533
abb 380639915500
abb 380639916600
abb 380634546611
abb 380634546655
abb 380639916688
abb 380634546677
abb 380639911880
abb 380936556766
abb 380639911616
abb 380938069699
abb 380639909899
abb 380639909930
abb 380639909960
abb 380639909917
abb 380639909934
abb 380639909932
abb 380639909940
abb 380639909941
abb 380639909947
abb 380639909948
abb 380639909951
abb 380639909952
abb 380639909915
abb 380981741000
abb 380981728000
abb 380981729000
abb 380970168111
abb 380963663111
abb 380970289222
abb 380970277333
abb 380677857333
abb 380965517333
abb 380671168333
abb 380963306444
abb 380963307555
abb 380678698555
abb 380970408666
abb 380678619666
abb 380963301888
abb 380970292888
abb 380679885151
abb 380679884848
abb 380988777667
abb 380974441005
abb 380980080056
abb 380970211115
abb 380965655443
abb 380974441134
abb 380963302223
abb 380963303433
abb 380974393339
abb 380678677767
abb 380967277787
abb 380677857677
abb 380970282228
abb 380678656566
abb 380980757577
abb 380980767727
abb 380677907744
abb 380966615566
abb 380969710100
abb 380979610100
abb 380979668008
abb 380985590900
abb 380678619991
abb 380967470008
abb 380974422443
abb 380963382211
abb 380974455611
abb 380963305500
abb 380963311855
abb 380974455448
abb 380974455011
abb 380980022551
abb 380980022552
abb 380974422005
abb 380963302200
abb 380974435577
abb 380974455899
abb 380963381133
abb 380964422889
abb 380974455226
abb 380974455411
abb 380974422003
abb 380988558866
abb 380988566688
abb 380988566677
abb 380988566699
abb 380988558882
abb 380988566606
abb 380988444881
abb 380969696337
abb 380980576676
abb 380980611177
abb 380980011134
abb 380970266655
abb 380970266616
abb 380988777622
abb 380970502228
abb 380974394448
abb 380974422251
abb 380974455520
abb 380974455536
abb 380678149990
abb 380678149991
abb 380678149992
abb 380678149993
abb 380678149994
abb 380678149995
abb 380678149996
abb 380984663939
abb 380966770010
abb 380979660096
abb 380989897008
abb 380977661414
abb 380977661331
abb 380987107111
abb 380960742444
abb 380977661555
abb 380989896995
abb 380988860688
abb 380978666689
abb 380978666766
abb 380501004414
abb 380501811180
abb 380958551234
abb 380990309990
abb 380955450006
abb 380666664515
abb 380666663944
abb 380666663233
abb 380666665144
abb 380666661494
abb 380666662809
abb 380666663415
abb 380666662316
abb 380666661414
abb 380992474111
abb 380663548111
abb 380953857222
abb 380954815444
abb 380663725444
abb 380953857444
abb 380500524666

NEXT MASK

aba 0676634400
aba 0676633522
aba 0676633644
aba 0678609006
aba 0675842020
aba 0674775771
aba 0679093111
aba 0675835358
aba 0675961717
aba 0676637770
aba 0676637337
aba 0676634545
aba 0679093335
aba 380934379999
aba 380638347777
aba 380931177717
aba 380634131131
aba 380636227227
aba 380639909903
aba 380634306111
aba 380634331222
aba 380634306222
aba 380637230333
aba 380636168333
aba 380634101333
aba 380938045444
aba 380934391555
aba 380938069666
aba 380636224666
aba 380638373666
aba 380931575666
aba 380936572777
aba 380636184888
aba 380938565888
aba 380931565888
aba 380931575888
aba 380637878999
aba 380931292999
aba 380935182020
aba 380638405151
aba 380637879494
aba 380931172727
aba 380633709070
aba 380639909911
aba 380639909696
aba 380639909797
aba 380639909799
aba 380639909699
aba 380634331166
aba 380634331188
aba 380634331199
aba 380637878989
aba 380639909919
aba 380639909959
aba 380931288828
aba 380639912424
aba 380938583131
aba 380938584242
aba 380636084545
aba 380633134646
aba 380938584848
aba 380938585353
aba 380938586363
aba 380639916767
aba 380639916868
aba 380636227474
aba 380636207979
aba 380636228181
aba 380636228787
aba 380637879009
aba 380638455505
aba 380634546611
aba 380634546655
aba 380634546677
aba 380936556766
aba 380639911616
aba 380938069699
aba 380639909899
aba 380639909930
aba 380639909960
aba 380639909917
aba 380639909934
aba 380639909932
aba 380639909940
aba 380639909941
aba 380639909947
aba 380639909948
aba 380639909951
aba 380639909952
aba 380639909915
aba 380963663111
aba 380970408666
aba 380970292888
aba 380965656560
aba 380960901090
aba 380960963434
aba 380965656363
aba 380960308686
aba 380960308585
aba 380679885151
aba 380679884848
aba 380980807272
aba 380980080056
aba 380965655443
aba 380963303433
aba 380974393339
aba 380678677767
aba 380967277787
aba 380967279757
aba 380677857677
aba 380970292959
aba 380970282228
aba 380678656566
aba 380980575737
aba 380980757577
aba 380980767727
aba 380980683858
aba 380981729090
aba 380981729090
aba 380969710100
aba 380979610100
aba 380979668008
aba 380985590900
aba 380967470008
aba 380988566606
aba 380969696337
aba 380980808025
aba 380980808034
aba 380980576676
aba 380970266616
aba 380970502228
aba 380984663939
aba 380966770010
aba 380979660096
aba 380989897008
aba 380977661414
aba 380960742444
aba 380989896995
aba 380988860688
aba 380979543216
aba 380978666766
aba 380501004414
aba 380501811180
aba 380958551234
aba 380990309990
aba 380955450006
aba 380666664515
aba 380666663233
aba 380666661494
aba 380666661414
aba 380992474111
aba 380500524666

NEXT MASK

abba 0676633644
abba 0679155885
abba 0676637337
abba 380634131131
abba 380636227227
abba 380639909903
abba 380936556665
abba 380637879009
abba 380936556766
abba 380963663111
abba 380988777667
abba 380980080056
abba 380979668008
abba 380974422443
abba 380963305500
abba 380974455448
abba 380980022552
abba 380963302200
abba 380974455411
abba 380988558866
abba 380988558882
abba 380980576676
abba 380977661331
abba 380990309990
abba 380500524666

71 Востаннє редагувалося Vo_Vik (04.10.2012 05:07:26)

Re: Фільтрація номерів за маскою (задача на 5+)

Доречі ще варіант

"робити прегмач зразу по всьому масиву, там взагалі нема циклів, тільки генерування маски, якщо початковий масив номерів заданий як строка то на одну пару імплоде/експлоде менше вийде"
class NewPhones extends Phones {
    protected $pattern;
    protected function addNumericMask($number,$position) {
    $this->numericMasks[$position] = $number;
  }
    protected function generatePatern() {
        $pattern = array();
        for($i=0;$i<$this->maskLength;$i++) {
            if(array_key_exists($i, $this->numericMasks)) $pattern[$i] ="[".$this->numericMasks[$i]."]";
            else $pattern[$i] = "[0-9]";
            foreach($this->letterMasks as $mask) {
                if ($i>$mask['is'][0])
                    if(in_array($i,$mask['is'])) {
                        $pattern[$i] ="((\\".($mask['is'][0]+1)."))";
                        continue(2);
                    }
                    elseif(in_array($i,$mask['not']))
                        $pattern[$i] = "(?!\\".($mask['is'][0]+1).")".$pattern[$i];
            }
            $pattern[$i] = '('.$pattern[$i].')';
        }
        
        $this->pattern = '/\s[0-9]*'.implode($pattern).'[0-9]*\s/U';
    }
    public function getPhonesByMask ($mask, $numbers) {
        $this->analizeMask($mask);
        $this->generatePatern();
        preg_match_all($this->pattern, ' '.implode('  ',$numbers).' ', $matches);
        return $matches[0];
    }    
}
"таймінги"

funivan time =0.0022439956665039 seconds
smart time =0.0023441314697266 seconds
smarter time =0.0017080307006836 seconds
Total selected funivan 152 numbers
Total selected smart 152 numbers
Total selected replace 152 numbers
Mask: aba

ПС: patron, у вас числові маски працюють?

72 Востаннє редагувалося Vo_Vik (04.10.2012 05:55:09)

Re: Фільтрація номерів за маскою (задача на 5+)

"покращений розрахунок патерну"
class NewPhones3 {
    protected $pattern;
    protected function generatePatern($mask) {
        $pattern = array();
        $mask = str_split($mask);
        $unicMask = array();
        foreach($mask as $position=>$char) {
            if(is_numeric($char)) $pattern[$position] ="[".$char."]";
            else {
                $pattern[$position] = "[0-9]";
                if(is_numeric($i = array_search($char, $unicMask))) {
                    $pattern[$position] = '(\\'.($i+1).')';
                }
                else{
                    foreach($unicMask as $i=>$char)
                        $pattern[$position] = "(?!\\".($i+1).")".$pattern[$position];
                    $unicMask[$position]=$char;
                }
            }
            $pattern[$position] = '('.$pattern[$position].')';
        }
        $this->pattern = '/\s[0-9]*'.implode($pattern).'[0-9]*\s/U';
    }
    public function getPhonesByMask ($mask, $numbers) {
        $this->generatePatern($mask);
        preg_match_all($this->pattern, ' '.implode('  ',$numbers).' ', $matches);
        return $matches[0];
    }    
}
"таймінги"

funivan time =0.0023620128631592 seconds
smart time =0.002479076385498 seconds
smarter time =0.0014598369598389 seconds
Total selected funivan 152 numbers
Total selected smart 152 numbers
Total selected replace 152 numbers
Mask: abcda

на числових масках 0,5 мілісекунди виходить.

73

Re: Фільтрація номерів за маскою (задача на 5+)

Vo_Vik написав:

Доречі ще варіант

"робити прегмач зразу по всьому масиву, там взагалі нема циклів, тільки генерування маски, якщо початковий масив номерів заданий як строка то на одну пару імплоде/експлоде менше вийде"
class NewPhones extends Phones {
    protected $pattern;
    protected function addNumericMask($number,$position) {
    $this->numericMasks[$position] = $number;
  }
    protected function generatePatern() {
        $pattern = array();
        for($i=0;$i<$this->maskLength;$i++) {
            if(array_key_exists($i, $this->numericMasks)) $pattern[$i] ="[".$this->numericMasks[$i]."]";
            else $pattern[$i] = "[0-9]";
            foreach($this->letterMasks as $mask) {
                if ($i>$mask['is'][0])
                    if(in_array($i,$mask['is'])) {
                        $pattern[$i] ="((\\".($mask['is'][0]+1)."))";
                        continue(2);
                    }
                    elseif(in_array($i,$mask['not']))
                        $pattern[$i] = "(?!\\".($mask['is'][0]+1).")".$pattern[$i];
            }
            $pattern[$i] = '('.$pattern[$i].')';
        }
        
        $this->pattern = '/\s[0-9]*'.implode($pattern).'[0-9]*\s/U';
    }
    public function getPhonesByMask ($mask, $numbers) {
        $this->analizeMask($mask);
        $this->generatePatern();
        preg_match_all($this->pattern, ' '.implode('  ',$numbers).' ', $matches);
        return $matches[0];
    }    
}
"таймінги"

funivan time =0.0022439956665039 seconds
smart time =0.0023441314697266 seconds
smarter time =0.0017080307006836 seconds
Total selected funivan 152 numbers
Total selected smart 152 numbers
Total selected replace 152 numbers
Mask: aba

ПС: patron, у вас числові маски працюють?

Неа, під числові маски я вже робив окрему реалізацію.

74

Re: Фільтрація номерів за маскою (задача на 5+)

Ну що народ вітаю =) Всі ми дізнались про прегматчі багато цікавого. =) Особисто я зрозумів як можна робити матч включаючи і виключаючи певні паттерни.

Думаю тему можна закривати =)

75

Re: Фільтрація номерів за маскою (задача на 5+)

Можливо ще хтось захоче в майбутньому розв'язати цю задачу, тому не потрібно закривати.

Подякували: Patron1

76

Re: Фільтрація номерів за маскою (задача на 5+)

Угу після цієї задачі я як то кажуть - j'adore preg_match

Доречі пробував в циклі задавати всі маски від 000 до fff Займає 2.7 секунди.

77

Re: Фільтрація номерів за маскою (задача на 5+)

Та да з масками довга тєма получається. Брутфорс завжди прожорливий

78

Re: Фільтрація номерів за маскою (задача на 5+)

Та нє, Я маю наувазі, що тому скрипту передавав почерзі всі маски, щоб глянути як він реагує на кожну, бо на одних масках один може швидще працювати, а на інших інший.

79

Re: Фільтрація номерів за маскою (задача на 5+)

А догнав) ну так. Різні маски по різному))