Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Наиболее близкое число 
V
    Опции темы
MoLeX
Дата 16.10.2011, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Местный пингвин
****


Профиль
Группа: Модератор
Сообщений: 4076
Регистрация: 17.5.2007

Репутация: 46
Всего: 140



Добрый вечер.

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

Например, у нас массив чисел (ключ это и есть число)
Код

$d[30] = '';
$d[1] = '';
$d[18] = '';
$d[9] = '';
$d[25] = '';


Допустим загадаем число 16, соответственно максимально близкое будет - 18.

И еще один пример:
Код

$d[1] = '';
$d[10] = '';
$d[9] = '';

В этом случае максимально близким числом будет 10.

Как это реализовать?

Это сообщение отредактировал(а) MoLeX - 16.10.2011, 18:45


--------------------
Amazing  smile 
PM MAIL WWW ICQ   Вверх
patap
Дата 16.10.2011, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 893
Регистрация: 7.5.2005
Где: Украина, Зп

Репутация: 26
Всего: 40



Код

$d[1] = '';
$d[10] = '';
$d[9] = '';
    
    $number = 16;
    $result = NULL;

    foreach ($d as $key => $val)
    {
        $diff = abs($key - $number);
        if ( ! $result)
        {
            $result['key'] = $key;
            $result['diff'] = $diff;
            continue;
        }

        if ($result['diff'] > $diff)
        {
            $result['key'] = $key;
            $result['diff'] = $diff;
        }
        
    }

    echo '<pre>';
    print_r($result);


Это сообщение отредактировал(а) patap - 16.10.2011, 19:22


--------------------
На боку кобура болталась, сзади шашка отцовская звякала. 
Впереди меня все хохотало, а позади все плакало (с)
PM MAIL ICQ   Вверх
Absinthe
Дата 16.10.2011, 19:32 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 4.5.2011

Репутация: 5
Всего: 11



Код

<?php

$d[30] = '';
$d[1] = '';
$d[18] = '';
$d[9] = '';
$d[25] = '';

$target = 16;

$unsorted = array_map(function($key) use ($target) { return $key - $target;}, array_keys($d));
usort($unsorted, function($a, $b) {return abs($a) - abs($b);});
echo $unsorted[0] + $target;

PM MAIL   Вверх
Evghenusi
Дата 16.10.2011, 23:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


майский жук
**


Профиль
Группа: Участник
Сообщений: 506
Регистрация: 3.8.2006
Где: Молдова, Кишинёв

Репутация: 6
Всего: 15



решил тоже поучаствовать в теме, не знаю мой вариант ГК или нет, решать вам.

Код
<?php
$n=16;

$d[30] = '';
$d[1] = '';
$d[18] = '';
$d[9] = '';
$d[25] = '';
$d[10] = '';

$a = $d;

if(!isset($a[$n]))
$a[$n] = '';

ksort($a);
$k = array_keys($a);
$f = array_search($n, $k);
$prev = $n - $k[$f-1];
$next = $k[$f+1] - $n;
$result = $prev < $next ? $k[$f-1] : $k[$f+1];

echo "Наиболее близкое число \$d[$result]";
?>

PM WWW   Вверх
Shogun
Дата 17.10.2011, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сёгун-сан
**


Профиль
Группа: Участник
Сообщений: 290
Регистрация: 8.6.2006
Где: Кишинёв

Репутация: 9
Всего: 11



Evghenusi, +1

Это сообщение отредактировал(а) Shogun - 17.10.2011, 11:59


--------------------
2b || !2b
PM MAIL ICQ Skype   Вверх
Evghenusi
Дата 17.10.2011, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


майский жук
**


Профиль
Группа: Участник
Сообщений: 506
Регистрация: 3.8.2006
Где: Молдова, Кишинёв

Репутация: 6
Всего: 15



предыдущий вариант с ошибкой, а новый со страшной проверкой  smile 

Код
<?php
$d[30] = '';
$d[1] = '';
$d[18] = '';
$d[9] = '';
$d[25] = '';
$d[10] = '';

$a[1] = '';
$a[10] = '';
$a[9] = '';

function closest_number($arr, $number)
{
$arr = array_keys($arr);
if(!in_array($number, $arr))
$arr[] = $number;
sort($arr);
$f = array_search($number, $arr);

if(isset($arr[$f-1]) && isset($arr[$f+1]))
{
    if($number - $arr[$f-1] < $arr[$f+1] - $number)
    $result = $arr[$f-1];
    else
    $result = $arr[$f+1];
}
else 
{
    if(isset($arr[$f-1]))
    $result = $arr[$f-1];
    elseif(isset($arr[$f+1]))
    $result = $arr[$f+1];
    else 
    $result = 'увы';
}
return 'Наиболее близкое число '.$result;
}

