Знакомство с тегами

  • 10
  • Недоступна
Считайте с консоли имя файла, который имеет HTML-формат. Первым параметром в метод main приходит тег. Например, «span». Вывести на консоль все теги, которые соответствуют заданному тегу. Каждый тег на новой строке, порядок должен соответствовать порядку следования в файле. Количество пробелов, n, r не влияют на результат.
Вы не можете решать эту задачу, т.к. не залогинены.
Комментарии (190)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Николай20 уровень
позавчера, 20:36
Сначала хотел через jsoup сделать, но потом решил бросить себе вызов и написал полную логику парсера для любого уровня вложенности тегов с рекурсивным перебором.
GreenLight20 уровень, Москва
3 марта, 16:30
через jsoup основное решение в 4 строки советую разобраться)
vk20 уровень, Санкт-Петербург
27 февраля, 21:16
Написал маленький класс Tag, который по сути текст с флагом закрыт/не закрыт. Парсинг простой: - ко всем открытым тегам приклеиваем прочитанный текст - если прочитали открытый тег - добавляем новый тег в список - если прочитали закрытый тег - закрываем последний открытый тег - рекурсивно парсим остаток текста. И не нужны никакие упорядоченные мапы, никакие индексы запоминать не нужно. Ведь закрывающий тег всегда относится именно к последнему из открытых. Через jsoup делать не стал из спортивного интереса
S3R3N1TY28 уровень, Санкт-Петербург
13 февраля, 23:42
Задача называется "Знакомство с тегами" - ничего себе знакомство, сразу давай пиши готовый парсер)) Ребят особо не парьтесь если не решили и полезли в комменты, как я. Главное разобраться, я например узнал для себя про новую библиотеку jsoup. Да и то- даже решив с ней и получив вывод такой же, как в условие в примере валидатор ругается на последний пункт. Затем начинаются танцы с бубном, в разделе помощь все есть. Кто то решает сам через свои алгоритмы и валидатор принимает их, я считаю достойно уважения. Я пробовал в начале подобрать регулярку, состояющую из нескольких условий ()разделенных pipeline, но вышло вывести только 3 строки. Потом полез сюда, и тут столько разных решений.Немного опечалился, что до меня не дошло решить как-то иначе, видимо все соки из меня выжили предыдущие задачи, ну ничего прорвемся мужики.
Денис23 уровень
13 февраля, 21:33
ВотДосада!!! Два дня читал про Html, XML, парсеры, думал, тут намекают на то, что, мол, ребята, давайтека углубляйтесь в параллельные темы самостоятельно. Научился импортировать сторонние библиотеки, написал вот такую красоту: Document document = Jsoup.parse(new File(fileName), "UTF-8"); String s = document.getElementsByTag(args[0]).outerHtml().replaceAll(" ", ""); System.out.println(s); А ВАЛИДАТОР НЕ ПРИНЯЛ!!!
Evgenii26 уровень, Санкт-Петербург
2 февраля, 16:26
Валидатор принимает неверное решение!!! Не учитывает вложенные тэги.
Artur38 уровень
1 февраля, 08:50
Решал часа 2, получился лютый говнокод, но валидатор засчитал. У других комментаторов решение гораздо элегантнее, на мой взгляд, я бы до такого не додумался. Мой алгоритм вкратце: Основная идея ввести счётчик count = 0, который увеличивается на 1 при открытии тега, и уменьшается при закрытии. 1. Объединил всё в 1 строку, убрал от греха все переносы строк. Разбил на массив чаров. 2. создал две стринг переменные, буффер и результат. 3. Шёл по массиву, добавляя к буфферу по символу. 4. Проверял, оканчивается ли буффер на <tag, если да, увеличивал счётчик. 5. Если счётчик больше нуля то я начинал записывать символы в переменную результат. 6. Если Результат оканчивается на закрывающий тег </tag>, то уменьшаем count на 1. Если count стал 0, то добавляем результат в итоговый массив, обнулял String resultat. 7. А вот если нет, то тут надо выцепить из результата вложенный тег,добавить его в другой массив и потом докинуть его в массив после того как основной добавим Не знаю, зачем всё это расписал, потому что подход явно далеко не самый эффективный, просто как еще один вариант для решения) Мой совет: Прежде чем писать код по считыванию из файла, просто скопируйте пример из условий, и попытайтесь его привести к нужному результату, когда всё получится, можно уже дописывать ридеры. На мой взгляд гораздо проще дебажить конкретную строку, а не прописывать путь к файлу каждый раз.
Даниил24 уровень
1 февраля, 10:16
Совет дельный, сам так и делал. Вот только на этом сайте подбирал себе регулярки в процессе решения (так как пока вообще не уверен в правильной работе того что придумал). Сам решил с 4 попытки, был 5666-м. Сначала просто часа пол сидел и даже не мог понять с чего начать. Потом подсмотрел тут общий подход к решению и начал рожать. 3 попытки потратил на свой первый вариант решения, потратил 4 часа в муках и в итоге вроде универсальное решение, только вот вывод был не в том порядке (в случае вложенных тегов сначала выводились те что внутренние, а нужно было наоборот). Общая суть была что записывал файл в строку (заодно и переносы строки обрезались), и в 2 "листа" записывал отдельно начальные индексы открывающих тегов, а в другую крайние индексы закрывающих тегов, и уже сравнивал между собой значения... Вообщем подход крайне не удачный. Плюнул, накидал новый подход и лёг спать. С утра меньше часа по рожал, и как говориться "и плов готов". Общая суть. Такая же строка, только уже добавил в один лист индексы закрывающих тегов. Потом в цикле искал совпадения открывающих тегов. Внутри цикла производил подпоиск начиная с закрывающего индекса совпадения внешнего цикла (только не бейте за то что закрутил) и до конца считанной строки. И уже там!!! если после открывающего тега сразу идёт закрывающий, то выводил эту строку, а если между ними есть N-ое количество открывающих тегов, то инкрементировал счётчик внешнего цикла и после того как были подсчитано количество вложенных открывающих тегов, брал элемент из листа под индексом N (то самое количество вложенных открывающихся тегов тегов)
Alexey Tarakanov19 уровень, Москва
вчера, 03:52
А как справились с текстом между тегов? Я что-то похожее делал, но если между тегами нет текста, то не работало. Сейчас сдался и делаю на jsoup
Erik Ghukasyan28 уровень
31 января, 22:09
Решил в течении 4 часов. Без регулярок (я их ненавижу) пользовался TreeMap для сортировки и уникальности клюйчей. indexOf и substring всего 52 строки считая пустые линии, импорты, скобки. Будут вопросы обращайтесь.
Роман22 уровень
23 января, 05:42
Долго пришлось помучиться над этой задачей, почти руки опустились.. Самое сложное было это придумать алгоритм для поиска вложенных тегов, уместился у меня на 21 строчку кода в цикле while со всеми скобками. Для алгоритма понадобилось: - цикл while, - один TreeMap (в него были впиханы все индексы открывающихся и закрывающихся тегов c метками), - форыч (для перебора TreeMap) и - переменная - итератор для подсчета кол-ва встреченных закр. тегов - вспомогательные переменные для временного хранения найденных индексов от тегов Перед началом перебора, нужно было как то запомнить первый индекс в TreeMap, к счастью есть и такой метод :) это firstKey() не представляю как без него я бы это сделал.. Ну а после найденного закрывающегося тега мы выходим из форыча, выводим на консоль строку по найденым индексам, ну и удаляем их из нашей мапы... и всё повторяется вновь. P.S.: Надеюсь что кому ни будь выше написанное поможет.
Vitaly Khan35 уровень
15 декабря 2018, 06:41
классная задача! обожаю такие, где нужно придумать свой алгоритм для решения поставленной задачи. для решения пришлось написать всего 20 строк. программа работает с любой глубиной вложения тегов. никакие доп.классы не использовал, кроме изученных на предыдущих уровнях (ну, и регулярок, конечно) основная идея такая - создаем упорядоченный map, где ключ представляет индекс начала открывающего тега, а значение - индекс конца закрывающего тега. алгоритм вкратце такой. 1) считываем все символы файла в одну строку и удаляем из нее переносы строк, 2) организуем проверку этой строки на соответствие регулярному выражению. как только найден открывающий или закрывающий тег, заходим внутрь цикла. 2.1) делаем доп.проверку, какой именно тег найден. 2.1.1) если это открывающий тег, то добавляем новый элемент в map. при этом, поскольку закрывающий тег еще не найден, добавляем в качестве значения null 2.1.2) если это закрывающий тег, то находим в map, последний из добавленных элементов, в котором значение равно null. и вместо null заносим найденный индекс конца закрывающего тега. собственно все!) по итогам работы цикла имеем пары индексов, пригодные без всякого преобразования для использования в методе substring. кому интересно, могу поделиться кодом.
Sasha Dmitrieva26 уровень, Москва
6 января, 21:59
спасибо за пункт 1, у меня без удаления переносов на этапе составления строки не проходила валидация (хотя при удалении переноса строки на этапе вывода в консоль результат был такой же) на код твой посмотреть хотелось бы, ибо лично у меня создается впечатление о несоответствии открывающих-закрывающих тегов в твоей мапе по причине вложенности тегов. лично у меня StringBuilder в цикле в цикле с переменной глубины тэга была мною также предпринята попытка использования javax.swing.text.html.parser, но там какая-то странная ерунда с атрибутами - xml:lang="en" парсится, например, в нечто, что в виде строки отображается как "xml#DEFAULT"
Vitaly Khan35 уровень
7 января, 01:03
пожалуйста) мой вариант
IceBerg30 уровень, Днепр
21 января, 11:27
Vitaly Khan, а разве readline() сам не тримает строку?
sb.append(br.readLine());                       //StringBuilder object includes all chars in the given file.
final String fileString = sb.toString().replaceAll("[\\n\\r]", "");
Vitaly Khan35 уровень
21 января, 12:59
да, действительно тримает... получается, вторая строка избыточная. на момент написания я не знал точно, как именно "под капотом" реализован метод readLine(). и, видимо, глядя на условие задачи, решил явно (для себя) удалить лишние символы.
Vitaly Khan35 уровень
23 января, 07:32
теперь знаю, что концом строки в методе readLine считается либо "\n", либо "\r", либо сочетание "\r\n". таким образом, "\r\n" - это конец одной строки, а, например, сочетание "\n\r" - это два разных, следующих друг за другом, конца строки. не знаю, пока насколько важно это знать, но решил поделиться...
Максим Хузеев25 уровень
26 января, 20:12
Красивое решение. Я пошел более сложным путем. В TreeMap запихиваем в качестве ключа индекс тега, в качестве значения: 1 (для открывающегося тега) или -1 (для закрывающегося). Тег считаем, когда сумму последовательных значений мапы равна 0. (Т.е. 1 + (-1) = 0 >> делаем субстринг... 1 + 1 + (-1) + (-1) = 0 >> делаем субстринг)