Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Skrypt sortujący plik
Forum PHP.pl > Forum > Gotowe rozwiązania > Szukam
Beniooo
Witam, poszukuje skryptu kjtóry mi posortuje słowa znajdujące się w pliku tekstowym, każde słowo jest w innym wierszy, słów jest mniej niż 3 miliony, a pliczek ma rozmiar ~36MB
Dostałem od usera na forum takie coś:
  1. <?php
  2. $file = file_get_contents("slowa-win.txt");
  3. $file_lines = explode("\n", $file);
  4.  
  5.  
  6. for($i=0;$i<count($file_lines);$i++)
  7. {
  8.  
  9. $line_length[$i] = mb_strlen($file_lines[$i]);
  10. }
  11.  
  12. asort($line_length);
  13.  
  14. foreach ($line_length as $kl => $linel)
  15. {
  16. echo "$file_lines[$kl]<br>";
  17. }
  18. ?>


Niestety nie działa, wyświetla błąd "Fatal error: Allowed memory size of 25165824 bytes exhausted (tried to allocate 36854802 bytes) in C:\AppServ\www\index.php on line 6"
Ma ktos skrypt który posortuje ten plik żeby słowa były od najkrótszego do najdłuższego?
toaspzoo
Wartość dozwolonej pamięci zdefiniowanej w php.ini została przekroczona. Zwróć się do usługodawcy o zwiększenie parametru, obecnie jest to jedynie 24MB a potrzeba ponad 34

Lub spróbuj wrzucić zaraz po <?
  1. ini_set('memory_limit',52428800);


Jeśli nie zadziała, napisz do providera o zmianę parametru memory_limit na 50M
Beniooo
tak, a teraz "Fatal error: Allowed memory size of 52428800 bytes exhausted (tried to allocate 35 bytes) in C:\AppServ\www\index.php on line 9"
toaspzoo
Daj konfigurację php.ini
Beniooo
mam na appservie(localhost) i mam plik php.ini-dist
zawartość pliku : http://pastebin.com/XEFuJQGG
zegarek84
nie wczytuj na raz całego pliku ;]
  1. <?php
  2. $aLineLength = new ArrayObject();
  3. $file = new SplFileObject('./slowa-win.txt');
  4. foreach ($file as $line) {
  5. $aLineLength[] = mb_strlen($line);
  6. }
  7. $aLineLength->asort();
  8. $iterator = $aLineLength->getIterator();
  9. while ($iterator->valid()) {
  10. $file->seek($iterator->key());
  11. echo $file->current(), '<br />';
  12. $iterator->next();
  13. }

lub skorzystaj z tymczasowej bazy danych np. SQLite
Beniooo
Wrzuciłem na xaa i teraz coś takiego Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 71 bytes)
redeemer
Dlaczego to musi być skrypt? PHP nie nadaje się do takich rzeczy jak sortowanie plików o takich wielkościach (chyba że zrzucimy to na bazę danych, ale tutaj PHP miałoby tylko rolę "odczytaj linię i wrzuć do bazy"). Zasadnicze pytanie jest takie: czy chcesz ten plik posortować, czy chcesz mieć skrypt w PHP, który Ci to posortuje?

Edit: Postanowiłem jednak się zabawić i napisać skrypt w PHP (bez udziału baz danych) oparty na plikach tymczasowych (w celu ograniczenia zużycia pamięci). Nie sortuje on jednak alfabetycznie, ale tylko po długości.
  1. <?php
  2.  
  3. $fnameIn = 'input.txt';
  4. $fnameOut = 'output.txt';
  5. $tmpFilePrefix = '/tmp/xx_length.';
  6. $chunks = 4; // how many files per one length
  7.  
  8. //@todo check if fnameIn exists
  9.  
  10. /* step 1, separate lines with same lengths into different files, they're also chunked */
  11. $f = fopen($fnameIn, 'r');
  12. $maxLength = -1;
  13. $chunkArr = array();
  14.  
  15. while(!feof($f)) {
  16. $line = fgets($f);
  17.  
  18. $lineLength = mb_strlen($line);
  19. if ($lineLength > $maxLength) {
  20. $maxLength = $lineLength;
  21. }
  22.  
  23. if (!isset($chunkArr[$lineLength])) {
  24. $chunkArr[$lineLength] = 0;
  25. //@todo clear $tmpFname file (with all chunks). When "step 2" won't remove tmp files somehow, we will have doubled content, couse of FILE_APPEND flag
  26. }
  27.  
  28. $tmpFname = $tmpFilePrefix.$lineLength.'_'.($chunkArr[$lineLength]++%$chunks);
  29. file_put_contents($tmpFname, $line, FILE_APPEND); }
  30.  
  31. fclose($f);
  32.  
  33. /* step 2, merge and delete all temporary files
  34. This may also be memory consumpting (ex. when all lines have same length and we have chunks set to 1), but in most cases should be better than sorting whole file at once
  35. */
  36.  
  37. $f = fopen($fnameOut, 'w');
  38.  
  39. for($i=0; $i<=$maxLength; $i++) {
  40.  
  41. // check all chunks
  42. for($k=0;$k<$chunks;$k++) {
  43. $tmpFname = $tmpFilePrefix.$i.'_'.$k;
  44.  
  45. if (file_exists($tmpFname)) {
  46. $content = file_get_contents($tmpFname);
  47. fputs($f, $content);
  48. unlink($tmpFname);
  49. }
  50. }
  51. }
  52.  
  53. fclose($f);

Co do samego jednorazowego posortowania to nie wiem jak pod Windowsem, ale polecenie, które zadziała pod Linuksem wkleiłem Ci w poprzednim wątku http://forum.php.pl/index.php?s=&showt...st&p=979723. Na windowsie możesz zainstalować sobie cygwin - konsola i narzędzia konsolowe z linuksa.
Beniooo
ogólnie to chce to tylko posortować, ale ksrypt też by się przydał, lecz priorytetem jest jednorazowe posortowanie
toaspzoo
Jeśli to nie tajemnica, to podeślij plik smile.gif
Beniooo
ten który chce posortować?
http://www.gimkarpacz.xaa.pl/slowa-win.zip



Odświeżam, nadal nie działa
toaspzoo
Jakie kodowanie ma ten plik tekstowy ?
Beniooo
ANSI
toaspzoo
proszę http://sowa-mat.pl/sorter
Beniooo
Dzięki Wielkie *.*
redeemer
Rozumiem Beniooo, że zmiana nazwy pliku w 3 linii mojego skryptu Cię przerosła?
Beniooo
redeemer, zmieniałem, nadal błąd wywalało ale z komunikatem (tried to allocate 16 bytes)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.