LINUX.ORG.RU

А вы бы приняли такой ответ?

 , ,


0

2

Привет ЛОР!

Недавно,между делом, хотел пройти маленький тест на php задача была такова: нужно объявить массив, в цикле от 1 до 100 заполнить его случайными цифрами (тоже от 1го до 100), и в итоге получить массив с уникальными значениями, реализовать минимальным кол-вом строк

Чтоб решить по-быстрому и красиво я прибегнул к жульничеству:

<?php
$arr = range(1, 100);
shuffle($arr);
foreach ($arr as $key) {
    echo "$key ";
    }
?>

То есть, результат вроде бы тот, что нужно, но достигнут не тем путём, который требовался.

А сжульничал я во-первых, потому, что если генерировать случайные числа через mt_rand() нам нужно после избавиться от дублей и, в то же время, обеспечить, чтобы в массиве точно были все числа от 1 до 100.

Во-вторых, потому, что посчитал это красивым решением да и требовали минимум строк :-)

Пацаны это лечится?!

★★★★★

Последнее исправление: Twissel (всего исправлений: 2)
Ответ на: комментарий от Twissel

Хотя, зачем Гугл?

Можно просто добавить вот эту строчку в код автора

if (!isset($a[$i])) echo "<pre>fail!\n</pre>";

Вуаля!

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

И чтоб я уже совсем успокоился, код, который наглядно показывает дырки в массиве:

<?php
$j = 0;
$a=array();
for($i=1;$i<=100;$i++){
  $t=rand(1,100);
  $a[$t]=$t;
  
  } 
 for ($k=1;$k <= 100;$k++){
	  if (!isset($a[$k])) $j++;} 
  echo $j."<br/>";
  var_dump($a);
Фуух, у меня все, господа!

Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от Waterlaz

Я больше не буду такое на ЛОРчик тащить, честно!

Я думал, что он серьёзный дяденька.

А оказалось, что он даже глупее меня :-D

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Сам автор заявил, что его устраивает частичная заполненность ключей 0..100, так что смысл твоего занятия не ясен, а вопрос остался без ответа.

staseg ★★★★★
()
Ответ на: комментарий от staseg

Например, чтобы показать, что если в массиве есть нуллы, то уже нельзя сказать,что это массив уникальных значений.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Там нет нуллов, там вообще ничего нет. С т.з. php это нормальный полностью заполненный массив. Ассоциативный. Других там нет. Убедиться можешь, посмотрев keys или values этого массива (я точно не помню синтаксис), пробелов там не будет.

staseg ★★★★★
()
Ответ на: комментарий от staseg

Хм, а вот это уже интересно, если я просматриваю после нескольких запусков, например содержимое

var_dump($a[6])
То примерно в 30% испытаний получаю NULL в выхлоп, как это объяснить?!

Twissel ★★★★★
() автор топика
Ответ на: комментарий от staseg

посмотрев keys или values этого массива (я точно не помню синтаксис)

Это можно сделать и просто через print_r

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Правда этот код у меня нормально работает на php 5.3 из Денвера, под онтопиком, запускаться отказался, хз, почему)

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Хотя скорее всего дело в настройках Апач.

Из консоли по

php /var/www/test.php 

Все работает и на 5.6 :-)

ДОБАВЛЕНО:

И тут же в консоли есть вполне ожидаемое

PHP Notice:  Undefined offset:6
Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от anonymous

А зачем ты это тут пишешь, если у ТС в ОП сразу приведено более эффективное решение чем твоё?

Just 4 lulz

К тому же, тут что-то было о непредвзятости выборок, а этот способ даёт настолько случайные перестоновки, насколько качественный используется ГПСЧ

instant
()
Ответ на: комментарий от instant

Правильно реализованный shuffle (например, по Фишеру–Йетсу) генерирует непредвзятую выборку.

mix_mix ★★★★★
()
Последнее исправление: mix_mix (всего исправлений: 1)
Ответ на: комментарий от staseg

Этот топик уже всем глаза намозолил, конечно, но нуллы, приятель там все-таки будут.

Если прикрутить xdebug для симпатичного вывода и запустить такую модификацию авторского «шедевра»

