Problem Statement
A description of the problem can be found on Hackerrank.
Solution
Parse all tags with attributes. Then parse only tags and attributes. Group attributes by tag name. Sort grouped tags and accordingly attributes.
I created solution in:
All solutions are also available on my GitHub.
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DetectHtmlAttributes { private static final String REGEX = "<[a-z0-9]+(\\s+[a-z]+=[\\\"\\'][a-zA-Z\\[\\]\\-\\/\\\\:\\.\\s_\\?!\\d;\\(\\),#@\\{\\}=%\\&\\|\\+\\*]*[\\\"\\'])*(\\s+/)?>"; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Pattern regex = Pattern.compile(REGEX); int tests = Integer.parseInt(scanner.nextLine()); List<String> tagsWithAttributes = new ArrayList<>(); for(int i = 0; i < tests; i++) { String line = scanner.nextLine(); Matcher matcher = regex.matcher(line); while(matcher.find()) { tagsWithAttributes.add(matcher.group()); } } Map<String, Set<String>> map = new TreeMap<>(); for(String tagAtt : tagsWithAttributes) { Pattern tagPattern = Pattern.compile("<[a-z0-9]+"); Matcher tagMatcher = tagPattern.matcher(tagAtt); String tag = null; Set<String> attributes = new TreeSet<>(); if(tagMatcher.find()) { tag = tagMatcher.group().replace("<", ""); } Pattern attPattern = Pattern .compile("[a-z]+=[\\\"\\'][a-zA-Z\\[\\]\\-\\/\\\\:\\.\\s_\\?!\\d;\\(\\),#@\\{\\}=%\\&\\|\\+\\*]*[\\\"\\']"); Matcher attMatcher = attPattern.matcher(tagAtt); while(attMatcher.find()) { attributes .add(attMatcher .group() .trim() .replaceAll( "=[\\\"\\'][a-zA-Z\\[\\]\\-\\/\\\\:\\.\\s_\\?!\\d;\\(\\),#@\\{\\}=%\\&\\|\\+\\*]*[\\\"\\']", "")); } Set<String> mapSet = map.get(tag); if(mapSet != null && !mapSet.isEmpty()) { mapSet.addAll(attributes); map.put(tag, mapSet); } else { map.put(tag, attributes); } } StringBuilder sb = new StringBuilder(); for(String tag : map.keySet()) { sb.append(tag); sb.append(":"); for(String attribute : map.get(tag)) { sb.append(attribute); sb.append(","); } if(!map.get(tag).isEmpty()) { sb.deleteCharAt(sb.length() - 1); } System.out.println(sb); sb.delete(0, sb.length()); } scanner.close(); } } |
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import scala.io.Source import scala.collection.mutable.Map object DetectHtmlAttributes extends App { private[this] val TAG_WITH_ATTRIBUTE_REGEX = "<[a-z0-9]+(\\s+[a-z]+=[\\\"\\'][a-zA-Z\\[\\]\\-\\/\\\\:\\.\\s_\\?!\\d;\\(\\),#@\\{\\}=%\\&\\|\\+\\*]*[\\\"\\'])*(\\s+/)?>".r private[this] val TAG_NAME_REGEX = "<[a-z0-9]+".r private[this] val ATTRIBUTE_REGEX = "[a-z]+=[\\\"\\'][a-zA-Z\\[\\]\\-\\/\\\\:\\.\\s_\\?!\\d;\\(\\),#@\\{\\}=%\\&\\|\\+\\*]*[\\\"\\']".r private[this] val ATTRIBUTE_VALUE_PATTERN = "=[\\\"\\'][a-zA-Z\\[\\]\\-\\/\\\\:\\.\\s_\\?!\\d;\\(\\),#@\\{\\}=%\\&\\|\\+\\*]*[\\\"\\']" val lines = Source.stdin.getLines().drop(1).toList val tagsWithAttributes = lines.map(findTagsWithAttributes).flatten val tagNames = tagsWithAttributes.map(parseTagName).flatten val attributes = tagsWithAttributes.map(parseAttributes) val tagGroups = groupAttributesByTags() createOutput() def findTagsWithAttributes(line: String): List[String] = { TAG_WITH_ATTRIBUTE_REGEX.findAllMatchIn(line).map(_.toString()).toList } def parseTagName(tag: String): List[String] = { TAG_NAME_REGEX.findAllMatchIn(tag).map(_.toString).map(_.replace("<", "")).toList } def parseAttributes(tag: String): List[String] = { ATTRIBUTE_REGEX.findAllMatchIn(tag).map(_.toString) .map(_.replaceAll(ATTRIBUTE_VALUE_PATTERN, "")).toList } def groupAttributesByTags(): Map[String, List[String]] = { val tagGroups: Map[String, List[String]] = Map.empty tagNames.indices.foreach(i => { val tag = tagNames(i) val attributeList = attributes(i) val actualAttributes = tagGroups.getOrElse(tag, Nil) tagGroups.put(tag, attributeList:::actualAttributes) }) tagGroups } def createOutput(): Unit = { val sortedKeys = tagGroups.keys.toList.sorted sortedKeys.foreach(tag => { val sortedAttributes = tagGroups.get(tag).get.distinct.sorted println(tag + ":" + sortedAttributes.mkString(",")) }) } } |