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

  • 10
  • Недоступна
Считайте с консоли имя файла, который имеет HTML-формат. Первым параметром в метод main приходит тег. Например, «span». Вывести на консоль все теги, которые соответствуют заданному тегу. Каждый тег на новой строке, порядок должен соответствовать порядку следования в файле. Количество пробелов, n, r не влияют на результат.
Вы не можете решать эту задачу, т.к. не залогинены.
Комментарии (177)
  • популярные
  • новые
  • старые
Для того, что бы оставить комментарий вы должны авторизоваться
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 Dmitrieva20 уровень, Москва
6 января, 21:59
спасибо за пункт 1, у меня без удаления переносов на этапе составления строки не проходила валидация (хотя при удалении переноса строки на этапе вывода в консоль результат был такой же) на код твой посмотреть хотелось бы, ибо лично у меня создается впечатление о несоответствии открывающих-закрывающих тегов в твоей мапе по причине вложенности тегов. лично у меня StringBuilder в цикле в цикле с переменной глубины тэга была мною также предпринята попытка использования javax.swing.text.html.parser, но там какая-то странная ерунда с атрибутами - xml:lang="en" парсится, например, в нечто, что в виде строки отображается как "xml#DEFAULT"
Vitaly Khan35 уровень
7 января, 01:03
пожалуйста) мой вариант
Андрей Коробов22 уровень, Уфа
13 декабря 2018, 06:52
Сделал через Jsoup. Столкнулся с тем, что замена
String strOut = element.toString().replaceAll("\\n","");
добавляла пробел после ">". Пришлось сделать еще одну замену:
String strOut = element.toString().replaceAll("\\n","");
System.out.println(strOut.replaceAll("> ",">"));
Так приняло
Vitaly Khan35 уровень
15 декабря 2018, 06:48
я делал
....replaceAll("[\\n\\r]", "");
никаких лишних пробелов не заметил.
DancingShaman23 уровень
20 ноября 2018, 01:27
Как пошагово решить задачу не изобретая велосипед: 1) Прочитать статью https://o7planning.org/ru/10399/jsoup-java-html-parser-tutorial 2) Установить сию библиотеку по ссылке https://jsoup.org/ 3) Написать код. И если вдруг валидатор не принял, то парсить нужно так: Element element = Jsoup.parse(whole_file, "span", Parser.xmlParser());
Alexey Maleev30 уровень
14 ноября 2018, 13:08
Вдруг кому будет интересно - решил задачу без всяких регэкспов и других библиотек, которые советуют пользовать в каментах. Сливаем файл в одну строку - не забываем тримить строки Определяем два массива - позиции открывающего тега, позиции закрывающего тега. Для приведенного в задаче примера имеем следующее (S - старт, Е - конец) : 18(S) 51(S) 70(E) 81(E) 88(S) 99(E) 106(S) 116(E) А теперь бежим по строке первого старта, счетчик пар "начало конец" равен 1, встретили конец - счетчик -1, встретили начало - счетчик +1. Как счетчик стал равен 0 - получили подстроку для вывода. Берем следующую точку старта и чешем по строке от неё. Вот и вся логика. :-)
Евгений24 уровень
11 ноября 2018, 23:12
Решил с двумя ArrayList и без регулярок ) Может, конечно, некрасиво, но решилось )
Victoria Sedletskaya31 уровень, Одесса
8 ноября 2018, 20:34
Больше чем полдня O_O без сторонних библиотек, с 5й проверки. честно думала бросить, хотя до этого все задачи решила. совет - проверьте на этом примере из условия, у меня не выводился последний тег из-за того что я конкатенировала строки в одну и получался другой тег <tagtext2.
<tag>text1</tag>
<tag text2>text1</tag>
<tag
text2>text1</tag>
Bogdan Yushkov31 уровень, Екатеринбург
5 ноября 2018, 23:05
Ребят, кто сделал "Знакомство с тэгами" без сторонних библиотек, помогите пожалуйста разобраться, почему валидатор не принимает. Ссылка на обсуждение
Антон41 уровень, Москва
2 ноября 2018, 15:29
Решилось довольно просто без JSOUP через Stack и TreeMap.
RegEx для тэга:
 "<(/?)" + tag + ".*?>"
В первой группе матчера будет пустая строка для открывающего тэга и / для закрывающего
Дальше ищем тэги, и если открывающий - push() в Стэк индекс начала тэга, если закрывающий - pop() ,и кладем в мапу: ключ - начало, которое достали из стэка, значение - подстрока
int start = indexStack.pop();
int end = matcher.end();
map.put(start, input.substring(start, end));
Map нужна, потому что содержимое тэгов получаем по мере закрытия, а выводить надо по порядку открытия
Ivan23 уровень
13 ноября 2018, 09:37
Не совсем понятно вот это: Дальше ищем тэги, и если открывающий - push() в Стэк индекс начала тэга, если закрывающий - pop() метод push() положить запись в стек, метод pop() вытаскивает объект из стека удаляя его. PS все понял идея в самом простом воплощении SAX https://ru.wikipedia.org/wiki/SAX, как то сразу этого увидеть не смог. Это действительно самое правильное решение для этой задачи на данный момент:)
Anonymous #37410529 уровень, Амстердам
11 декабря 2018, 20:47
Блин, решаешь, думаешь, как притулить сюда stack. Додумываешься до ответа. Читаешь комменты - находишь точь в точь такое же решение. Дурацкое чувство какое-то :) Единственное отличие - regEx у меня чуть сложнее, хотя тоже универсальный и использует группы.
Vitaly Khan35 уровень
15 декабря 2018, 07:10
у меня все довольно компактно получилось без Stack, только с TreeMap. вот основная часть кода (sb - объект StringBuilder, в котором собраны все символы из файла): может, конечно, у вас покороче получился код вместо моего дополнительного цикла for по map с поиском -1?
Антон41 уровень, Москва
20 декабря 2018, 17:07
Основная логика меньше 10 строк, но дело даже не в том, что код короче. В вашем алгоритме закрытие тэга требует линейного времени О(n), где n - количество открытых тэгов, т.к. нужно пройти по всей мапе. Можно оптимизировать, передав компаратор для сортировки по убыванию при создании TreeMap и отлавливать первое значение, равное -1, но решение со стэком все равно быстрее, т.к. гарантированно постоянное время поиска индекса последнего незакрытого тэга О(1).
Vitaly Khan35 уровень
21 декабря 2018, 01:18
спасибо за разъяснение. да, логично. забрать элемент из стэка будет быстрее, чем перебрать весь мэп.
Sasha S25 уровень, Киев
29 октября 2018, 22:40
сидів цілий день написав своє рішення, протестив на різних файлах. Працює! но як завжди валідатор не приймає((. З Jsoup написав через три рядка і все прийняло. Но хотяби досвід получив))
29 октября 2018, 19:43
Регулярки думаю правильнее будет тут использовать, поскольку JSOUP дальше по плану.