IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Веб-программирование (https://www.imho.ws/forumdisplay.php?f=29)
-   -   Помогите с алгоритмом... (https://www.imho.ws/showthread.php?t=55605)

Psionic Vision 04.04.2004 01:24

Помогите с алгоритмом...
 
Задача:

Человек может выбрать год - от 2003 до 2005 (в дальнейшем кол-во лет будет увеличено).
При выборе 2005 нужно сложить переменные 1 + $yr2004 + $yr2003
При выборе 2004 нужно сложить переменные 1 + $yr2003
При выборе 2003 нужно сложить переменные 1

Смысл понятен?
Нужно чтобы выбранный год складывался со всеми предыдущими (начиная с 2003). И чтобы это было полностью автоматически... как это сделать?

Psionic Vision 04.04.2004 01:38

У меня пока на уме что-то такое, но это сложно:

вводим test.php?yr=2005

PHP код:

$yr2003 4;
$yr2004 10;
$yr2005 10;
$yr2006 10;
$yr2007 10;
$yr2008 10;

$dif $yr-2003;

if (
$yr==2003) {
    
$total=$yr2003;
} else {
    for (
$i=0$i<=$dif$i++) {
    
$par "yr$yr";
    
$total $total+$$par;
    
$yr=$yr-1;
    }
}

echo 
$total

нельзя ли это как-то упростить?

joker99 04.04.2004 01:43

А на каком языке?

Psionic Vision 04.04.2004 01:46

joker99
PHP

mmaaxx 04.04.2004 01:52

Neo
PHP код:

$yr2003 4
$yr2004 10
$yr2005 10

//$yr=2005;

for($i=2003$i<=$yr$i++) $total+=${"yr$i"};

echo 
$total


Psionic Vision 04.04.2004 01:54

mmaaxx
Привет!
Спасибо :). А я и не знал, что можно так вкладывать переменные:

Цитата:

mmaaxx:
${"yr$i"};
в документации об этом не написано :(

Vaulter 04.04.2004 02:22

Variable variables
Sometimes it is convenient to be able to have variable variable names. That is, a variable name which can be set and used dynamically. A normal variable is set with a statement such as:

PHP код:

<?php
$a 
"hello";
?>

A variable variable takes the value of a variable and treats that as the name of a variable. In the above example, hello, can be used as the name of a variable by using two dollar signs. i.e.

PHP код:

<?php
$$a "world";
?>


At this point two variables have been defined and stored in the PHP symbol tree: $a with contents "hello" and $hello with contents "world". Therefore, this statement:

PHP код:

<?php
echo "$a ${$a}";
?>


produces the exact same output as:

PHP код:

<?php
echo "$a $hello";
?>


i.e. they both produce: hello world.

In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.

Please note that variable variables cannot be used with PHP's Superglobal arrays. This means you cannot do things like ${$_GET}. If you are looking for a way to handle availability of superglobals and the old HTTP_*_VARS, you might want to try referencing them.

sky7 04.04.2004 02:41

mmaaxx
Классно. Я тоже об этом не знал. Вот уж век живи - век учись. С меня 5 (;

Добавлено через 9 минут:
Кстати можно было бы и массивом сделать. Благо массивы динамические.

$yr_array = array ( 4 , 10, 10); $total = 0;
// $yr_array[3] = 10; // for year 2006

for ($i = $yr - 2003 ; $i >= 0; $i-- ) $total += $yr_array[$i];

Конечно малёк сложнее, но проще ( моно вообще динамически ) будет добавлять года.

Psionic Vision 04.04.2004 03:10

С меня тоже :dance:
А почему вот это не работает:

$sel[01]="selected";
$numstr = ${"sel[01]"};
var_dump ($numstr); // выдает NULL

sky7 04.04.2004 03:27

А, ну тут конечно не пойдёт. Переменной "sel[01]" то нет! есть переменная "sel" типа array и "01" элемент оной является строкой "selected".

Если
//$selected=1234;
$sel[01]="selected";
$numstr = ${$sel[01]}; // или = ${${"sel"}[01]};

По-идее будет работать, если я правильно понял намеренья. ( я не проверял ) (;

Добавлено через 4 минуты:
Тут имхо на эвалюацию строк в ЛИСПе логика похожа. Плохой стиль, но бывает полезно...

Psionic Vision 04.04.2004 03:42

не, не правильно. еще раз:

есть

PHP код:

будет считать что $sel[01до $sel[10] = "selected";

for (
$i=1$i<10$i++) {
print 
"<option $sel[".sprintf("%02d", $i)."]>";


это не работает.
зы. что такое ЛИСП?

sky7 04.04.2004 04:20

В предыдущем случае, прежде чем вызывать переменную её надо эвалюировать ( термином LISPа - это язык такой ... с круглыми скобками (; )

Для эвалюации и используется ${имя_переменной_как_строка}

( И почему нет? Я даже спецом проверил ... оба варианта работают )

Мало того

Цитата:

будет считать что $sel[01] до $sel[10] = "selected";

for ($i=1; $i<10; $i++) {
print "<option $sel[".sprintf("%02d", $i)."]>";
}
В этом случае
PHP код:

//for ($i=1; $i<10; $i++) $sel[$i] = "selected";

for ($i=1$i<10$i++) {echo "<option  ".$sel[$i]." >";} 

твой sprintf будет возвращать строчку для print'а а не для индексации массива ( видимо, да и по-логике, сначала в строках ищутся переменные, а только потом строки складываются для передачи в print () ).

Отсюда ошибка: Parse error: parse error, unexpected '\"', expecting T_STRING or T_VARIABLE or T_NUM_STRING , что по-русски - он ждал индексации массива, так как нашел "[", а индексации не произошло.

Объясни на словах, что ты хочешь добиться?

PS Да, и старайся таки следовать принципу KISS.. Это и так плохой стиль, а ещё усложнять.... хотя смотри сам.



Добавлено через 14 минут:
Или, уж если очень хочется с 01 -09 то
PHP код:

//for ($i=1; $i<10; $i++) $sel[sprintf("%02d", $i)] = "selected";
   
for ($i=1$i<10$i++) print "<option ".$sel[sprintf("%02d"$i)].">"

Проверил. Работает.

Psionic Vision 04.04.2004 04:32

Нет. не работает. выходит <option ><option ><option ><option >....

Добавлено через 6 минут:
Сложновато объяснить чего я хочу.. но - попробую.
Короче, есть выпадающее меню навигации (см. здесь: http://shabash.dreamsee.ru/xron.html)

Допустим, начало:

PHP код:

$yr2003 4
$yr2004 14
if (!
$yr$yr=2004;

// for($i=2003; $i<=$yr; $i++) $total+=${"yr$i"}; - пока не надо, чуть позже понадобится 

Сейчас у меня есть файл, допустим nav2004, содержащий вот это:

<option <?php echo "$sel[01]"; ?> value=1>01 [005]</option>
<option <?php echo "$sel[02]"; ?> value=2>02 [006]</option>
<option <?php echo "$sel[03]"; ?> value=3>03 [007]</option>
<option <?php echo "$sel[04]"; ?> value=4>04 [008]</option>
...
и так далее, строк столько, сколько выпусков в году.
далее, человек выбирает выпуск 1, год 2004. значит,

PHP код:

$sel[01]="selected";

for (
$i=1$i<10$i++) print "<option ".$sel[sprintf("%02d"$i)].">"

вот этой строкой мне надо сгенерировать строки типа
<option <?php echo "$sel[01]"; ?> value=1>01 [005]</option>
причем этих строк столько, сколько выпусков в текущем году.
достаточно понятно?

sky7 04.04.2004 04:48

Фи! Так то и есть последствия плохого стиля (; ( не в обиду сказано... сам страдаю периодически )

Смотри - ты индексируешь массив челыми числами, а обратиться хочешь, индексируя строками. Тут надо определиться. Или так:
PHP код:

/*
   $sel[01] = "selected";
   $sel[02] = "selected";
   $sel[03] = "selected";
   $sel[04] = "selected";
   $sel[05] = "selected";
*/
   
for ($i=1$i<=5$i++) print "<option ".$sel[$i].">"

Или так:
PHP код:

/*
   $sel["01"] = "selected";
   $sel["02"] = "selected";
   $sel["03"] = "selected";
   $sel["04"] = "selected";
   $sel["05"] = "selected";
*/
  
for ($i=1$i<=5$i++) print "<option ".$sel[sprintf("%02d"$i)].">"

PS Да, и не обижай меня.. я проверяю примеры, перед постом... снимая комментарии всё работает ;) :yees: :dance:

Psionic Vision 04.04.2004 05:05

sky7
Спасибо.
Еще одна вещь, которой я не знал - что массив можно индексировать числами или строками. думал - числа всегда есть числа :)

кроме того, чего вдруг sprintf возвращает строку? ведь то что он возвращает есть число. :confused:

а что ты называешь плохим стилем?

sky7 04.04.2004 05:22

Цитата:

Первоначальное сообщение от Neo
кроме того, чего вдруг sprintf возвращает строку? ведь то что он возвращает есть число. :confused:
Цитата:

php.net: http://be2.php.net/manual/en/function.sprintf.php
sprintf
(PHP 3, PHP 4 )
sprintf -- Return a formatted string
Description
string sprintf ( string format [, mixed args])
Цитата:

Первоначальное сообщение от Neo
а что ты называешь плохим стилем?
В данной ситуации то, что ведёт к нечитаемому коду и ошибкам работы с типами. Как то вышеупомянутое преобразование из строки в имя переменной, или индексация строками, содержащими числа.. список этим не ограничевается, где найти полную версию - не знаю (;

Всегда пожайлуста :yees:

Psionic Vision 04.04.2004 23:54

Всем спасибо. Вот что у меня получилось: (конечно сложно читать но что ж поделаешь я не мастер языка пхп - пока что :) )

PHP код:

<?php
$lastnum
=14// ЭТО ЧИСЛО Я МЕНЯЮ ВРУЧНУЮ С КАЖДЫМ ВЫПУСКОМ
$yr2003 4
$yr2004 $lastnum

$yr=2004;
$n=10;

for(
$z=2003$z<$yr$z++) $total+=${"yr$z"}; // ВЫЧИСЛЯЮ КОЛИЧЕСТВО ВЫПУСКОВ ВО ВСЕ ГОДА ПЕРЕД ДАННЫМ
$total += 1// И ПРИБАВЛЯЮ ЕДИНИЦУ - ЧИСЛО СЛЕД. ВЫПУСКА

$sel[sprintf("%02d"$n)]="selected"// ВЫБР. ЧИСЛО ВЫДЕЛЯЕТСЯ

print "<select>";
for (
$i=1$i<=${"yr$yr"}; $i++) {
print 
"<option ".$sel[sprintf("%02d"$i)]." value=$i>".sprintf("%02d"$i)." [".sprintf("%03d"$total)."]</option><br>\n"// ФОРМИРУЮ СТРОКУ, ТАКУЮ КАК ПИСАЛ ВЫШЕ
$total += 1// И ПРИБАВЛЯЮ ОДИН ДЛЯ ИСПОЛЬЗОВАНИЯ В СЛЕДУЮЩЕМ КРУГЕ (ЕСЛИ ТАКОЙ ПОСЛЕДУЕТ)
}
print 
"</select>";
?>

можно ли это как то оптимизировать

Psionic Vision 05.04.2004 03:08

В чем ошибка?

<?php
$year[2003]="selected";
$year[2004]="selected";

for ($i = 2003; $i <= 2005; $i++) {
var_dump (${"year[$i]"}); // NULL
}

?>

mmaaxx 05.04.2004 09:53

Neo
<?php
$year[2003]="selected";
$year[2004]="selected";

for ($i = 2003; $i <= 2005; $i++) {
var_dump (${"year"}[$i]); // NULL
}

?>

Psionic Vision 05.04.2004 16:48

mmaaxx
Ошибаисси. Не работает или ты не понял чего я хочу. работает так:

<?php
$year[2003]="selected";
$year[2004]="selected";

for ($i = 2003; $i <= 2005; $i++) {
var_dump ($year[$i]); // selected, selected, NULL
}

?>

mmaaxx 05.04.2004 17:35

Мда, я просто увидев ${"year[$i]"}, сразу подумал (и ответил) что нужно (или по крайней мере желательно) выносить "сложные" конструкции переменных (а-ля $c->var, $a['var'] ) из строки, пхп не во всех слуйчаях их коректно находит.
Тот что я запостил у меня работает на ура (и выдайёт то же что и твой пост.

А вообще конечно ты прав на все 100% что там вообще ненужна никакая ${}.

Добавлено через 3 минуты:
Да и вообще имхо удобнее, правильнее и бысрее (по выполнению) общаться к переменным имя которой в строке через $_GLOBALS[$myvar] а не ${$myvar}. Заодно и путаницы с массивами не будет (ну или по крайней мере не должно быть). :)

Psionic Vision 05.04.2004 18:58

Кто нибудь мне может внятно объяснить, когда нужно ${} , а когда просто $?

mmaaxx 05.04.2004 19:04

Neo
Когда не знаешь точного названия переменной:
Не нужно: ${"var1"} , проще и быстрее $var1
Нужно: ${"my_".$i."_var"} , сдесь мы не знаем названия переменной и поэтому юзаем ${} (но правильнее в таких слуйчаях (как было сказаны выше) использовать массив типа $my_var[$i]).

Просто вместо ${"my_".$i."_var"}, с таким-же успехом можно использовать $_GLOBALS["my_".$i."_var"] (массив через который можно доступиться ко всем переменным. Для наявность можешь сделать:
echo "<pre>";
print_r($_GLOBALS);
echo "</pre>";

Gike 05.04.2004 19:20

а не проще использовать формулу?

$yr_min=2003
$yr_max=2xxx

$sum=($yr_max^2+$yr_max-$yr_min^2-$yr_min)/2

или

$sum=($yr_max-$yr_min)*($yr_max+$yr_min+1)/2

арифметическая прогрессия...

Psionic Vision 05.04.2004 22:10

Gike
а смысл? формула непонятная :( :confused:

sky7 05.04.2004 22:29

Цитата:

Neo:
можно ли это как то оптимизировать
Ну, для начала везде вместо sprintf, для индексации массива я бы использовал числа вместо строк. ( все sprintf ( ...... $i) заменить на $i ) Так и работать быстрее будет, и код куда читабельнее.

Во-вторых, вместо переменных $year200x -я бы использовал массив. Так и писать и поддерживать код намного проще. В остальном.. да тут и не так много кода (;

Да.. а ошибку подобную сообщению от 05-04-2004 01:08 я комментировал в своём
ответе от 04-04-2004 00:27.

Psionic Vision 05.04.2004 22:41

Цитата:

sky7:
все sprintf ( ...... $i) заменить на $i
но ведь мне нужно чтобы там нолик впереди был.

Цитата:

sky7:
$year200x -я бы
тут ты наверно прав.. ща пойду переделывать :)

Добавлено через 4 минуты:
а как получить значение последнего элемента массива?

sky7 05.04.2004 22:42

Цитата:

Neo:
но ведь мне нужно чтобы там нолик впереди был.
А зачем? Лучше этот нолик добавлять при выводе на HTML( если так уж надо), а внутри держать как число. А принимая из HTML приводить обратно к числу. Но... это моё имхо (;

mmaaxx 05.04.2004 22:45

Neo
Цитата:

но ведь мне нужно чтобы там нолик впереди был
зачем ? :) если потом будешь выводить ключи массива и там будет нужен 0, то поставь sprintf там, так будет правильнее.

sky7 05.04.2004 22:49

mmaaxx
:beer:

PS Сорри за флуд...

Psionic Vision 05.04.2004 23:43

mmaaxx
зачем - смотри здесь: http://shabash.dreamsee.ru/xron.html - блок навигации по выпускам. для красоты, короче. :)

sky7
А чего, тут без меня пиво пьют? Нее я не согласен. Щас ваще уйду в монастырь :).
mmaaxx
:beer:

Добавлено через 3 минуты:
Ах да, я же забыл зачем пришел.

Как сложить ВСЕ значения ВСЕХ ключей массива?

Добавлено через 7 минут:
А знаю вот так
foreach ($years as $temp) $total_currnum += $temp;

mmaaxx 06.04.2004 10:59

Neo
sky7
:beer: :)

Neo
Ты наверно имел введу ссумировать все значения масива (массив: $array[$key]=>$value), поскольку ключи сумируют так:
if(!empty($a)) foreach($a as $key=>$value) $key_sum+=$key;
Не забываем про проверку на пустоту, поскольку foreach будет ругаться, если масив пустой.

is_absent 06.04.2004 13:35

mmaaxx
хм.. не надо на непустоту. надо на "массивность" проверять is_array вместо empty... $a = 1; тоже не пустая :)

mmaaxx 06.04.2004 14:55

@_is_absent
совершенно верно

Gike 07.04.2004 13:31

Neo
Почитай про сумму арифметической прогрессии ....

Psionic Vision 07.04.2004 17:41

Всем спасибо :)

Gike
а зачем здесь ар.прогрессия если можно сделать гораздо проще без таких сложных формул?

mmaaxx 07.04.2004 17:49

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

sky7 07.04.2004 18:00

Neo
Так с формулой эффективнее. Если куда можно формулу какую впихнуть - намного быстрей прога работает, чем то-же самое циклами вычислять. Представь, что у тебя накопилось 10 000 выпусков, что-б их пересчитать, ты используешь цикл ( по 14 ) с одним арифметическим действием. Итого: (10 000/*выпусков*/ / 14/*в год*/) /*циклов*/ * 1 /*действие*/ ~= 80 /*операциям */ А формулой - у тебя 4 операции, не зависимо от количества выпусков. Разница в этом примере - 20 раз, а чем больше выпусков - тем больше разница.
А после этого представь что у тебя бешенная посещаемоть( скажем 1000 человек в минуту запрашивают этот скрипт ) и прикинь насколько разной будет нагрузка на сервер.

Добавлено через 1 минуту:
Я не говорю, что та или иная формула подходит в этом конкретном примере - это сам думай... но если можно что-то посчитать формулой - то лучше так и сделать :yees:

Добавлено через 1 минуту:
mmaaxx
И снова одинаково отвечаем ;) Ну и впрямь у моряков мысли сходятся :beer:

is_absent 08.04.2004 09:29

а почему все решили что сумма аривметической прогрессии сложная формула?
если мне не изменяет память, то S(n) = (a1 + an)*n/2 или a1 + d*(n - 1)/2
a1 - первый член последовательности, an - последний. d - разность.

sky7 08.04.2004 14:18

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


Часовой пояс GMT +4, время: 02:19.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.