<?php
$j = 0;
$a=array();
for($i=1;$i<=100;$i++){
  $t=rand(1,100);
  $a[$t]=$t;
  var_dump($a[i]);
  }
  var_dump($a); 

Все тайное станет явным.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Все оказалось примитивно: права на файл test.php.

Хотя странно, почему при таких условиях, нормально работал один код и не работал другой...

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Я тебе не приятель, дружище.

Исправь опечатку в своем коде. RTFM php arrays. print_r(array_values($a)) – найдешь дырки, свистни.

staseg ★★★★★
()
Ответ на: комментарий от staseg

Ну хорошо, а чем тогда var_dump не православен?

Точнее такое его использование. Я правда не в курсе ^—^

Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от Twissel

no-such-file, какой код адекватно отображает внутреннее представление подобных массивов?

С var_dump или print_r(array_values($a)) и почему?

Вопрос вроде мелкий, но мне тут уже важно докопаться до сути вопроса :-)

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Есть правда вот такое описание: http://stackoverflow.com/questions/3406171/php-var-dump-vs-print-r

И да, я дамплю значения на этапе итерации по массиву, а вывод print_r(array_values($a)) уже после его заполнения, так что возможно, что данные, полученные через print_r адекватны.

Не знаю.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Да дело не в var_dump. Бдин, распечатай любым удобным способом содержимое массива, дырок или NULL-ов там не будет. То, что явное обращение к какому-то индексу в массиве возвращает NULL, ни о чем не говорит.

staseg ★★★★★
()
Ответ на: комментарий от staseg

Я так понимаю: поскольку массив ассоциативный, после его формирования дырок там нет. Есть просто соответствие «ключ» => «значение»

А вот если идти по нему в цикле от 1 до 100 в момент заполнения, я не совсем уверен, насчет его внутреннего представления.

Как-то так.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

где гарантия, что ВСЕ 100 элементов будут заполнены?

Да не нужно там ВСЕ 100 элементов, я так понял ему нужен просто список уникальных результатов сотни вызовов rand. И сам понимаешь, что это абсолютно отличная задача от сабжа.
В общем, он не умеет объяснять, ты не умеешь уточнять (поверь, это важно в процессе деятельности над проектами) и не можешь передать смысл задачи, говнокод здесь в любом решении, ну а что еще ждать от пыха. Отписался потому что уже 2 страницы исписали после поста недоработодателя, а так никто и не указал, на различие в заданиях. А вообще, у тебя по крайней мере ход мыслей стал правильным:

А может все-таки Руби, а?!

comp00 ★★★★
()
Последнее исправление: comp00 (всего исправлений: 1)
Ответ на: комментарий от comp00

Спасибо за отклик. Да, задача поставлена криво, это факт.

Хотя парни с govnokod.ru тоже сходу предложили shuffle :D

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

поскольку массив ассоциативный, после его формирования дырок там нет

Зависит от того, что понимать под «дыркой». Массивы в пыхе пытаются сидеть на двух стульях сразу - они и ассоциативные и простые с числовым индексом, всё зависит от того как ты на это смотришь и как используешь. Т.е. например можно обходить массив как обычный через for($i=0;$i<count($arr);$i++), тогда ты получишь «дырки», т.к. при отсутствии индекса возвращается null (и кидается notice). А можно обходить через foreach, тогда «дырок» не будет.

адекватно отображает внутреннее представление подобных массивов

var_dump

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

То есть все зависит от методов работы с массивом, как я и предполагал.

Они, собственно, и определяют его интерпретацию.

Ясно, спасибо :-)

И при случае загляну в исходники функции array_values для порядка.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от staseg

Не батхерта ради, а порядка для — статья про array_values.

Как видно задача функции вернуть значения из массива на входе в массив с числовыми ключами на выходе.

Значения, а не нуллы, которые по здравому размышлению и хранить то незачем.

Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от staseg

То есть, в таком коде «дырок» в массиве тоже не будет, если передать его в array_values

<?php
$j = 0;
$a=array();
$b=array();
for($i=1;$i<=100;$i++){
    $a[$i]=rand(1,100);
  }
  $b=array_unique($a);
  print_r(array_values($b))
?>
Хотя на самом деле они там есть ;-)

Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от staseg

