Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Сохранения кода меню в древовидном формате в php  (Прочитано 17368 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Murolike
Интересующийся

ru
Offline Offline

« : 29-06-2012 22:31 » 

Здравствуйте помоги с такой проблемой:
Необходима организовать, сохранение в древовидном формате меню в массиве php.
Примерный вид кода:
Символ \t - является Табуляции, а \r\n - перевод строки.
Код: (PHP)
$MenuCode="привет\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nПока\r\n\Система\r\n\tWindows\r\n\t\tXP\r\n\t\t7\r\n";
Чего добился, но все еще с ошибкой.
Код: (PHP)
<?php
  $MenuName=$_POST['mName'];  //    Название меню
  $MenuCode=$_POST['mCode']; //     Код меню
  $MenuName="Temp";          //     Для тестирование : Название
  $MenuCode="привет\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nпока\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nсистема\r\n\t2\r\n\t3\r\nрабочий";   //  Код меню передающийся на сервер.
  // Класс меню
class Menu{
    var $Name; //   Название
    var $Code;  // Код
    var $LengthCode;    //  Длина кода
    var $TreeMenu;     //  Массив для сохранения пунктов ввиде древа
    var $SplitCode;   //   Разрека элементов на строчки
    var $Error;       //   Переменная для сохранения ошибок
    var $CopySplitCode;
    /*  Инициализация массива   */
    function Menu($MenuName,$MenuCode)
    {
        $this->Name=$MenuName;
        $this->Code=$MenuCode;
        $this->LengthCode=strlen($MenuName);
        $this->TreeMenu=array();
        $this->SplitCode=preg_split("/\n/",$this->Code);
        //  $i=$k=0;
        $this->TreeMenu=$this->TreeCreate($this->TreeMenu,0);
        echo "aa";      
    }
    /*    Функция для построения дерева */
    function TreeCreate($TreeArray)
    {
        $i=$k=0;
        foreach ($this->SplitCode as $key => $value)
        {
           if($this->CheckElementOnTab($value)==true)// Здесь уже не правильно и это я знаю.
           {
                $TreeArray[$i][$k+1]=array();
                $this->SplitCode[$key]="имя".$key." ";
                $this->TreeCreate(&$TreeArray[$i][$k+1]);
                $i++;                      
           }
           else
           {
              $TreeArray[$i][$k]=$value;
              unset($this->SplitCode[$key]);
           }
        }
        return $TreeArray;
    }
    function CheckElementOnTab($value)
    {
        for($i=0;$i<strlen($value);$i++)
        {
            if($value[$i]=="\t")
            {
                return true;
            }
        }
        return false;
    }
}
    $Object=new Menu($MenuName,$MenuCode);    
?>

Я понимаю, что для реализации необходима рекурсия, чтобы собрать все в одно, но у меня проблемы остаются с выходом из этой рекурсии, система должна записывать в [$i][0] = Элементы Родителя, а в [$i][1]=array(); Хранятся все дети этого элемента.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 30-06-2012 15:14 » 

объясни какое соответствие между

$this->TreeMenu=$this->TreeCreate($this->TreeMenu,0);
и
function TreeCreate($TreeArray)



Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Murolike
Интересующийся

ru
Offline Offline

« Ответ #2 : 30-06-2012 17:55 » new

аа, да 0 можно убрать, с ним и без него тоже работает.
0 использовал для изменения ключа $key в цикле.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 01-07-2012 09:09 » 

Я так и не понял, а что надо-то?
$MenuCode="привет\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nпока\r\n\tимя1\r\n\tимя2\r\n\tимя3\r\nсистема\r\n\t2\r\n\t3\r\nрабочий";
Вроде уже имеет древовидный вид


$this->SplitCode=preg_split("/\n/",$this->Code); - а почему именно так, ведь "разделителем" является  \r\n. Впрочем. это сути не меняет. Это вопрос второстепенный.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Murolike
Интересующийся

ru
Offline Offline

« Ответ #4 : 02-07-2012 14:42 » 

Есть код который вы процитировали, который отправил пользователь, теперь его необходимо превратить в массив вложенностей
Допустим Массив $TreeArray[$i][$j] -  под элементами [$i] понимают ВЕТКИ, или родители кому как проще, в индексе [$j], где $j=0 это есть Имя Родителя или ветки, а [$j] $j=1 есть массив ДЕТЕЙ, других веток.
Примером является древовидное меню:
Программу откройте блокнот, там есть "файл", " о программе" и другие вещи - это родители, то что внутри них это дети, но если есть еще вложенности, это дети становятся родителями, то есть иными словами уход на 1 уровень ниже и так на несколько уровней ниже пока не закончится все.
Насчет разделителя, не важно, но оставил с \r вдруг в проверки понадобится.
Записан
Murolike
Интересующийся

ru
Offline Offline

« Ответ #5 : 02-07-2012 14:52 » 

Вот изображение, это то как он должен быть в php после обработки кода, результат работы функции.

* temp.jpg (44.54 Кб - загружено 1220 раз.)
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 02-07-2012 17:14 » 

Ну... теперь более менее ясно стало (не прошло и 4-х дней)

Основная функция TreeCreate
Опиши ее работу, как ты понимаешь как она должна работать
Описать словами не кодом.
например
Взять текущий элемент, проверить ... , если ... то сделать ...    , иначе сделать ...
Потом берешь свой код и смотришь, а соответствует ли он описанному?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Murolike
Интересующийся

ru
Offline Offline

« Ответ #7 : 06-07-2012 04:18 » 

ммм да, там не то. ладно вот новый код, по сути он все делает правильно, но если у нас идет переход меню от 2 уровень к 1 он пропускает элемент цикл foreach , а если добавлять параметры с указателем на наш массив элементов, то он слишком часто их дописывает.
Код: (PHP)
<?php
  $MenuName="TEMP";
  $MenuCode="привет\r\n\tС1\r\n\tС2\r\n\tС3\r\n\t\tС3-1\r\n\t\tС3-2\r\n\t\tС3-3\r\n\tЫЫЫ\r\nСистема\r\nЭксперт";
  $StringCode=preg_split("/\n/",$MenuCode);
  $Level=0;
  $TreeArray=array();
  $TreeArray=SaveCode($TreeArray,$StringCode);
  echo "gfg";
  function SaveCode($TreeArray)
  {
          $i=$j=0;
          global $Level;
          global $StringCode;
          foreach($StringCode as $key => $value)
          {
              if(TabElement($value)==true)
              {
                $CurrentElement=0;
                $CurrentElement=CountElementTab($value);
                if($Level==$CurrentElement) // Если текущий уровень совпадает с кол-вом \t
                {
                    $j++;
                    $TreeArray[$i][$j]=$value;
                    unset($StringCode[$key]);  
                }
                else
                {
                    if($Level>$CurrentElement) // Если уровень больше чем элементов \t
                    {
                        $Level--;
                        return $TreeArray;                        
                    }
                    else
                    {  
                        $Temp=$TreeArray[$i][$j];
                        $TreeArray[$i][$j]=array();
                        $TreeArray[$i][$j][0]=$Temp;
                        $Level++;
                        $TreeArray[$i][$j][1]=SaveCode($TreeArray[$i][$j][1]);
                    }
                }  
              }
              else
              {
                  $CurrentElement=0;
                  $CurrentElement=CountElementTab($value);
                 
                  if($Level!=$CurrentElement) // пока уровни не совпадут.
                  {
                    $Level--;
                    return $TreeArray;
                  }
                  else
                  {
                      $TreeArray[$i][$j]=$value;
                      unset($StringCode[$key]);
                      $TreeArray[$i][$j+1]=array();
                      $Level++;
                      $TreeArray[$i][$j+1]=SaveCode($TreeArray[$i][$j+1]);
                      $i++;
                  }
              }
          }
          return $TreeArray;
      }
      function TabElement($value) // Проверка на элемент \t
      {
          for($i=0;$i<strlen($value);$i++)
          {
              if($value[$i]=="\t")
              {
                  return true;
              }
          }
          return false;
      }
      function CountElementTab($value) // Количество элементов \t
      {
         $k=0;
         for($i=0;$i<strlen($value);$i++)
         {
             if($value[$i]=="\t")
             {
                 $k++;
             }
             
         }
         return $k;
      }
?>
Вот как избавиться,от такой фигни.
Скриншот с результатом этой программы.

* Poster1.jpg (50.13 Кб - загружено 1175 раз.)
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 06-07-2012 06:13 » 

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

Потом берешь свой код и смотришь, а соответствует ли он описанному?

ммм да, там не то. ладно вот новый код ...

Murolike, ты в советах не нуждаешься?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Murolike
Интересующийся

ru
Offline Offline

« Ответ #9 : 06-07-2012 09:02 » 

вообще-то я так и сделал и вот, что получилось после переноса слов на код.
или надо словами?
Словами,тогда будет так.:
"Берем элемента из списка, проверяем его на присутствие символа \t, если есть, тогда, сверяем совпадает-ли  глобальный уровень и количество элементов \t, если совпадает, то записываем их в прямом порядке, если не совпадает, является ли глобальный уровень больше чем количество элементов \t, если условие выполняется тогда, уменьшаем уровень и возвращаемся на 1 шаг выше, если же не выполняется условие, тогда получается, что текущий глобальный уровень меньше, чем количество элементов \t, а значит создаем для предыдущего элемента массив, где 0 это имя родителя, а 1 его дети и тут же вызываем функцию, чтобы определить если у него дети. Если же у элемента нету \t, тогда записываем его в прямом порядке и вызываем функцию еще раз, для проверки на детей.  " Примерно так получается.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 06-07-2012 09:15 » 

Здесь даже рекурсия не нужна

$StringCode - содержит массив строк в виде

[0] привет
[1]\tС1
[2]\tС2

...
уровень вложенности зависит от количества символов табуляции
Задача - запомнить верхний уровень

1. Посчитали количество табов
2. Сделали вывод к какому уровню относимся, и на каком уровне были
3. Соответственно заполнили "дерево"

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Murolike
Интересующийся

ru
Offline Offline

« Ответ #11 : 06-07-2012 11:50 » 

ладно, вроде бы понял, попробую набить на коде, сделал кстати с рекурсии, но попробую и этот вариант.
Просто получается, что можно сделать двумерный массив где будет 3 столбца: 1 - элемент 2- количество табов 3- родитель?
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 06-07-2012 12:39 » 

Нет...

Прочитал строку - уровень родителя
Положил в массив с индексом родителя
Прочитал сдедующую строку - посчитал количество табов (количество табов должно быть столько же или на 1 больше)
Если табов столько же - увеличил индекс родителя
Если табов больше  - в массив c родительским индексом добавляем массив наследника
Если табов меньше - обнуляем индекс массива наследника и уменьшаем индекс на количество табов
Текст для проверки алгоритма.
1
\t
\t
\t\t
\t\t\t
2

Вот что я от тебя хочу.
Никакого кода.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines