Find longest word in a sentence recursively - java

So I need to find the longest word recursively, I've written the code, but it's not working, and I have no idea what to fix.
public static String longestWord(String sentence)
{
int i = sentence.indexOf(" ");
if (i==-1){
return sentence;
}
else{
String first = sentence.substring(0,i);
String rest = sentence.substring(i+1);
if(first.length()>=rest.length()){
return longestWord(first);
}
else{
return longestWord(rest);
}
}
}

The line:
if(first.length() >= rest.length())
should read like:
String res = longestWord(rest);
if(first.length() >= res.length())

The reason it does not work is that you are ignoring the length of the longestWord(rest): instead of comparing the length of the initial word and the rest of the sentence, you should compare the length of the initial word to the length of the longest word found in the rest of the sentence.
String first = sentence.substring(0,i);
String rest = longestWord(sentence.substring(i+1));
return first.length()>=rest.length() ? first : rest;

Your basic approach is sane: you're breaking the input into two: the first word, and the rest of the string. But then the logic is bungled a little bit.
If the first word is longer than the entire rest of the string, you should just return first, not longestWord(first) (although, you do handle that case: longestWord will notice that the word cannot be split and just return it. It's pointless though).
Secondly, if that is not the case, you cannot assume that the first word is not the longest word. You must capture the return value of longestWord(rest), and then compare that word's length to the length of first. If that word is longer, then return it. Otherwise return first.
The essence of "divide and conquer" by recursion is that you solve some smaller versions of the problem, and then integrate those results. Don't forget this second part. This is not a binary search tree search where the data is organized such that you can just recurse to one half of the space or the other to find the answer. You don't know where the longest word might be.

This is another approach to solve the question:
public static String longestWord(String sentence) {
return longest(sentence.split("\\s+"), 0, 0);
}
private static String longest(String[] words, int idx, int longest) {
if (idx == words.length)
return words[longest];
return longest(words, idx+1,
words[idx].length() > words[longest].length() ? idx : longest);
}
First, in longestWord() the sentence gets split by its spaces, producing an array of words. From that point on, the method longest() recursively iterates over all the words passing the index of the longest one found so far in the longest parameter, until there are no more words. This is an efficient answer, as it doesn't create substrings at each step.

package com.kota.java;
import java.util.*;
class LongestWord{
String str = "Ram is intelligent boy";
String stringArray[] = str.split("\\s");
public String compare(String st1, String st2) {
if (st1.length() > st2.length()) {
return st1;
} else {
return st2;
}
}
LongestWord() {
String word = "";
for (int i = 0; i < stringArray.length; i++) {
if (i == 0) {
word = stringArray[0];
}
word = compare(word, stringArray[i]);
}
System.out.println("Longest word = " + word);
}
public static void main(String[] args) {
new LongestWord();
}
}
/**
* Out put : Longest word = intelligent
*
* */

Related

Find words in String consisting of all distinct characters without using Java Collection Framework

I need your help. I am stuck on one problem, solving it for several hours.
*1. Find word containing only of various characters. Return first word if there are a few of such words.
2. #param words Input array of words
3. #return First word that containing only of various characters*
**public String findWordConsistingOfVariousCharacters(String[] words) {
throw new UnsupportedOperationException("You need to implement this method");
}**
#Test
public void testFindWordConsistingOfVariousCharacters() {
String[] input = new String[] {"aaaaaaawe", "qwer", "128883", "4321"};
String expectedResult = "qwer";
StringProcessor stringProcessor = new StringProcessor();
String result = stringProcessor.findWordConsistingOfVariousCharacters(input);
assertThat(String.format("Wrong result of method findWordConsistingOfVariousCharacters (input is %s)", Arrays.toString(input)), result, is(expectedResult));
}
Thank you in advance
Just go through the data and check whether each string is made up of only distinct characters:
public static boolean repeat(String str) {
char[] chars = str.toCharArray();
Arrays.sort(chars);//The same character will only appear in groups
for(int i = 1;i<chars.length;i++) {
if(chars[i] == chars[i - 1]) {
return false;//Same character appeared twice
}
}
return true;//There is no repeating character
}
The method above is used to check whether a string is made up of distinct characters, now loops through the data:
for(int i = 0;i<input.length;i++){
if(repeat(input[i])){
System.out.println("The answer is " + input[i] + " at index " + i);
break;//you find it! Now break the loop
}
}
Assuming the strings are all ASCII characters, use a boolean[] to mark if you have encountered that character in the word already:
boolean [] encountered = new boolean[256];
for (char c : word.toCharArray()) {
if (encountered[(int)c]) {
// not unique
} else {
encountered[(int)c] = true;
}
}

How to find the last word in a string

I'm trying to create a method that returns the last word in a string but I am having some trouble writing it.
I am trying to do it by finding the last blank space in the string and using a substring to find the word. This is what I have so far:
String strSpace=" ";
int Temp; //the index of the last space
for(int i=str.length()-1; i>0; i--){
if(strSpace.indexOf(str.charAt(i))>=0){
//some code in between that I not sure how to write
}
}
}
I am just beginning in Java so I don't know many of the complicated parts of the language. It would be much appreciated if someone could help me find a simple way to solve this problem. Thanks!
You can do this:
String[] words = originalStr.split(" "); // uses an array
String lastWord = words[words.length - 1];
and you've got your last word.
You are splitting the original string at every space and storing the substrings in an array using the String#split method.
Once you have the array, you are retrieving the last element by taking the value at the last array index (found by taking array length and subtracting 1, since array indices begin at 0).
String str = "Code Wines";
String lastWord = str.substring(str.lastIndexOf(" ")+1);
System.out.print(lastWord);
Output:
Wines
String#lastIndexOf and String#substring are your friends here.
chars in Java can be directly converted to ints, which we'll use to find the last space. Then we'll simply substring from there.
String phrase = "The last word of this sentence is stackoverflow";
System.out.println(phrase.substring(phrase.lastIndexOf(' ')));
This prints the space character itself too. To get rid of that, we just increment the index at which we substring by one.
String phrase = "The last word of this sentence is stackoverflow";
System.out.println(phrase.substring(1 + phrase.lastIndexOf(' ')));
If you don't want to use String#lastIndexOf, you can loop through the string and substring it at every space until you don't have any left.
String phrase = "The last word of this sentence is stackoverflow";
String subPhrase = phrase;
while(true) {
String temp = subPhrase.substring(1 + subPhrase.indexOf(" "));
if(temp.equals(subPhrase)) {
break;
} else {
subPhrase = temp;
}
}
System.out.println(subPhrase);
You can use: (if you are not familiar with arrays or unusual methods)
public static String lastWord(String a) // only use static if it's in the
main class
{
String lastWord = "";
// below is a new String which is the String without spaces at the ends
String x = a.trim();
for (int i=0; i< x.length(); i++)
{
if (x.charAt(i)==' ')
lastWord = x.substring(i);
}
return lastWord;
}
you just need to traverse the input string from tail when first find blank char stop traverse work and return the word.a simple code like this:
public static String lastWord(String inputs) {
boolean beforWords = false;
StringBuilder sb = new StringBuilder();
for (int i = inputs.length() - 1; i >= 0; i--) {
if (inputs.charAt(i) != ' ') {
sb.append(inputs.charAt(i));
beforWords = true;
} else if (beforWords){
break;
}
}
return sb.reverse().toString();
}
You could try:
System.out.println("Last word of the sentence is : " + string.substring (string.lastIndexOf (' '), string.length()));

