Обратите внимание на ошибку при подсчете количества случаев

Я создаю простой скрипт.php, который

  1. Создает массив со случайными числами (скажем, 1000 целых)
  2. Выводит изображение, где оно отображает расположение всех этих чисел в масштабе от 0 до наибольшего нарисованного числа.

На выходе получается изображение (с заданной шириной), вот что я получил:

пример вывода изображения

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

Проблема: иногда этот скрипт работает хорошо, но иногда я получаю многочисленные сообщения об ошибках:

Примечание: неопределенное смещение: 398 в /.../index.php в строке 61

Примечание: неопределенное смещение: 125 in /.../index.php в строке 61

Примечание: неопределенное смещение: 192 in /.../index.php в строке 61...

Сценарий ниже, некоторые пояснения:

  • Линия 61 отмечена красным (внизу)
  • Функция toScale() возвращает intval(число / maxNumber * scaleWidth)
  • inb4 ненужное двойное объявление $countts[num]=0, это то, что я сделал, пытаясь решить проблему, похоже, ничего не изменилось
  • $count не используется нигде между этими двумя частями
  • количество ошибок Уведомления никогда не равно общему количеству, это либо несколько, либо ни одного из них.

скриншот кода

Обновление: Как упоминал Barmar, второй цикл из моего кода можно заменить на

$max = max($data); $counts = array_count_values(array_map('toScale', $data));

Это похоже на упрощение кода, но каким-то образом это решает проблему. Есть идеи почему?

1 ответ

Решение

Проблема в том, что вы масштабируете свои числа по-разному в двух циклах.

В первом цикле вы обновляете $max каждый раз через цикл, а затем вызывая toScale(data[$x]), поскольку toScale() зависит от $maxнекоторые числа будут масштабированы до другого максимума.

Во втором цикле все масштабируется до конечного максимума. Так что для тех же значений $data[$a] вы получите другой toScale($data[$a]) этот раз.

Вам нужно рассчитать максимум всех номеров перед любыми звонками на toScale, Один из способов сделать это - вычислить максимум в цикле, который генерирует все случайные числа:

$max = 0;
for ($a = 0; $a < $num; $a++) {
    $rand = rand();
    if ($rand > $max) {
        $max = $rand;
    }
    $data[] = $rand;
}

Или вы можете сделать это с помощью встроенной функции:

$max = max($data);
$counts = array_count_values(array_map('toScale', $data));
Другие вопросы по тегам