Как проверить сходство

Статус
Закрыто для дальнейших ответов.

FiRеFоX

V.I.P.
Регистрация
07.08.2010
Сообщения
744
Имеется поле 3х3(квадрат), заполненный числами в клетках(рандомно от 1 до 100), также имеется 3 числа в массиве(динамичные):
Код:
$array = array($n1,$n2,$n3);
Как проверить есть ли совпадения по горизонтали или вертикали по 3 числа? Вобщем числа должны совпасть все 3 по горизонтали в любой строке или вертикали(тоже любой строки).ScreenShot004.jpg
На скрине показаны какие должны быть совпадения.
Вот как это сделать?
 

brevis

Well-Known Member
Регистрация
10.08.2010
Сообщения
452
Код:
// без защиты от дурака (всяческих проверок на размеры массивов...)
function check($array, $check)
{
  if ( in_array($check, $array) ) return true;
  for ($i=0,$c=count($array); $i<$c; $i++)
  {
    $a = array();
    for ($j=0,$c2=count($array[$i]); $j<$c2; $j++) $a[] = $array[$j][$i];
    if ( $a === $check ) return true;
  }
 
  return false;
}

$matrix = array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9));
var_dump( check($matrix, array(1, 2, 3)) ); //true
var_dump( check($matrix, array(4, 5, 6)) ); //true
var_dump( check($matrix, array(7, 8, 9)) ); //true
var_dump( check($matrix, array(1, 4, 7)) ); //true
var_dump( check($matrix, array(2, 5, 8)) ); //true
var_dump( check($matrix, array(3, 6, 9)) ); //true
var_dump( check($matrix, array(1, 2, 4)) ); //false
 

FiRеFоX

V.I.P.
Регистрация
07.08.2010
Сообщения
744
Спасибо, работает! Ждал хотя бы подсказки, но за реализацию отдельный плюс!
 

AngelGabriel

И имя мне - легион
Регистрация
23.11.2008
Сообщения
778
Я давно с пхп не работал
Код:
for ($i=0,$c=count($array); $i<$c; $i++)
есть разница?
Код:
for ($i=0, $i<count($array); $i++)
и далее..
 

tigra60

Спасатель
Регистрация
10.12.2009
Сообщения
1 990
В первом варианте функция count() вызывается один раз, а во втором - при каждой итерации цикла.
При достаточно большом массиве будет заметно.
Кроме того, переменная $c может использоваться и внутри цикла.
 

ArhAngel

Well-Known Member
Регистрация
07.05.2011
Сообщения
378
В первом варианте функция count() вызывается один раз, а во втором - при каждой итерации цикла.
Ну почти так)
По логике - все верно, но вот интерпретатор php он не такой уже и дурак, и результаты функций кеширует, т.е. если $array не изменится внутри цикла, то count($array) не будет каждый раз выполнятся, а просто подставится уже известный результат.

Сам проверял однажды время выполнения функции выполняемой с неизменяемым объектом дважды, первый раз время выполнения было порядка 0.009c а второй раз уже 0.001c, если функции выполняются последовательно вроде этого.

Код:
myFunction();
myFunction();
Ну это к примеру. Где-то видел статью на эту тему, и потом сам решил попробывать.
 

AngelGabriel

И имя мне - легион
Регистрация
23.11.2008
Сообщения
778
Да, точно, вот здесь еще есть рассуждения http://ua2.php.net/manual/ru/control-structures.for.php
 

ArhAngel

Well-Known Member
Регистрация
07.05.2011
Сообщения
378
Ну вот, специально пример
Код:
<pre>
<?php
for($i = 0; $i < 100000; $i++) $array[] = $i;

$summ = 0;
$begin_time = (float)microtime(true);
for($i = 0; $i < count($array); $i++) $summ+=$array[$i];
echo (float)microtime(true) - $begin_time."\n\n";
$begin_time = (float)microtime(true);
$count_array = count($array);
for($i = 0; $i < $count_array; $i++) $summ+=$array[$i];
echo (float)microtime(true) - $begin_time."\n\n";
?></pre>
В результате
Код:
0.032065868377686
0.031040906906128
Ну как вам "огромная" разница?
 

