Some time ago, to be more honest last Sunday, I participated at some Java exam again. The results were not something to boast, quite on the contrary, but I did not have a lot of time to prepare π The contest was hosted by the SoftUniΒ and the tasks were quite tough. At least this time I knew how to debug in Eclipse, so I did not waste time to learn it π
The Java problem, which I had to resolve was concerning words.
Pretty much, you have a string as input where you should consider all the latin characters as words. You should return all triples, in which two words together make a third one. It is probably better to see the original examples in order to understand:
Yup, I am probably the only person in the world, who knows enough HTML to format a table and still prefers to make a screenshot of it. Pretty much, I managed to resolve the problem after some time. This was my approach:
- I read the string;
- I replaced everything, which is not a latin character with a space (with a Regex π );
- In order to avoid some misunderstanding, if there were some places with more than one space, I replaced them with one space;
- I split by the space to make a string array;
- Then came the real part – I started three loops, which gave me values for aΒ ,Β b and c;
- Then I made the check for the condition;
- I wrote the solution in one ArrayList;
- I checked the frequency of my solution in the ArrayList;
- If the frequency was 1, I printed it;
- If I printed anything, I increased the counter plus one;
- At the end I made a check whether the counter is 0, in order to print “No” if true;
Here is the outstanding code:
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 |
import java.util.*; public class CognateWords { public static void main(String[] args) { Scanner input = new Scanner(System.in); String Normal = input.nextLine(); String MoreNormal = Normal.replaceAll("[^A-Za-z]", " "); String SuperNormal = MoreNormal.replaceAll("[ ]+", " "); String[] numsStr = SuperNormal.split(" "); int Counter = 0; ArrayList ar = new ArrayList(); int myCount = 0; for (int k = 0; k < numsStr.length; k++) { for (int i = 0; i < numsStr.length; i++) { for (int z = 0; z < numsStr.length; z++) { String a = numsStr[k]; String b = numsStr[i]; String c = numsStr[z]; if ((a + b).equals(c)) { String myString = a + "|" + b + "=" + c; ar.add(myString); for (String sA : ar) { myCount = Collections.frequency(ar, sA); } if (myCount == 1) { System.out.println(myString); Counter++; } } } } } if (Counter == 0) { System.out.println("No"); } } } |
Pretty much I could have reduced a pair of lines, but I really thing it is a smooth decision.
The original solution was a bit better:
- It used HashSet<String> – thus, you do not have to check whether the value is unique or not;
- The reading of the first line and the split into an array is done in one line;
- I like the way the boolean check is declared and given value;
- Also, the original solution works with less variables, thus it should be faster;
Pretty much, this is how it looks like:
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 |
import java.util.Scanner; import java.util.HashSet; public class CognateWords { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String[] words = sc.nextLine().split("[^a-zA-Z]+"); HashSet cognateWords = new HashSet<>(); for (int a = 0; a < words.length; a++) { for (int b = 0; b < words.length; b++) { for (int c = 0; c < words.length; c++) { // Check if a!=b and a|b=c if (a != b) { boolean check = (words[a] + words[b]).equals(words[c]); if (check) { cognateWords.add(words[a] + "|" + words[b] + "=" + words[c]); } } } } if (cognateWords.isEmpty()) { System.out.println("No"); } else { for (String cognate : cognateWords) { System.out.println(cognate); } } } } |
Enjoy it responsibly! π