И, кстати, интересный момент: «дырки» будут как раз в местах дублей функции rand() при прогоне массива в сплошную.

Чем кстати и объясняется заполненность результирующего массива примерно на 60%

Twissel ★★★★★
() автор топика

Напишу себе для памяти и тред можно удалять :-D

Итак, следуя автору, получаем такой расклад.

Примерно 60 итераций, мы генерируем уникальные значения. Остальные 40 — гоняем эти значения в пределах наших ~60 элементов, получая дубликаты. После 100-й итерации получаем наш многострадальный ассоциативный массив без «дырок»

У меня все.

Закрывайте тред.

Надоел :-)

Twissel ★★★★★
() автор топика

Авторский пример идеален для демонстрации «КПД» функции rand() на выборке из 100 элементов.

Для того, чтобы получить нормальный рандом без значительного числа повторов, нужно велосипедить свою функцию rand(), я считаю.

Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от A1

Каждый волен устранить конфликт по своему.

в твоем случае после set() ты потеряешь порядок элементов, и большая часть энтропии потеряется.

maloi ★★★★★
()
Ответ на: комментарий от maloi

в твоем случае после set()

Моего случая не было)

ты потеряешь порядок элементов

Но вообще ничего не мешает отфильтровать с сохранением порядка.

A1
()
Ответ на: комментарий от gh0stwizard

со своим генератором чисел и дергать нужно его, а не псевдорандомный rand из ОС (лол)

в стандартных библиотеках нормальных ЯП есть shuffle принимающая генератор случайных чисел в качестве параметра.

maloi ★★★★★
()

Как по мне - это одно из лучших возможных решений этой задачи. Костылем, воркараундом итд., это назвать нельзя. Также, оно демонстрирует что автор с пхп глубже чем 5 минут погуглил, так как я не знаю другого яп, где есть отдельная функция для рандомного перемешивания массивов. Как по мне - ей не место в ядре языка, (но это же пхп, что с него взять) например в perl - функция shuffle это часть стандартного модуля List::Util, но не ядра самого языка. В общем автор молодец, возьми свой пряник).

P.S решение на perl «в лоб», без использования List::Util:

my %numbers;

$numbers{ int rand 100 } = 1 while keys %numbers < 100;

print join ' ', keys %numbers;

SDSWanderer
()
Ответ на: комментарий от ilovewindows

А так ты афигенно крут, посмотрел перед собеседованием функции для работы с массивами и общаться не желаешь - это давай до свидания.

Не знаешь что есть функции рендж и шаффл - это давай до свидания.

drull ★☆☆☆
()
2 апреля 2016 г.

Соррян за некрофилию если что. Случайно наткнулся, и теперь спать не смогу, пока не напишу :D. Не понимаю, в чем трабл собственно? Вариант решения ТС - отличный, хотя и не совсем соответствует ТЗ. Вариант с флагами - рабочий, но зачем? Да и жрать он будет ого-го (хотя может быть и не будет:)).

Думаю, это самый норм:

<?php
$a = array();
for($i = 0; $i < 100; $i++){
	$t = rand(1,100);
//Проверяем, есть ли такой элемент в массиве
	if(!in_array($t, $a)){
//Если нет, пишем
		$a[$i] = $t;
	}else{
//Если да, тогда декрементрируем
		$i--;
	}
//и рандомим, пока не получим уникальное значение
}
//Выводим элементы массива
print_r($a);
echo "</br>";
//Узнаем количество элементов
$count = count($a);
echo $count; //==100 [complete]

/*<?php
$a=array();
for($i=0;$i<100;$i++){
 $t=rand(1,100);
 $a[$t]=$t;
}
print_r($a);
echo "</br>";
$count = count($a);
echo $count;//Рандомное число (в среднем от 55 до 70)
?>*/
?>

А тот вариант, который HR предложил, совсем никуда не годится. Как можно видеть, количество элементов будет меньше необходимой сотни.

anonymous
()
24 января 2017 г.
Ответ на: комментарий от anonymous

<?php for($i=0,$a=array();$t=rand(1,100),$i<100;$a[$t]=$t,$i++);

anonymous
()
Ответ на: комментарий от anonymous

По прошествии времени да, это таки самый годный вариант.

Хоть и строк не минимум.

Twissel ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.