echo closest_number($d, 16),"\n";
echo closest_number($a, 16);
?>

PM WWW   Вверх
Muerto
Дата 17.10.2011, 14:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1207
Регистрация: 23.9.2006

Репутация: 3
Всего: 4



Нужно отсортировать затем от нашего числа посмотреть влево и вправо, и выбрать.



--------------------
user posted image
PM MAIL   Вверх
Evghenusi
Дата 17.10.2011, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


майский жук
**


Профиль
Группа: Участник
Сообщений: 506
Регистрация: 3.8.2006
Где: Молдова, Кишинёв

Репутация: 6
Всего: 15



Цитата(Muerto @  17.10.2011,  14:27 Найти цитируемый пост)
Нужно отсортировать затем от нашего числа посмотреть влево и вправо, и выбрать.
 smile 

PM WWW   Вверх
Shogun
Дата 17.10.2011, 21:09 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


сёгун-сан
**


Профиль
Группа: Участник
Сообщений: 290
Регистрация: 8.6.2006
Где: Кишинёв

Репутация: 9
Всего: 11



Код

$n = 16;

$ar[30] = '';
$ar[1] = '';
$ar[18] = '';
$ar[9] = '';
$ar[25] = '';
$ar[10] = '';

if (in_array($n, array_keys($ar))) { echo 'Key: ', $n; }

$ar[$n] = '';

ksort($ar);

$keys = array_keys($ar);

$i = array_search($n, $keys);

$key = (abs(abs($keys[$i-1]) - $n) < abs(abs($keys[$i+1]) - $n)) ? $keys[$i-1] : $keys[$i+1];

echo 'Key: ', $key;


Это сообщение отредактировал(а) Shogun - 17.10.2011, 21:50


--------------------
2b || !2b
PM MAIL ICQ Skype   Вверх
Evghenusi
Дата 17.10.2011, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


майский жук
**


Профиль
Группа: Участник
Сообщений: 506
Регистрация: 3.8.2006
Где: Молдова, Кишинёв

Репутация: 6
Всего: 15



Shogun, спасибо за пример, хотя ждал его от Muerto.

Shogun, не знаю что оптимальнее (по скорости, потреблении памяти) ksort или sort, но если равнозначно, да ещё и присутствуют функции in_array и array_keys то почему бы не sort?, и почему не воспользоваться ф. array_keys один раз?  smile 

Зачем выводить сообщение о нахождении в массиве элемента с ключом равным значению искомого числа, а после опустошать ($ar[$n] = '') его значение тоже не совсем понятно.

За пример проверки "получаемых" данных отдельное спасибо, думал abs не понадобится (хотя видел в примерах от patap и Absinthe), а вы доказали что необходим.

Это сообщение отредактировал(а) Evghenusi - 17.10.2011, 22:41
PM WWW   Вверх
MoLeX
Дата 18.10.2011, 06:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Местный пингвин
****


Профиль
Группа: Модератор
Сообщений: 4076
Регистрация: 17.5.2007

Репутация: 46
Всего: 140



Всем спасибо. Больше всех понравился пример Shogun. Но его немного модернизировал
Код

$n = 10;
$ar[30] = '';
$ar[1] = '';
$ar[18] = '';
$ar[9] = '';
$ar[25] = '';
$ar[11] = '';

if( isset($ar[$n]) )
    $key = $n;    
else
{
    $ar[$n] = '';
    ksort($ar);
    $keys = array_keys($ar);
    $i = array_search($n, $keys);
    $key = (abs(abs($keys[$i-1]) - $n) < abs(abs($keys[$i+1]) - $n)) ? $keys[$i-1] : $keys[$i+1];
}

echo 'Key: ', $key;



--------------------
Amazing  smile 
PM MAIL WWW ICQ   Вверх
Shogun
Дата 18.10.2011, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сёгун-сан
**


Профиль
Группа: Участник
Сообщений: 290
Регистрация: 8.6.2006
Где: Кишинёв

Репутация: 9
Всего: 11



MoLeX, isset тут не совсем правильно используется, тогда уж так:

Код

$n = 10;
$ar[30] = '';
$ar[1] = '';
$ar[18] = '';
$ar[9] = '';
$ar[25] = '';
$ar[11] = '';

$key = $n;

if (!array_key_exists($n, $ar))
  {
    $ar[$n] = '';
    ksort($ar);
    $keys = array_keys($ar);
    $i = array_search($n, $keys);
    $key = (abs(abs($keys[$i-1]) - $n) < abs(abs($keys[$i+1]) - $n)) ? $keys[$i-1] : $keys[$i+1];
  }

echo 'Key: ', $key;


Это сообщение отредактировал(а) Shogun - 18.10.2011, 10:23


--------------------
2b || !2b
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1039 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.