last 3 characters of string to capital letter

Hi,

I am trying below challenge

http://codingbat.com/prob/p125268

I wrote as below

public String endUp(String str) {

if(str.length()<=3){
return str.toUpperCase();
}


if(str.length()>=3){
String str1=str.substring(0,4);
return str1.toUpperCase();
}
return null;
  
}

Open in new window


I see some test cases failing

Expected      Run            
endUp("Hello") → "HeLLO"      "HELL"      X         
endUp("hi there") → "hi thERE"      "HI T"      X         
endUp("hi") → "HI"      "HI"      OK         
endUp("woo hoo") → "woo HOO"      "WOO "      X         
endUp("xyz12") → "xyZ12"      "XYZ1"      X         
endUp("x") → "X"      "X"      OK         
endUp("") → ""      ""      OK         


How to improve and fix above program. Please advise
LVL 7
gudii9Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gudii9Author Commented:
how to capitalize the last 3 characters of string bigger than 3 characters. Please advise
0
gudii9Author Commented:
public String endUp(String str) {

if(str.length()<=3){
return str.toUpperCase();
}


if(str.length()>=3){
String str1=str.substring(Math.max(0, str.length() - 3));

return str1.toUpperCase();
}
return null;
  
}

Open in new window


i tried as above based on my search but got failed test cases as below

Expected      Run            
endUp("Hello") → "HeLLO"      "LLO"      X         
endUp("hi there") → "hi thERE"      "ERE"      X         
endUp("hi") → "HI"      "HI"      OK         
endUp("woo hoo") → "woo HOO"      "HOO"      X         
endUp("xyz12") → "xyZ12"      "Z12"      X         
endUp("x") → "X"      "X"      OK         
endUp("") → ""      ""      OK         


Please advise
0
gudii9Author Commented:
How  below line giving last 3 characters of string
String str1=str.substring(Math.max(0, str.length() - 3));
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

CEHJCommented:
Substringing isn't really appropriate, since no part of the String should be cut off

public String endUp(String str) {
   StringBuilder sb = new StringBuilder(str);
   int replaced = 0;
   for(int i = sb.length();--i>=0 && replaced < 3;) {
     char c = sb.charAt(i);
     sb.setCharAt(i, Character.toUpperCase(c));
     replaced++;
   } 
   return sb.toString();
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gudii9Author Commented:
Is there is a way i can do without using StringBuilder. Please advise
0
ozoCommented:
Yes, there is a way.

Your attempts are getting closer.  What is missing from the ones that are wrong, and how can you add that piece.
0
gudii9Author Commented:
I need to add front part of the string that is mising. I somehow need to get that and attach in the front
0
gudii9Author Commented:

String str1=str.substring(Math.max(0, str.length() - 3));

I was not clear on above line how it is giving last 3 characters of string. please advise.

what is the need of Math.max here
0
ozoCommented:
Math.max is useful when str.length() - 3 can be negative
0
gudii9Author Commented:
oh got it
0
gudii9Author Commented:
public class Test11 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        endUp("hello");

	}

	
	public static  String endUp(String str) {

		if(str.length()<=3){
		return str.toUpperCase();
		}


		if(str.length()>=3){
			
			
			
		String str1=str.substring(Math.max(0, str.length() - 3));
		String str2=str.substring(0, (str.length() - 3));
		return str2+str1.toUpperCase();
		}
		return null;
		  
		}
}

Open in new window


I wrote as above and all test cases seems happy




Show output only (no red/green)
prev  |  next  |  chance   |  CodingBat  >  Warmup-1      
Expected      Run            
endUp("Hello") → "HeLLO"      "HeLLO"      OK         
endUp("hi there") → "hi thERE"      "hi thERE"      OK         
endUp("hi") → "HI"      "HI"      OK         
endUp("woo hoo") → "woo HOO"      "woo HOO"      OK         
endUp("xyz12") → "xyZ12"      "xyZ12"      OK         
endUp("x") → "X"      "X"      OK         
endUp("") → ""      ""      OK         

I wonder how to avoid null

How my code is looking. Please advise
0
ozoCommented:
I might consider the if(str.length()>=3){ superfluous.  CEHJ might consider the string concatenation inefficient.
0
gudii9Author Commented:
public class Test12 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        endUp("hello");

	}

	
	public static  String endUp(String str) {

		if(str.length()<=3){
		return str.toUpperCase();
		}


	//	if(str.length()>=3){
			
			
			
		String str1=str.substring(Math.max(0, str.length() - 3));
		String str2=str.substring(0, (str.length() - 3));
		return str2+str1.toUpperCase();
		//}
		//return null;
		  
		}
}

Open in new window


I wrote as above and tests cases all of them passing

