Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Список чисел по диапазону....

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
Dragon_Knight
Отправлено: 24 Сентября, 2014 - 17:05:49
Post Id



Гость


Покинул форум
Сообщений всего: 103
Дата рег-ции: Май 2012  
Откуда: г.Мытищи, МО


Помог: 0 раз(а)




Всем привет.

Нужна Ваша помощь, т.е. сам уже не знаю как быть...
Есть строка: "4.17,5.21-5.26,6.0-6.7,6.9-6.19". Задача получить массив чисел: "4.17, 5.21, 5.22, 5.23, 5.24, 5.25, 5.26, 6.0, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.9, 6.10, 6.11, 6.12, 6.13, 6.14, 6.15, 6.16, 6.17, 6.18, 6.19" (Строго в таком виде и никак иначе).
При этом, например число "6.5" меньше числа "6.12".

Пробовал через range, но она строит массив совершенно не в том порядке, т.к. считает что число "6.5" больше числа "6.12", а та-же убирает нули на конце, превращая число "6.0" в "6".

Как можно спарсить такую строку, для получения нужного результата, или как эту строку изменить, но что-бы оставить возможность указания как одного числа, так и диапазона чисел.
 
 Top
RickMan
Отправлено: 24 Сентября, 2014 - 18:15:20
Post Id


Участник


Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012  


Помог: 30 раз(а)




PHP:
скопировать код в буфер обмена
  1.     $str = '4.17,5.21-5.26,6.0-6.7,6.9-6.19';
  2.    $result = array();
  3.    $f_arr = explode(',', $str);
  4.    foreach ($f_arr as $v){
  5.       if (strpos($v, '-') !== false){
  6.         $s_arr = explode('-', $v);
  7.         if (number_format((($s_arr[0] * 10) - floor($s_arr[0] * 10)), 2) !== number_format((($s_arr[1] * 10) - floor($s_arr[1] * 10)), 2)){
  8.           if ($s_arr[0] < $s_arr[1]){
  9.             for ($i = $s_arr[0]; $i<$s_arr[1]; $i += 0.01){
  10.               $result[] = $i;
  11.             }
  12.           }else{
  13.             for ($i = $s_arr[0]; $i>$s_arr[1]; $i -= 0.01){
  14.               $result[] = $i;
  15.             }            
  16.           }
  17.         }else{
  18.           if ($s_arr[0] < $s_arr[1]){
  19.             for ($i = $s_arr[0]; $i<$s_arr[1]; $i += 0.1){
  20.               $result[] = $i;
  21.             }
  22.           }else{
  23.             for ($i = $s_arr[0]; $i>$s_arr[1]; $i -= 0.01){
  24.               $result[] = $i;
  25.             }            
  26.           }
  27.         }
  28.       }else{
  29.         $result[] = $v;
  30.       }
  31.    }
  32.    
  33.    print_r($result);