brevis

Well-Known Member
Регистрация
10.08.2010
Сообщения
452
На 100 тысячах не видно. На миллионе уже что-то.
Замеряй на 10 миллионах -- с удовольствием посмотрим.
 

ArhAngel

Well-Known Member
Регистрация
07.05.2011
Сообщения
378
1 000 000
Код:
0.33192300796509
0.27293014526367
Для десятка лям пришлось переписать код, иначе просто не выполнялись циклы с 10 000 000 итераций, вис скрипт
Код:
<pre>
<?php
$array[] = 1;
while(count($array) < 1000000){
$array[] = $i;
}
$summ = 0;
$begin_time = (float)microtime(true);
for($k = 0; $k < 10; $k++) for($i = 0; $i < count($array); $i++) $i;
echo (float)microtime(true) - $begin_time."\n\n";

$begin_time = (float)microtime(true);
$count_array = count($array);
for($k = 0; $k < 10; $k++) for($i = 0; $i < $count_array; $i++) $i;
echo (float)microtime(true) - $begin_time."\n\n";
?></pre>
Но результат уже не так порадовал ((
Код:
2.8813619613647
0.85232591629028

А это уже for($i = 0; $i < $count_array; $i++) и foreach($array as $x) на 100 000 000 в том же стиле)
Код:
6.200217962265
7.5545649528503
 

AngelGabriel

И имя мне - легион
Регистрация
23.11.2008
Сообщения
778
Код:
<?php
$array[] = 1;
while(count($array) < 1000000){
$array[] = $i;
}
$summ = 0;
$begin_time = (float)microtime(true);
for($k = 0; $k < 10; $k++) for($i = 0; $i < count($array); $i++) $i;
echo (float)microtime(true) - $begin_time."\n\n";
$begin_time = (float)microtime(true);
$count_array = count($array);
for($k = 0; $k < 10; $k++) for($i = 0; $i < $count_array; $i++) $i;
echo (float)microtime(true) - $begin_time."\n\n";
?>
добавь комментарии по коду не пойму как работает
 

ArhAngel

Well-Known Member
Регистрация
07.05.2011
Сообщения
378
Код:
<pre>
<?php
$array[] = 1; // инициализируем масив
while(count($array) < 1000000) $array[] = 1;

$begin_time = (float)microtime(true); //Время старта

//тут два вложеных цикла, было бы понятнее,
// если-бы были скобки
for($k = 0; $k < 10; $k++){
    for($i = 0; $i < count($array); $i++){
	    $i; //ничего не делающее выражение
    }
}

//отнимаем от нынешнего микровремени сохраненное
//и выводим на экран
echo (float)microtime(true) - $begin_time."\n\n";

//а тут уже все то-же только без count($array) внутри
$begin_time = (float)microtime(true);
$count_array = count($array);
for($k = 0; $k < 10; $k++) for($i = 0; $i < $count_array; $i++) $i;
echo (float)microtime(true) - $begin_time."\n\n";
?></pre>
Вот пипец
http://codepad.org/PfypeHzB - тут получилось что на 100000 с count($array) работает быстрее))
врет codepad((
 

AngelGabriel

И имя мне - легион
Регистрация
23.11.2008
Сообщения
778
синтаксис пхп я зная кэп. я имел ввиду
Код:
for($k = 0; $k < 10; $k++){
    for($i = 0; $i < count($array); $i++){
		    $i; //ничего не делающее выражение
    }
}
будет ли адекватной оценкой резултат такого перебора якобы 10и лямов
 

ArhAngel

Well-Known Member
Регистрация
07.05.2011
Сообщения
378
будет ли адекватной оценкой резултат такого перебора якобы 10и лямов
почему якобы?
ничего не делающее выражение - все равно выражение, но на его вычисление тратится минимум времени, а значит меньшая вероятность влияния на время это-го же выражения.
Ну это я так думаю. А вообще в первом варианте была сумма, и результат особо не отличался
 
Статус
Закрыто для дальнейших ответов.
Верх Низ