Help
9 отговора
332 прегледа
Help
nqkoi moje li da mi kaje kak da nakaram PHP da 4ete proizvolen red ot fail
naprimer imam fail s 10 reda i na seki red ima nekvi 4isla
i pitam dali moje pri vsqko otvarqne na stranicata da pokazva proizvolen red
i ako moje drasnete koda kak da stane
P.S kato kazvam proizvolen imam predvid da ne povtarq edin i su6t ili da sa posledovatelni
se edno da ima6 4islata 1 2 3 4 5 6 7 8 9 10 i da ti pokazva proizvolno ot tqh
pri parvo otvarane da pokazva naprimer 5 pri vtoro 1 pri 3to 8 i tn.
predvaritelno 10x ako mojete da pomognete
naprimer imam fail s 10 reda i na seki red ima nekvi 4isla
i pitam dali moje pri vsqko otvarqne na stranicata da pokazva proizvolen red
i ako moje drasnete koda kak da stane
P.S kato kazvam proizvolen imam predvid da ne povtarq edin i su6t ili da sa posledovatelni
se edno da ima6 4islata 1 2 3 4 5 6 7 8 9 10 i da ti pokazva proizvolno ot tqh
pri parvo otvarane da pokazva naprimer 5 pri vtoro 1 pri 3to 8 i tn.
predvaritelno 10x ako mojete da pomognete
Редактирано от _Unreal_ на
Opitay tova...
// pravim random index
function make_seed() {
list($usec, $sec) = explode(' ', microtime());
return (float) $sec + ((float) $usec * 100000);
}
srand(make_seed());
$rand_index = rand();
// chetem faila v array
$file_contents = file(numbers.txt);
// otpechatvame proizvolen red ot faila
echo $file_contents[$rand_index];
Uspeh ;)
my body lies but still i roam...
function make_seed() {
list($usec, $sec) = explode(' ', microtime());
return (float) $sec + ((float) $usec * 100000);
}
srand(make_seed());
$rand_index = rand();
// chetem faila v array
$file_contents = file(numbers.txt);
// otpechatvame proizvolen red ot faila
echo $file_contents[$rand_index];
Uspeh ;)
my body lies but still i roam...
две грешки
Допуснал си 2 грешки. Едната е, че си извикал file() с параметър, който не е в кавички. Втората - rand() извикано без параметри, ще ти върне стойност от 0 до RAND_MAX, което можеш да разбереш колко е от функцията getrandmax(). В моя случай: 32767
А очевидно трябва да се ограничи връщаната стойност отгоре до броя на редовете във файла. Т.е.:
$file_contents = file("numbers.txt");
srand(make_seed());
$rand_index = rand(0, count($file_contents)-1);
echo $file_contents[$rand_index];
"Животът е това, което се случва с нас, докато правителството си прави реформата."
А очевидно трябва да се ограничи връщаната стойност отгоре до броя на редовете във файла. Т.е.:
$file_contents = file("numbers.txt");
srand(make_seed());
$rand_index = rand(0, count($file_contents)-1);
echo $file_contents[$rand_index];
"Животът е това, което се случва с нас, докато правителството си прави реформата."
Re: две грешки
Дакота, ето още по-елегантно решение (не знам дали е по-бързо обаче)
$file_contents = file("numbers.txt");
srand(make_seed());
echo $file_contents[array_rand( $file_contents)];
There are only 10 types of people in this world: those who understand binary and those who don't
$file_contents = file("numbers.txt");
srand(make_seed());
echo $file_contents[array_rand( $file_contents)];
There are only 10 types of people in this world: those who understand binary and those who don't
Re: две грешки
Определено е по бързо
__________________________________
Пътят към ада е осеян с добри намерения
__________________________________
Пътят към ада е осеян с добри намерения
array_rand() 4.2.0 bug
От гледна точка на скоростта на изпълнение, поне моите тестове показаха едни и същи резултати.
При 4.2.0 около 0.0016 ms.
При 4.1.1 около 0.0020 ms.
Разбира се, това е силно относително големината на файла и натовареността на системата.
Иначе наистина е доста по-удобно да се използва array_rand().
Между другото, при тестовете се сблъсках с един бъг на array_rand() при 4.2.0 под windows. Функцията връща винаги една и съща стойност. Оказа се, че това е от версията и е фикснато.
Поне така пише тук [линк].
"Животът е това, което се случва с нас, докато правителството си прави реформата."
При 4.2.0 около 0.0016 ms.
При 4.1.1 около 0.0020 ms.
Разбира се, това е силно относително големината на файла и натовареността на системата.
Иначе наистина е доста по-удобно да се използва array_rand().
Между другото, при тестовете се сблъсках с един бъг на array_rand() при 4.2.0 под windows. Функцията връща винаги една и съща стойност. Оказа се, че това е от версията и е фикснато.
Поне така пише тук [линк].
"Животът е това, което се случва с нас, докато правителството си прави реформата."
Re: array_rand() 4.2.0 bug
Най-сигурния начин е да прочетеш файла ред по ред, без обаче да запазваш редовете, а само тяхната дължина и отместване от началото на файла... и кат прочетеш файла да избереш един ред, да се върнеш и да си го прочетеш /бързо ще стане/... найэвероятно ще работи по-бързо: пестиш на PHP сумати заделяния на памет, а връщането и прочитенето на един ред от известна позиция, с известна дължина ще стане бързо... и печелиш... какво печелиш? скрипта работи с файлове на 8Mb или колкото си сетнал за макс. размер RAM за един скрипт
P.S. numbers.txt е валидна конструкция, само дето evaluate-ва до ексвивалента на 'numberstxt'... щото точката се хаби за конкатенация...
P.S. 2 тестове с резултати от под 1ms /или все пак си имал предвид 0.0016s - по-реалното/ или даже няколко ms са... неточни... повтори N пъти че да качиш над секунда /най-добре 5-6/, тогава ще е по-добре
ViruS
P.S. numbers.txt е валидна конструкция, само дето evaluate-ва до ексвивалента на 'numberstxt'... щото точката се хаби за конкатенация...
P.S. 2 тестове с резултати от под 1ms /или все пак си имал предвид 0.0016s - по-реалното/ или даже няколко ms са... неточни... повтори N пъти че да качиш над секунда /най-добре 5-6/, тогава ще е по-добре
ViruS
интересни резултати
Разбира се, става дума за 0016 секунди...не милисекунди.
Идеята ти е интересна, но може би е препоръчителна за мнооого големи файлове. Ако съм разбрал правилно имаш предвид нещо подобно:
srand($time_start*100000);
$fp = fopen("numbers.txt", "r");
while (!feof($fp)) {
$lines[] = ftell($fp);
fgets($fp);
}
$end = ftell($fp);
$rand_index = rand(0, count($lines)-1);
fseek($fp, $lines[$rand_index]-$end, SEEK_END);
$line = fgets($fp);
fclose($fp);
echo rtrim($line);
Моите тестове (с файлове до 30kb) показаха обаче почти двойно по-бавно изпълнение в този случай...не знам как е при много големите файлове.
А за конкретния случай с редове
1
2
3
...
използваната памет се увеличава, защото отместването е по-голямо от самия ред. Може би от там идва и това забавяне...трябва да се отчете и операционната система, на която тествам, разбира се - win98.
Иначе (numbers.txt) е валидно, но не знам как ще escape-неш точката, без кавички...може би с регулярни изрази?
"Животът е това, което се случва с нас, докато правителството си прави реформата." - Джон Ленън
Идеята ти е интересна, но може би е препоръчителна за мнооого големи файлове. Ако съм разбрал правилно имаш предвид нещо подобно:
srand($time_start*100000);
$fp = fopen("numbers.txt", "r");
while (!feof($fp)) {
$lines[] = ftell($fp);
fgets($fp);
}
$end = ftell($fp);
$rand_index = rand(0, count($lines)-1);
fseek($fp, $lines[$rand_index]-$end, SEEK_END);
$line = fgets($fp);
fclose($fp);
echo rtrim($line);
Моите тестове (с файлове до 30kb) показаха обаче почти двойно по-бавно изпълнение в този случай...не знам как е при много големите файлове.
А за конкретния случай с редове
1
2
3
...
използваната памет се увеличава, защото отместването е по-голямо от самия ред. Може би от там идва и това забавяне...трябва да се отчете и операционната система, на която тествам, разбира се - win98.
Иначе (numbers.txt) е валидно, но не знам как ще escape-неш точката, без кавички...може би с регулярни изрази?
"Животът е това, което се случва с нас, докато правителството си прави реформата." - Джон Ленън
Редактирано от Dakota на
Re: интересни резултати
Пробвай да не ползваш ftell, а да си имаш променлива, към която да добавяш дължината на реда... тъй и тъй го четеш... и пробвай с файлове с малко поэдълги редове и поэголяма като цяло... + да изпълниш всичкото това поне 1000 пъти /в рамките на един скрипт/... щото именно във Windows да сравняваш милисекунди... не звучи добре...
ViruS
ViruS