Вот решение...НО вы не правы по поводу последнего диапазона... Почему вы посчитали что 6,9 = 6,09 )))) Поэтому там диапахон цифр чуть другой)
Ответ в данном случае должен быть:
Цитата:
Array ( [0] => 4.17 [1] => 5.21 [2] => 5.22 [3] => 5.23 [4] => 5.24 [5] => 5.25 [6] => 5.26 [7] => 6.0 [8] => 6.1 [9] => 6.2 [10] => 6.3 [11] => 6.4 [12] => 6.5 [13] => 6.6 [14] => 6.7 [15] => 6.9 [16] => 6.89 [17] => 6.88 [18] => 6.87 [19] => 6.86 [20] => 6.85 [21] => 6.84 [22] => 6.83 [23] => 6.82 [24] => 6.81 [25] => 6.8 [26] => 6.79 [27] => 6.78 [28] => 6.77 [29] => 6.76 [30] => 6.75 [31] => 6.74 [32] => 6.73 [33] => 6.72 [34] => 6.71 [35] => 6.7 [36] => 6.69 [37] => 6.68 [38] => 6.67 [39] => 6.66 [40] => 6.65 [41] => 6.64 [42] => 6.63 [43] => 6.62 [44] => 6.61 [45] => 6.6 [46] => 6.59 [47] => 6.58 [48] => 6.57 [49] => 6.56 [50] => 6.55 [51] => 6.54 [52] => 6.53 [53] => 6.52 [54] => 6.51 [55] => 6.5 [56] => 6.49 [57] => 6.48 [58] => 6.47 [59] => 6.46 [60] => 6.45 [61] => 6.44 [62] => 6.43 [63] => 6.42 [64] => 6.41 [65] => 6.4 [66] => 6.39 [67] => 6.38 [68] => 6.37 [69] => 6.36 [70] => 6.35 [71] => 6.34 [72] => 6.33 [73] => 6.32 [74] => 6.31 [75] => 6.3 [76] => 6.29 [77] => 6.28 [78] => 6.27 [79] => 6.26 [80] => 6.25 [81] => 6.24 [82] => 6.23 [83] => 6.22 [84] => 6.21 [85] => 6.2 [86] => 6.19 )

(Добавление)
Вот точнее где ваша ошибка:
Цитата:
6.9-6.19

и разбили это как
Цитата:
6.9, 6.10, 6.11, 6.12, 6.13, 6.14, 6.15, 6.16, 6.17, 6.18, 6.19

а надо:
Цитата:
6.90, 6.89, 6.88 ................ 6.20, 6.19
 
 Top
armancho7777777 Супермодератор
Отправлено: 25 Сентября, 2014 - 08:45:29
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




Dragon_Knight пишет:
т.к. считает что число "6.5" больше числа "6.12"

А почему Вы считаете, что должно быть наоборот?)

Dragon_Knight пишет:
та-же убирает нули на конце

Приводите сами его в нужный формат.
 
 Top
Sail
Отправлено: 25 Сентября, 2014 - 10:16:03
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




RickMan пишет:
Вот точнее где ваша ошибка:
Цитата:
6.9-6.19
и разбили это как
Цитата:
6.9, 6.10, 6.11, 6.12, 6.13, 6.14, 6.15, 6.16, 6.17, 6.18, 6.19
а надо:
Цитата:
6.90, 6.89, 6.88 ................ 6.20, 6.19

А если надо так, как ТС написал? Например, числа - это составной ключ, где то, что до десятичной точки означает раздельчик, а то, что после - подраздельчик Улыбка
Dragon_Knight, в общем, если при разборе встречается интервал, то посредством функций substr() и strpos(), или explode() из первого числа интервала можно выделить число до точки и число после точки, из второго - число после точки. И уже эти два числа пропустить через range.

(Отредактировано автором: 25 Сентября, 2014 - 10:52:04)

 
 Top
RickMan
Отправлено: 25 Сентября, 2014 - 10:44:50
Post Id


Участник


Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012  


Помог: 30 раз(а)




Может автору надо чуток математику тогда выучить? И не мешало бы и хотябы чуток основы алгоритмики...
(Добавление)
Чуть поигравшись довел решение до такого вот варианта:
PHP:
скопировать код в буфер обмена
  1. $str = '4.17,5.21-5.26,6.0-6.7,6.9-6.19';
  2.  
  3. $result = array();
  4. foreach (explode(',', $str) as $v){
  5.         if (strpos($v, '-') !== false){
  6.                 $s_arr = explode('-', $v);
  7.                 if ( (($s_arr[0] * 10) - floor($s_arr[0] * 10)) !== (($s_arr[1] * 10) - floor($s_arr[1] * 10)) ){
  8.                         foreach (range($s_arr[0], $s_arr[1], 0.01) as $i){ $result[] = $i;}
  9.                 }else{
  10.                         foreach (range($s_arr[0], $s_arr[1], 0.1) as $i){ $result[] = $i;}
  11.                 }
  12.         }else{
  13.                 $result[] = $v;
  14.         }
  15. }
  16.  
  17. print_r($result);
 
 Top