Expected      Run            
endUp("Hello") → "HeLLO"      "HeLLO"      OK         
endUp("hi there") → "hi thERE"      "hi thERE"      OK         
endUp("hi") → "HI"      "HI"      OK         
endUp("woo hoo") → "woo HOO"      "woo HOO"      OK         
endUp("xyz12") → "xyZ12"      "xyZ12"      OK         
endUp("x") → "X"      "X"      OK         
endUp("") → ""      ""      OK
0
gudii9Author Commented:
for(int i = sb.length();--i>=0 && replaced < 3;) {


in the above line what is the importance of below code

&& replaced < 3

Please advise
0
ozoCommented:
It stops the loop when 3 characters have been replaced
0
krakatoaCommented:
You don't need any loops for this stuff; take another approach :

public String endUp(String str) {
  
  String temp = str;
  str = str.toUpperCase();
  str = str.length()>2?str.replace(str.substring(0,str.length()-3),temp.substring(0,str.length()-3)):str;
    
  return str;
    }

Open in new window

0
gudii9Author Commented:
for(int i = sb.length();--i>=0 && replaced < 3;) {

Is increment operator missing in above code.  As usually for loop is in below format ?(assignment;condition;increment)
for(i=0;i<n;i++)
0
gudii9Author Commented:
str = str.length()>2?str.replace(str.substring(0,str.length()-3),temp.substring(0,str.length()-3)):str;

I was not very clear on above line.

If string length is greater than 2 is true then do  str.replace(str.substring(0,str.length()-3)
If string length is greater than 2 is false then do temp.substring(0,str.length()-3)):str

what is meaing of temp.substring(0,str.length()-3)):str

why we are using temp?
Please advise
0
ozoCommented:
Is increment operator missing in above code.  As usually for loop is in below format ?(assignment;condition;increment)
Yes, the increment part of the for(init;condition;increment)statement; is empty,
however, the --i in the condition part, and the replaced++ in the statement both serve the role.
0
ozoCommented:
what is meaing of temp.substring(0,str.length()-3)):str
It is part of the ternary conditional expression operator condition?value1:value2
str.length()>2?str.replace(str.substring(0,str.length()-3),temp.substring(0,str.length()-3)):str;
Here str.length()>2 is the condition,
str.replace(str.substring(0,str.length()-3),temp.substring(0,str.length()-3)) is value1, and str is value2
0
krakatoaCommented:
To expand on what ozo has explained : the ternary operator evaluates an expression to true or false. We only need to know whether the string is at least 3 characters long, (i.e. more than 2), - (or not) - then we can take the appropriate action.

Since we can copy the original string very easily by copying it to "temp", we can now capitalise the entire passed-in string, and replace the part of it that should NOT be in caps, with the correct length substring from "temp" (which holds a copy of the original, lower case version). And if the passed-in string was 2 characters long or less, then we just return the (already) uppercased version of it.
0
awking00Commented:
One statement will do it -

public String endUp(String str) {

return str.length() <= 3? str.toUpperCase() : str.substring(0,str.length() - 3)
                                    + str.substring(str.length() - 3,str.length)).toUpperCase();
}
0
krakatoaCommented:
Yes that would be a refinement. But the last length will cause a compile error as it is missing parentheses.
0
gudii9Author Commented:
public class Test15 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str3=endUp("hello");
		System.out.println("str3==>"+str3);

	}

	public static String endUp(String str) {
		   StringBuilder sb = new StringBuilder(str);
		   int replaced = 0;
		   for(int i = sb.length();--i>=0 && replaced < 3;) {
		     char c = sb.charAt(i);
		     sb.setCharAt(i, Character.toUpperCase(c));
		     replaced++;
		   } 
		   return sb.toString();
		}
}

Open in new window


i wonder why we need two counters like i and also replaced. please advise

return str.length() <= 3? str.toUpperCase() : str.substring(0,str.length() - 3)
                                    + str.substring(str.length() - 3,str.length)).toUpperCase();

above line is more easy to understand for me.
0
gudii9Author Commented:
public class Test15 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str3=endUp("hello");
		System.out.println("str3==>"+str3);

	}
	public static String endUp(String str) {

		return str.length() <= 3? str.toUpperCase() : str.substring(0,str.length() - 3)
		                                    + str.substring(str.length() - 3,str.length()).toUpperCase();
		}
}

Open in new window


above also worked fine after adding one bracket '('
0
awking00Commented:
Sorry for the bad typing. As krakatoa pointed out and you discovered.... - 3, str.length)) should have been ... - 3, str.length())
0
ozoCommented:
The reason for two counters was that --i>=0 stops the loop when you get to the start of the string, and replaced  < 3 stops the loop after replacing 3 characters.
Presumably this was more easy for the author of that code to understand,
but when you write your code you probably want to choose a way that's more easy for you.
0
gudii9Author Commented:
--i>=0 stops the loop when you get to the start of the string,

i thought we supposed to start the loop when we get to start of the string. I am not clear on this. please advise
0
ozoCommented:
That particular loop started at the end of the string, with int i = sb.length()


i thought we supposed to
Different people may approach problems differently.
I think this is a good thing because if we all thought the same way, we would never learn anything, and a problem that stumped one of us would stump everyone.
Eventually you will develop your own preferred styles, but it can still behoove you to be exposed to other styles.  It can help you understand other people's solutions, and it can give you more flexibility to choose styles according to how well they fit particular types of problems.
On the other hand, you don't need to learn every method at once, and you may want to concentrate first on what makes sense to you until you get comfortable with it and have a base to expand from.
0
gudii9Author Commented:
can we move the replaced into the for loop in the place of initialization along with 'i' initialization like

for(int replaced = 0 && int i = sb.length();--i>=0 && replaced < 3;)

Open in new window


Also in the conditional statement of for loop is there is limit on how many conditions we can check(like above we are checking two conditions)?
0
ozoCommented:
In Java, that would be an improper use of &&
but you could do it like
for(int replaced = 0, i = sb.length();--i>=0 && replaced < 3;){ }

There is no limit on how many conditions we can check, but too many may become confusing, and may suggest a rethink.
0
CEHJCommented:
Personally i'd never go above 2 or it starts becoming unreadable
0
krakatoaCommented:
and a problem that stumped one of us would stump everyone.


That is a good statement.

And as mega-Savant CEHJ often exhorts, the important thing is being sure of your objective.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.