Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Построить дерево, Дан список Uri объектов (Absolute) 
V
    Опции темы
W1zArD
Дата 7.1.2010, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 29.1.2006

Репутация: нет
Всего: 3



Добрых суток.

Совсем запутался, точнее понял в чем проблема, но как решить ее, уже нет сил.
На часах 2:40, а времени все меньше и меньше. Буду рад помощи.

Итак имеется код:

Файл Record.cs
Код

public class Record
        {
            public string Url;
            public List<Record> Pages { get; set; }

            public Record(string url, List<Record> pages)
            {
                Url = url;
                Pages = pages;
            }

            public Record() : this("/", new List<Record>()) { }
        }


Файл Form1.cs
Код

private static Record Get(string fr, Record o)
        {
            foreach(var a in o.Pages)
            {
                if (a.Url == fr)
                {
                    return a;
                }
                var ab = Get(fr, a);
                if (ab != null)
                {
                    return ab;
                }
            }
            return null;
        }

        private static Record MakeTree(IEnumerable<Uri> list)
        {
            var result = new Record();
            foreach (var page in list)
            {
                var level = 0;
                foreach (var segment in page.Segments)
                {
                    if (segment == "/")
                    {
                        continue;
                    }
                    string print = level == 0 ? segment : page.Segments[level];
                    Record x = Get(print, result);
                    if (x != null)
                    {
                        if (x.Url == segment)
                        {
                            level++;
                            continue;
                        }
                        var wo = new Record(segment, new List<Record>());
                        if (!x.Pages.Exists(a => a.Url == wo.Url))
                        {
                            x.Pages.Add(wo);
                        }
                    }
                    else
                    {
                        result.Pages.Add(new Record(segment, new List<Record>()));
                    }
                    level++;
                }
            }
            return result;
        }


Вроде бы все хорошо, но если скормить ссылки к примеру:
http://site.com/abc/cba/test.php
и 
http://site.com/abc2/cba/test2.php

то у меня получится примерно так:
/
-abc
--cba
---test.php
---test2.php
--abc2
---cba

вобщем получается что найдя первое совпадение, метод Get возвращает первый попавшийся объект для которого Url совпало по условию.

Как сделать правильно?
Цель задачи, построить Карту Сайта по заданной коллекции ссылок.

Благодарю за внимание.
PM   Вверх
W1zArD
Дата 10.1.2010, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 29.1.2006

Репутация: нет
Всего: 3



неужели никто?  smile 
PM   Вверх
tol05
Дата 10.1.2010, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



ошибка в методе Get - хотя "cba" и будет присутствовать в обеих подветвях - он всегда возвращает только первое совпадение по значению сегмента, независимо от того, какая Page сейчас обрабатывается. Текстовые Pages и сегменты меняются, а иерархии Records - не переключаются. Значит нужно указывать Page, где методу Get нужно искать

вот подправленный код.
Цитата

private static Record MakeTree(IEnumerable<Uri> list)
  {
    var result = new Record();
    int pageIndex = 0;
    foreach (var page in list)
    {
    var level = 0;
    foreach (var segment in page.Segments)
    {
     if (segment == "/")
     {
      continue;
     }
     string print = level == 0 ? segment : page.Segments[level];
     Record x = Get(print, result, pageIndex);
     if (x != null)
     {
      if (x.Url == segment)
      {
       level++;
       continue;
      }
      var wo = new Record(segment, new List<Record>());
      if (!x.Pages.Exists(a => a.Url == wo.Url))
      {
       x.Pages.Add(wo);
      }
     }
     else
     {
      result.Pages.Add(new Record(segment, new List<Record>()));
     }
     level++;
    }
    pageIndex++;
    }
    return result;
  }
    }

private static Record Get(string fr, Record o, int pageIndex)
  {
    if (o.Pages.Count == 0 || o.Pages.Count <= pageIndex)
    {
    return null;
    }
    Record a = o.Pages[pageIndex];

    if (a.Url == fr)
    {
    return a;
    }
    var ab = Get(fr, a, 0);
    if (ab != null)
    {
    return ab;
    }
    
    return null;
  }


хотя конечно я бы подумал над перепроектированием этих методов - они читаются очень тяжело. Я бы подумал над переносом метода Get в класс Record и удерживании ссылки на текущую иерархию Records, которая в данный момент обрабатывается

Это сообщение отредактировал(а) tol05 - 10.1.2010, 19:27


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
W1zArD
Дата 11.1.2010, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 29.1.2006

Репутация: нет
Всего: 3



tol05, благодарю за ответ. В действительности все работает, почти.
Дело в том что создаются элементы с одинаковым Url.
Думаю понятнее будет на скрине

Ссылки для примера:
http://site.com/Content/Css/General.css
http://site.com/Content/Css/General.css
http://site.com/rss/Content/Css/General.css
http://site.com/rss/Content/Css/Print.css

У меня складывается впечатление что выбран неверный подход и я все это время просто извращался...
PM   Вверх
tol05
Дата 13.1.2010, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



W1zArD, я бы сделал так примерно
Код

internal class Program
    {
        private static void Main(string[] args)
        {
            List<Uri> uris = new List<Uri>
                              {
                                  new Uri("http://site.com/Content/Css/General.css"),
                                  new Uri("http://site.com/Content/Css/General.css"),
                                  new Uri("http://site.com/rss/Content/Css/General.css"),
                                  new Uri("http://site.com/rss/Content/Css/Print.css")
                              };

            Record root = new Record(uris[0].Authority);    //  "site.com"
            root.MakeTree(uris);
        }
    }

    public class Record
    {
        public List<Record> Pages { get; set; }
        public string SegmentName { get; set; }

        public Record(string segmentName)
        {
            SegmentName = segmentName;
            Pages = new List<Record>();
        }

        public void MakeTree(List<Uri> uris)
        {
            foreach (Uri uri in uris)
            {
                if (uri.Authority != SegmentName)
                {
                    continue; // url не относится к сайту
                }

                List<string> segments = new List<string>(uri.AbsolutePath.Split('/'));
                segments.RemoveAt(0);    
                                                                 
                InnerMakeTree(segments);
            }
        }

        private void InnerMakeTree(List<string> segments)
        {
            string segmentName = segments[0];

            Record childPage = GetPage(segmentName);

            if (segments.Count == 1)
            {
                return; //конец рекурсии
            }

            segments.Remove(segmentName);

            childPage.InnerMakeTree(segments);
        }

        private Record GetPage(string pageName)
        {
            Record childPage = Pages.Find(rec => rec.SegmentName == pageName);
            if (childPage == null)
            {
                childPage = new Record(pageName);
                Pages.Add(childPage);
            }

            return childPage;
        }
    }




--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1011 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.