Dragon_Knight
Отправлено: 25 Сентября, 2014 - 12:42:56
Post Id



Гость


Покинул форум
Сообщений всего: 103
Дата рег-ции: Май 2012  
Откуда: г.Мытищи, МО


Помог: 0 раз(а)




RickMan, а может Вам стоит подучить чтение русского текста? Я вроде понятно написал как мне нужно и я не просил Вашего совета в получении вашего видения этих чисел.

Но если Вы так хотите, эти числа это версии программного обеспечения, которые поддерживает данная архитектура. И версии выходят в порядке 6.0, 6.6, 6.12, 6.19, и это возрастающий порядок чисел. Т.е. версия 6.6 старее и старше чем версия 6.19 и в конкретном случае: (6.6 < 6.19) === TRUE

Полный список версий выглядит так и только так: "4.17, 5.21, 5.22, 5.23, 5.24, 5.25, 5.26, 6.0, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.9, 6.10, 6.11, 6.12, 6.13, 6.14, 6.15, 6.16, 6.17, 6.18, 6.19"!

Sail, я тоже думал, что сначала поделить по запятой, потом если есть тире то делить по нему и потом поделить по точке и считать десятичные числа как простые, но тогда получиться уж слишком кривой код, да и циклов будет слишком много...
 
 Top
Мелкий Супермодератор
Отправлено: 25 Сентября, 2014 - 13:03:49
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




PHP:
скопировать код в буфер обмена
  1. function populateVersionsList($sFrom, $sTill) {
  2.         $rgList = array();
  3.         $rgVersionFrom = explode('.', $sFrom);
  4.         $rgVersionTill = explode('.', $sTill);
  5.         assert('count($rgVersionFrom)==2');
  6.         assert('count($rgVersionFrom)==2');
  7.         assert('$rgVersionFrom[0] == $rgVersionTill[0]');
  8.         assert('$rgVersionFrom[1] <= $rgVersionTill[1]');
  9.  
  10.         $iMajor = $rgVersionFrom[0];
  11.         for ($iMinor = $rgVersionFrom[1]; $iMinor <= $rgVersionTill[1]; ++$iMinor) {
  12.                 $rgList[] = $iMajor.'.'.$iMinor;
  13.                 }
  14.         return $rgList;
  15.         }
  16. function versionListExpand( $sInput ) {
  17.         $rgOutput = array();
  18.         foreach (array_map('trim', explode(',', $sInput)) as $sVersionInterval) {
  19.                 $rgVersionInterval = explode('-', $sVersionInterval);
  20.                 switch (count($rgVersionInterval)) {
  21.                         case 1:
  22.                                 $rgOutput[] = $sVersionInterval;
  23.                                 continue;
  24.                         case 2:
  25.                                 foreach (populateVersionsList($rgVersionInterval[0], $rgVersionInterval[1]) as $version) {
  26.                                         $rgOutput[] = $version;
  27.                                         }
  28.                                 break;
  29.                         default:
  30.                                 assert('version interval may not be '.count($rgVersionInterval));
  31.                                 continue;
  32.                         }
  33.                 }
  34.         return $rgOutput;
  35.         }
  36.  
  37. $sInput = "4.17,5.21-5.26,6.0-6.7,6.9-6.19";
  38. $sExpected = "4.17, 5.21, 5.22, 5.23, 5.24, 5.25, 5.26, 6.0, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.9, 6.10, 6.11, 6.12, 6.13, 6.14, 6.15, 6.16, 6.17, 6.18, 6.19";
  39. assert('$sExpected == join(", ", versionListExpand($sInput))');

Довольно сильно привязан к формату.


-----
PostgreSQL DBA
 
 Top
RickMan
Отправлено: 25 Сентября, 2014 - 13:07:24
Post Id


Участник


Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012  


