This code I've written reads the words from a certain file and connects them into a chain in accordance with the given principle.
Without the last snippet (the one after the last comment line), it would just output the longest chain possible, composed from the input words. Then the code would meet only 5 requirements. I added the last section in case there are some unmatchable words in the source file, and now the 6th requirement is satisfied, too. However, the last one is still not validated, though the input given in the example produces the expected output. I'm not sure what else I haven't taken into account.
package com.codegym.task.task22.task2209;
/*
Make a word chain
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.Buffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
public static void main(String[] args) throws IOException {
//String fileName = "C:\\Users\\passe\\codegym\\11483190\\codegym-project\\src\\com\\codegym\\task\\task22\\task2209\\Words";
StringBuilder fileContents = new StringBuilder();
// read the name of a file from the console
try (BufferedReader breader = new BufferedReader(new InputStreamReader(System.in));
BufferedReader bfreader = new BufferedReader(new FileReader(breader.readLine())))
//BufferedReader bfreader = new BufferedReader(new FileReader(fileName)))
{
// read the contents of the file, i.e. words separated by spaces
String line = null;
while ((line = bfreader.readLine()) != null) {
fileContents.append(line).append(" ");
}
}
String[] words = fileContents.toString().split("\\s+");
StringBuilder result = getLine(words);
System.out.println(result.toString());
}
public static StringBuilder getLine(String... words) {
StringBuilder longestChain = new StringBuilder();
if (words.length == 0 || words == null) return longestChain;
for (String firstWord : words) {
//-let's try every word as the first of our potential chain
//-initialize SB here, so it's new every time the outer for=loop starts
StringBuilder chain = new StringBuilder();
//-initialize the wordList here, in case the while-loop doesn't clean it completely
List<String> wordList = new ArrayList<>(Arrays.asList(words));
chain.append(firstWord);
wordList.remove(firstWord);
//let's make the longest possible chain with this randomly chosen word as te first one
while (!wordList.isEmpty()) {
boolean matchFound = false;
for (String word : wordList) {
if (word.toLowerCase().charAt(0) == chain.charAt(chain.length() - 1)) {
chain.append(" ").append(word);
wordList.remove(word);
matchFound = true;
break; //if the next word word is found, we break out of the for-loop and...
//...get back to the beginning of the while-loop, where we'll...
//...reset the matchFound tp false and continue searching for a match
}
}
//if no more matches are found, we've got the longest possible chain with this first word
if (matchFound == false) break;
}
// we assign the chain that we've built to the longestChain variable,
// if it's longer than its previous version
if (chain.length() > longestChain.length())
longestChain = chain;
}
//let's check how many words we have added to the chain
//and, if there are any words left, let's just add them to the end of the chain ignoring the matching principle
String[] longestChainArray = longestChain.toString().trim().split("\\s+");
if (words.length > longestChainArray.length) {
for (String w : words) {
if (!Arrays.asList(longestChainArray).contains(w))
longestChain.append(" ").append(w);
}
}
return longestChain;
}
}