Trying to retrieve the first longest word from a string, where a sentence contains strings of the same length ?

public class Challenge{
public static String longestWord(String sentence){
String s= sentence;
String[] word=s.split(" ");
String four=" ";
for(int i=0;i<word.length;i++){
if(word[i].length()>=four.length()){
four=word[i];
}
}
return four;
}
What i'm struggling with here is that if i have the sentence "This has lots that are four long" for example, the code defaults to printing "four" instead of "this" which i need - im not sure how to implement the code which allows me to return the first longest string from a given sentence. Any help would be appreciated.
You just need to stop overwriting your stored “longest word” when the length is equal to the current word. Replacing >= with > in your if statement should do the trick.
Your variable names are confusing, and redundant. I would assume the longest word is the first, and then begin the loop at the second word. And you want > (not >=). Like,
public static String longestWord(String sentence) {
String[] words = sentence.split("\\s+");
String longest = words[0];
for (int i = 1; i < words.length; i++) {
if (words[i].length() > longest.length()) {
longest = words[i];
}
}
return longest;
}
or in Java 8+
public static String longestWord(String sentence) {
return Stream.of(sentence.split("\\s+")).max(
(a, b) -> Integer.compare(a.length(), b.length())).get();
}
You can try in Java 8:
public static String longestString(String sentence){
return Stream.of(sentence.split("\\s+"))
.max(Comparator.comparing(String::length))
.orElse("");
}

Longest palindrome within a word

I am trying to make a program to find the longest a palindrome within a string.
E.g., Banana -> anana
I have made a for loop to reverse the inputted string and I can make it check each time if it is a palindrome but I'm not sure it will work since the palindrome may not start at the first letter of the string.
Right now, my programs output is the following:
a
an
ana
anan
anana
ananab
In this case it would work but if the input was, say, abracadabra, the two palindromes within would be ace and ada but the program would not find it properly.
Here is my code:
public class Palindrome {
public static void main(String[] args) {
String string = "banana";
String reverse = "";
int length = string.length() - 1;
for (int i = length; i >= 0; i--) {
reverse = reverse + string.charAt(i);
System.out.println(reverse);
}
}
}
My method considers all possible substrings of the input string. For each substring it uses StringBuilder.reverse() to reverse the substring and then compare it to the original substring to determine if it was a palindrome.
private static Collection<String> longestPalindromesIn(String input) {
// longest palindromes found until now
Set<String> result = new HashSet<>();
// length of longest palindrome found until now (all strings in result have this length)
// initialize to a negative value to make sure that the first palindrome found will appear to be longer
int longest = -1;
// iterate over all possible substrings
for (int start = 0; start <= input.length(); start++) {
for (int end = start; end <= input.length(); end++) {
String currentSubstring = input.substring(start, end);
// only consider if at least as long as the longest palindrome already found
if (currentSubstring.length() >= longest) {
if (isPalindrome(currentSubstring)) {
if (currentSubstring.length() > longest) {
// discard palindromes shorter than the one we have just found
result.clear();
longest = currentSubstring.length();
}
result.add(currentSubstring);
}
}
}
}
return result;
}
private static boolean isPalindrome(String candidate) {
// the following is the easy way of reversing a string;
// you may use your own code instead if you prefer
StringBuilder reverse = new StringBuilder(candidate);
reverse.reverse();
return candidate.equals(reverse.toString());
}
For input banana the method returns a set of a single string, anana.
abracadabra gives two palindromes, aca and ada.
abca gives a, b and c. If there is no interesting palindrome (length 2 or more), the method just returns each letter. Once each, since the result is a Set and hence filters out duplicates.
If input is the empty string "", output is the empty string too. It is a palindrome after all.

How do I find the letters of a certain word within a Character array in Java?

I need to compare the characters from two different Character Arrays to find the Hidden word inputted by the user.
The goal is to input 2 Strings and to find a word scrambled within the other.
Ex. The word "tot" is scrambled in the word "tomato"
With the help of some people of the forums, I have implemented character arrays to store the user Strings, but I do not know a way to check each array for the characters needed. I have tried the code below but it always results in the program not being able to find the word. If anyone could provide a better method or solution I'd highly appreciate it.
public static void main(String[] args) {
input = new Scanner(System.in);
System.out.println("Please enter a word");
String word = input.next();
char[] charOfWrds = word.toCharArray();
System.out.println("Please enter a hidden word you would like to search for");
String search = input.next();
char[] charOfSrch = search.toCharArray();
if (isContains(charOfWrds, charOfSrch))
{
System.out.print("The word " + search + " is found in the word " + word);
}
else
{
System.out.print("The word was not found in " + word);
}
}
public static Boolean isContains(char[] charOfWrds, char[] charOfSrch) {
int count = 0;
for (char cha : charOfWrds)
{
for (char chaaa : charOfSrch)
{
if (cha == chaaa)
count++;
}
}
if (count == charOfSrch.length)
{
return true;
}
return false;
}
public static Boolean isContains(char[] charOfWords, char[] charOfSrch) {
List<Character> searchFor = new ArrayList<>();
List<Character> searchMe=new ArrayList<>();
for(char c:charOfWords)
searchFor.add(c);
for(char c:charOfSrch)
searchMe.add(c);
for(int x=searchFor.size()-1;x>=0;x--){
if(searchMe.contains(searchFor.get(x)){
searchMe.remove(searchFor.get(x));
searchFor.remove(x);//line A
}
}
return searchFor.size()==0;
}
Quick overview of what this does. I converted both of the character arrays into Lists, so that I could use the List methods. Then, I iterated through every character in the word that you need to find, and if I could find it in the other word, I removed it from both of them, meaning that if all the words were removed from the word needed to be find, the word was found in the other word;otherwise it was not.
I assumed that you could not reuse letters in the second word, but if you can, then just remove line A.
You should try regular expression rather than trying to write an algo.
Build the expression using user input and then match with the desired word.
take
tomato as charOfWrds
tot as charOfSrch
isContains will count 6 because you don't quit when you find a letter of the first word in the second.
t : two times
o : two times
t : two times
try this :
if (cha == chaaa){
count++;
break;
}
but to make this work you need to remove the letter once found from the second string, because if the word you're looking for is "tttt", then this code will give you true even if it's not, but if you remove t when you found it then it should do the trick.
I don't know if that's clear enough for you.
here is the code :
public static Boolean isContains(char[] charOfWrds, char[] charOfSrch) {
int count = 0;
for (int i=0; i<charOfWrds.length;i++){
for (int j=0;j<charOfSrch.length;j++){
if (charOfWrds[i] == charOfSrch[j]){
count++;
charOfSrch[j]=' ';
break;
}
}
}
if (count == charOfSrch.length)
{
return true;
}
return false;
}
It's working, i tried it with this :
String word = "tomato";
char[] charOfWrds = word.toCharArray();
String search = "tot";
char[] charOfSrch = search.toCharArray();
But this is ugly, you should try to use the java Api, unless you really have to do it with arrays.
My idea was similar to what #kirbyquerby provided except that it has a few optimizations.
Instead of using a linear search, after converting each word (the needle and the haystack) to a list, we sort those lists. This allows us to use binary search which changes the search complexity from O(n^2) to O(n log n).
Additionally, there is no need to remove characters from the needle list as we can just keep track of how many needle characters have been found. Once we are done searching, we simply compare the number of found needle characters to the total number of needle characters. If they are equal, we have found our needle. Lastly, if a needle character is not found, we can stop searching immediately as we know that the entire needle does not exist within the haystack.
package hiddenword;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class HiddenWord {
public static void main(final String args[]) {
final String haystack = "Tomato";
final String needle = "tot";
if (contains(haystack, needle)) {
System.out.println(haystack + " contains " + needle);
} else {
System.out.println(haystack + " does not contain " + needle);
}
}
private static boolean contains(final String haystack, final String needle) {
// Convert each word to lowercase and into a List.
final List<Character> haystackChars = toSortedCharacterList(haystack.toLowerCase());
final List<Character> needleChars = toSortedCharacterList(needle.toLowerCase());
int foundNeedleChars = 0;
for (final Character c : needleChars) {
// Using sorted lists, our search time is be O(n log n) by using
// binary search instead of O(n^2) using linear search.
int index = Collections.binarySearch(haystackChars, c);
// A needle character has been found, remove it from the haystack
// and increment the count
if (index >= 0) {
haystackChars.remove(index);
++foundNeedleChars;
}
// A needle character was not found. This means that the haystack
// doesn't contain every character of the needle and we
// can quit early
else {
return false;
}
}
// If we've found all the needle characters, the needle word exists in
// the haystack word.
return foundNeedleChars == needleChars.size();
}
private static List<Character> toSortedCharacterList(final String input) {
final List<Character> list = new ArrayList<Character>();
// Convert primitive array to List
for (final char c : input.toCharArray()) {
list.add(c);
}
// Sort that thang
Collections.sort(list);
return list;
}
}
You can do this without having to convert the strings to an array with something like:
static boolean containsScrambled(String word, String search){
//loop through each character of the word whose characters we are searching for
for(int x = 0; x<search.length(); x++){
//find the current character to check
String c = search.substring(x, x+1);
if(word.indexOf(c) >= 0){
//if the character is in the word, remove the first instance of it
//as we cannot use that character again
word.replaceFirst(c, "");
}else{
//if the character is not in the word, fail and return false
return false;
}
}
//if we made it here, all of the characters existed, return true
return true;
}

Categories