Помог: 30 раз(а)




Научитесь писать нормально ТЗ и быть более благодарным, когда люди тратят свое время и помогают вам. Замечу, что в названии темы и первом вашем сообщении ни слова не сказанно по поводу того, что это диапазон версий. *facepalm*
 
 Top
armancho7777777 Супермодератор
Отправлено: 25 Сентября, 2014 - 13:39:42
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




---

(Отредактировано автором: 25 Сентября, 2014 - 13:44:01)

 
 Top
Sail
Отправлено: 25 Сентября, 2014 - 13:55:14
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




Мелкий, что насчёт диапазона "5.21-7.26"? Хорошо
 
 Top
Ch_chov
Отправлено: 25 Сентября, 2014 - 14:02:08
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2121
Дата рег-ции: Июль 2008  
Откуда: из города


Помог: 90 раз(а)




PHP:
скопировать код в буфер обмена
  1. $data = '4.17,5.21-5.26,6.0-6.7,6.9-6.19';
  2.  
  3. $result = [];
  4. foreach (explode(',', $data) as $item) {
  5.   list($major,$minor_min, ,$minor_max) = sscanf($item, '%d.%d-%d.%d');
  6.   if ($minor_max)
  7.     for ($i = $minor_min; $i <= $minor_max; $i++)
  8.         $result[] = "$major.$i";
  9.   else
  10.     $result[] = $item;    
  11. }
  12.  
  13. print_r($result);
 
 Top
Dragon_Knight
Отправлено: 25 Сентября, 2014 - 14:28:49
Post Id



Гость


Покинул форум
Сообщений всего: 103
Дата рег-ции: Май 2012  
Откуда: г.Мытищи, МО


Помог: 0 раз(а)




Мелкий, Очень интересный вариант, но громоздкий. Сам такого писать не хотел, потому что думал можно как-то более интереснее сделать, но всё равно спасибо. Вечером, дома проверю и отпишусь.Улыбка
PS: Исходный вариант не обязательно такой, просто я не придумал более грамотный способ хранить большое кол-во версий, учитывая что вводить их будут вручную.

RickMan, Я благодарный и всегда вежливый, но когда мне предлагают учить математику, я отправляю пойти и учиться читать...
Я не даром в первом посте указал что "число "6.5" меньше числа "6.12"" и то, что PHP считает числа не так как нужно мне. Могли-бы и догадаться, что это не просто числа...

armancho7777777, ----- Радость

Sail, диапазона типа "5.21-7.26" не может быть, потому что обычно переход на новую мажорную версию происходит не доходя до 30 минорной версии, и придётся указывать как-то так: "5.21-5.26,6.0-6.7,6.9-6.19,7.0-7.26".

Ch_chov, Тоже очень интересный вариант. Дома проверю и отпишусь. Спасибо Улыбка

(Отредактировано автором: 25 Сентября, 2014 - 14:32:51)

 
 Top
Мелкий Супермодератор
Отправлено: 25 Сентября, 2014 - 14:31:35
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Sail пишет:
что насчёт диапазона "5.21-7.26"?

Намеренно проверяю assert'ом.
Такой диапазон невозможно реализовать в общем случае: неизвестно, существовала ли в природе версия 5.22. Да что 5.22, вся ветка 6.* могла быть пропущена, т.к., например, чётные версии в этом проекте могут быть только тестовые.

Ch_chov, хм, блин, а я был уверен, что list выдаст то ли варнинг то ли предупреждение за пропущенные элементы Ниндзя


-----
PostgreSQL DBA
 
 Top
Dragon_Knight
Отправлено: 27 Сентября, 2014 - 16:00:30
Post Id



Гость


Покинул форум
Сообщений всего: 103
Дата рег-ции: Май 2012  
Откуда: г.Мытищи, МО


Помог: 0 раз(а)




Мелкий, Ch_chov, Ваши варианты замечательно работают. Спасибо за помощь Здорово
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB