Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ

Warning: Trying to access array offset on false in /home/u98739/softtime.ru/www/utils/currentforum.php on line 18

Warning: Trying to access array offset on false in /home/u98739/softtime.ru/www/utils/currentforum.php on line 19

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум (новые сообщения вниз) Структурный форум

тема: Ответ 002 на задачу N 12

Сообщения:  [1-7] 

 
 автор: Trianon   (20.03.2006 в 14:15)   письмо автору
 
   для: cheops   (20.03.2006 в 13:51)
 

Могу лишь объяснить как её понял я.
То, что требуется навигация по файлу , а не по массиву объектов, было подчеркнуто даже в названии задачи. Файловая постраничная навигация. А файл спокон веку был объектом, который имеет право не помещаться в оперативную память. Тем более, когда ссылка на файловую сущность идет в постановке задачи. Раз требуется листать по страницам, значит объект запросто может оказаться большим. А скрипт не имеет права на нем тормозить, и уж всяко - ломаться.

   
 
 автор: cheops   (20.03.2006 в 13:51)   письмо автору
 
   для: Trianon   (20.03.2006 в 13:48)
 

Хм... вообще предполагалось что-то вот такое http://www.softtime.ru/forum/read.php?id_forum=7&id_theme=14744 - т.е. обычная не затейлевая постраничная навигация при выводе из файла... может конечно, задач слишком формально задана...

   
 
 автор: Trianon   (20.03.2006 в 13:48)   письмо автору
 
   для: cheops   (20.03.2006 в 13:16)
 

Самая первая строка - это и есть меню :)
Для файла в 100 строк - а это одна станица (точнее - ровно половина страницы :)) В первой строке будет написано
1
Что, согласитесь, верно. Оглавление содержит название только одной страницы. И поскольку эта страница как раз показана, ссылкой это название не обрамлено.

Да, я был неправ, что в отосланных решениях оставил настройки умолчаний параметров на размер страницы в 200 строк (это произошло потому, что тестировался я на файле из нескольких тысяч строк). Надо было написать num => 4, set =>5, и в таком виде постить ответ.

   
 
 автор: cheops   (20.03.2006 в 13:16)   письмо автору
 
   для: Trianon   (20.03.2006 в 00:30)
 

Хм... а где меню 1 2 3 4 5 6 на страницы?

   
 
 автор: Trianon   (20.03.2006 в 00:30)   письмо автору
 
   для: cheops   (19.03.2006 в 23:36)
 

Страницы по условиям задачи состоят из n( у меня num=10) блоков по s (у меня set=20) строк. То есть в каждой странице 10*20 =200 строк. Умолчания можно поменять в скрипте. Или можно вручную вызвать скрипт, указав другие значения num и set: ?num=5&set=4 например. Наконец, можно погонять скрипт на немного бОльших файлах. 1000 строк например.
Или на реально БОЛЬШИХ файлах. Пару десятков миллионов строк например. А потом сравнить результат с другими решениями. Это к вопросу о реально работающих скриптах. :)

   
 
 автор: cheops   (19.03.2006 в 23:36)   письмо автору
 
   для: SoftTime   (17.03.2006 в 23:11)
 

Хитро... хм... не очень понятно что скрипт делает - у меня выводится всё содержимое файла на одной странице, прчём то что должно быть отдельной странице отделяется друг от друга <hr>. При этом сама постраничная навигация не реализуется...

   
 
 автор: SoftTime   (17.03.2006 в 23:11)   письмо автору
 
 

Ответ 002 на задачу N 12.
С условиями задачи можно ознакомится по ссылке.
У меня два решения.
Одно для относительно небольших файлов (до 300 кБ)

<?php
   $def=array('page' =>1, 'num' => 10, 'set' => 20);

   $f = fopen("data.txt", 'r');
   if(isset($_GET['total']))
      $total = intval($_GET['total']);
   else
   {
       for($i = 0; !feof($f); $i++) $s = fgets($f);
       rewind($f);
       $total = $i - (trim($s) == "");
   }
   foreach($def as $k => $v)
     $$k = isset($_GET[$k])&& $_GET[$k] > 0 ? $_GET[$k]: $v;

   $page_i = 1;
   for($lines = 0; $lines < $total; $page_i++)
   {
       $lines += $num * $set;
       if($page_i == $page)
          echo "$page_i\r\n";
       else
          echo "<a href=?total=$total&num=$num&set=$set&page=$page_i>"
               .$page_i. "</a>\r\n";
   }
   if($page >= $page_i)
         $page = $page_i-1;
   $lines_start = ($page-1) * $num * $set;

   for($i = 0; !feof($f) && $i < $lines_start; $i++) fgets($f);

   for($j = 0 ; !feof($f) && $j < $num; $j++)
   {
       echo '<hr>';
       for($i = 0 ; !feof($f) && $i < $set; $i++)
           echo fgets($f)."<br>\r\n";
   }
?>


Другое решение - для очень больших файлов. Более 1Мб.

<?php
   $def=array('page' =>1, 'num' => 10, 'set' => 20);
   $txtname = isset($_GET['file']) ? $_GET['file'] : "data.txt";
   $tfd = fopen($txtname, 'r') or die("cannot open $file");
   $tsize = filesize($txtname);
   $ttime = filemtime($txtname);
   $idxname = $txtname .".idx";
   for($try=0; $try < 2 &&     // Попытаемся 1 раз перестроить индекс, если
        (  ($ifd= @fopen($idxname, "r"))==0   // нет индекса
       || ($isize = @fgets($ifd)) != $tsize  // файл дописали
       || ($mult =  @ftell($ifd)) <= 3         // мал размер элемента индекса
       || ($itime = @fgets($ifd)) != $ttime  // файл изменили
       || ($ibase = @fgets($ifd)) == 0       // база индекса не определена
       ||  $ibase != @ftell($ifd)              // база индекса не достигнута
        ); $try++ )                          //
   {                                        //строим нафиг свежий индекс
      if($ifd) fclose($ifd);
      $ifd = fopen($idxname, "w") or die("cannot create index $idxname");
      $sizewidth = strlen("$tsize");
      if($sizewidth < 2) $sizewidth = 2;
      fprintf($ifd, "%${sizewidth}d\n", $tsize);
      $mult = ftell($ifd);

      $timewidth = strlen("$ttime");
      while($timewidth < $sizewidth || ($timewidth-$sizewidth)%$mult) ++ $timewidth;
      fprintf($ifd, "%${timewidth}d\n", $ttime);
      $ibase = ftell($ifd)+ $mult;
      fprintf($ifd, "%${sizewidth}d\n",  $ibase);
      if(ftell($ifd) != $ibase)
          $try = 2;

      for(;!feof($tfd); fgets($tfd))
         if(($pos = ftell($tfd)) < $tsize)
             fprintf($ifd, "%${sizewidth}d\n", $pos);
      fclose($ifd);
   }
   if($try <= 1)
   {
       fseek($ifd, 0, SEEK_END);
       $iend = ftell($ifd);
       $total = intval(($iend - $ibase)/$mult);
   }
   if($try > 1 || $total * $mult +$ibase != $iend)
          die ("Ну не умею я строить индекс. И вообще я обиделась.");
   foreach($def as $k => $v)
     $$k = isset($_GET[$k])&& $_GET[$k] > 0 ? $_GET[$k]: $v;

   $page_i = 1;

   for($lines = 0; $lines < $total; $page_i++)
   {
       $lines += $num * $set;
       if($page_i == $page)
          echo "$page_i\r\n";
       else
          echo "<a href=?file=".urlencode($txtname)."&num=$num&set=$set&page=$page_i>"
               .$page_i. "</a>\r\n";
   }
   if($page >= $page_i)
         $page = $page_i-1;
   $lines_start = ($page-1) * $num * $set;

   fseek($ifd, $ibase+$mult *$lines_start, SEEK_SET);
   fseek($tfd, trim(fgets($ifd)), SEEK_SET);

   for($j = 0 ; !feof($tfd) && $j < $num; $j++)
   {
       echo '<hr>';
       for($i = 0 ; !feof($tfd) && $i < $set; $i++)
           echo fgets($tfd)."<br>\r\n";
   }

?>

Trianon

http://www.softtime.ru/info/task.php?id_article=82

   

Сообщения:  [1-7] 

Форум разработан IT-студией SoftTime