Reputation: 550
MyApproach
For getting a middle word,I first found the length of each String.And checked multiple conditions for getting word such as
If the 2 words have equal length,If no word have equal length and if the last 2 have equal length for this I checked them character by character and used compareTo for the rest logic.
But I am unable to satisfy one test case.
Qn Can anyone guide me what I have done wrong in my code.
public String middleWord(String word1,String word2,String word3)
{
boolean b1=false;
boolean b2=false;
boolean b3=false;
int l1=word1.length();
int l2=word2.length();
int l3=word3.length();
if((l1>=l2)&&(l1>l3))
{
int p1=word1.compareTo(word2);
System.out.println(p1);
if(p1<0)
{
b1=true;
}
else
{
b2=true;
}
}
else if((l2>=l3)&&(l2>l1))
{
int p1=word2.compareTo(word3);
System.out.println(p1);
if(p1<0)
{
b2=true;
}
else
{
b3=true;
}
}
else if((l3>=l1)&&(l3>l2))
{
int p1=word1.compareTo(word3);
System.out.println(p1);
if(p1<0)
{
b1=true;
}
else
{
b3=true;
}
}
else if((l1>l2)&&(l1>l3))
{
if(l2>l3)
{
b2=true;
}
else if(l3>l2)
{
b3=true;
}
else
{
int p1=word2.compareTo(word3);
System.out.println(p1);
if(p1<0)
{
b2=true;
}
else
{
b3=true;
}
}
}
else if((l2>l3)&&(l2>l1))
{
if(l1>l3)
{
b1=true;
}
else if(l3>l1)
{
b3=true;
}
else
{
int p1=word1.compareTo(word3);
System.out.println(p1);
if(p1<0)
{
b1=true;
}
else
{
b3=true;
}
}
}
else if((l3>l1)&&(l3>l2))
{
if(l1>l2)
{
b1=true;
}
else if(l2>l1)
{
b2=true;
}
else
{
int p1=word1.compareTo(word2);
System.out.println(p1);
if(p1<0)
{
b1=true;
}
else
{
b2=true;
}
}
}
else if((l1==l2)&&(l1==l3))
{
int p1=word1.compareTo(word1);
int p2=word1.compareTo(word2);
int p3=word1.compareTo(word3);
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
if((p1<p2) &&(p1<p3))
{
if(p2<p3)
{
b2=true;
}
else
{
b3=true;
}
}
else if((p2<p3) &&(p2<p1))
{
if(p1<p3)
{
b1=true;
}
else
{
b3=true;
}
}
else if((p3<p2) &&(p3<p1))
{
if(p2<p1)
{
b2=true;
}
else
{
b1=true;
}
}
}
if(b1==true)
return word1;
else if(b2==true)
return word2;
else
return word3;
}
}
Parameters Actual Output Expected Output
'he' 'her' 'here' he her
Upvotes: 3
Views: 2186
Reputation: 4039
I'm sorry but there are so much problems with your approach that I think its a waste of time to get it up.
For example regard your whole if-statement
.
1: if ( (l1>=l2)&&(l1>l3) ) {}
2: else if ( (l2>=l3)&&(l2>l1) ) {}
3: else if ( (l3>=l1)&&(l3>l2) ) {}
4: else if ( (l1 >l2)&&(l1>l3) ) {}
5: else if ( (l2 >l3)&&(l2>l1) ) {}
6: else if ( (l3 >l1)&&(l3>l2) ) {}
7: else if ( (l1==l2)&&(l1==l3)) {}
The lines 4 - 6 are completely needless because these cases are full covered by the lines 1 - 3. This code will never be reached.
So instead of fixing your code I want to show you how your problem is solved in a professional way.
The Java build in solution
The Java Class Library has everything you need for sorting words. Put your words in a List and call Collections.sort
. After that you can find your middle word by getting the second entry out of the list.
List<String> list = new LinkedList<>();
list.add("her");
list.add("here");
list.add("he");
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
String middleWord = list.get(1); // "her"
The hand made solution
Your problem is very classic in computer science and if you really want to learn something you should keep trying to implement it yourself. But I recommend you to start with some reading about sorting algorithms.
I will show you an idea based on selection sort. That one is very easy to understand.
First I will introduce a simple method that returns the ascii value of one char
of a String
at specific position. If there is no char at the position it will return 0. Also it will work case insensitive means A
and a
result in the same value.
public static int getInsensitiveCharAt(String word, int index){
int c = 0;
if(word.length() > index){
c = word.charAt(index);
if(c >= 'A' && c <= 'Z') c = (c + 'a' - 'A');
}
return c;
}
Second I will introduce you a method that takes two String
values and compares them in a lexicographical way. The result is -1
if the first word is before second, +1
if the second is before the first and 0
if they are equal.
This method gets the ascii values of each char at each position in a loop using the method from above and compares them.
public static int compare(String s1, String s2){
int runs = Math.max(s1.length(), s2.length());
int index = 0;
while( index < runs){
int c1 = getInsensitiveCharAt(s1, index);
int c2 = getInsensitiveCharAt(s2, index);
if(c1 < c2) return -1;
if(c1 > c2) return 1;
index++;
}
return 0;
}
Last I will show you an implementation of selection sort that takes an unsorted array
of String
values and sort them using the compare method from above. It consists of two loops. The outer loop takes every entry in the list and the second loop compares that entry with all the following entries. If something smaller is found they will be swapped.
public static String[] sort(String[] list){
for (int i = 0; i < list.length - 1; i++) {
for (int j = i + 1; j < list.length; j++) {
if (compare(list[j], list[i]) == -1) {
String temp = list[j];
list[j] = list[i];
list[i] = temp;
}
}
}
return list;
}
And thats it. Now you can get your middle word by calling
String[] list = sort(new String[] {"her","here","he"});
String middleWord = list[1]; // "her"
Small improvements
This handmade solution gives you also the opportunity to adjust it for your special needs. Means if you are really interested in the second word only you can stop sorting at specific point. Just modify the sort method to stop sorting at n-ths
and return that one.
public static String getSortedWordAt(String[] list, int pos){
for (int i = 0; i < pos; i++) {
[...]
}
return list[pos - 1];
}
Now you simply call
String middleWord = getSortedWordAt(new String[] {"here","he","her"}, 2);
Upvotes: 0
Reputation: 43
Usage of Vector class can turn out be good idea because it stores automatically in sorted order. Finding out the size and printing out the middle one is possible..
Upvotes: 1
Reputation: 1427
For your specific case of middleWord("he", "her", "here"), you're hitting the 3rd else if clause:
else if((l3>=l1)&&(l3>l2))
{
int p1=word1.compareTo(word3);
System.out.println(p1);
if(p1<0)
{
b1=true;
}
else
{
b3=true;
}
}
In this case, l1 = 2, l2 = 3, l3 = 4
, p1 = a -ve number
because the length is of word 1 is smaller and that sets b1
to true
. You then return word1
because:
if(b1==true)
return word1;
else if(b2==true)
return word2;
else
return word3;
So yeah, your logic is wrong. Seems like you're comparing the strings with length first, then lexicographically. In which case, you can override the compareTo function and sort them. Then return the second element, which is a cleaner solution.
Seems like you don't really need to compare the lengths and just want to compare them lexicographically and you can't use the Collections or Arrays sort method. In this case you can just make use of the Java String's compareTo function.
public static String middleWord1(String word1, String word2, String word3) {
if (word1.compareTo(word2) == 0 || word1.compareTo(word3) == 0)
// word1 == word2 or word1 == word3
return word1;
else if (word2.compareTo(word1) == 0 || word2.compareTo(word3) == 0)
// word2 == word1 or word2 == word3
return word2;
else if (word3.compareTo(word1) == 0 || word3.compareTo(word2) == 0)
// word3 == word1 or word3 == word2
return word3;
else if ((word2.compareTo(word1) < 0 && word1.compareTo(word3) < 0) ||
(word3.compareTo(word1) < 0 && word1.compareTo(word2) < 0))
// word2 < word1 < word3 or word3 < word1 < word2
return word1;
else if ((word1.compareTo(word2) < 0 && word2.compareTo(word3) < 0) ||
(word3.compareTo(word2) < 0 && word2.compareTo(word1) < 0))
// word1 < word2 < word3 or word3 < word2 < word1
return word2;
else
// word1 < word3 < word2 or word2 < word3 < word1
return word3;
}
Upvotes: 1