I'm simply trying to delete the last char in a String, I know this is a simple task and has been done any times BUT for some reason it doesn't work.
Example method
public String removeLastChar(String stringToRemoveCharFrom)
{
if(stringToRemoveCharFrom.length() > 0)
{
return stringToRemoveCharFrom.substring(0, stringToRemoveCharFrom.length());
}
else{
return stringToRemoveCharFrom;
}
}
Now, when I output the string sometimes I get an empty char at the end, when I call this function it runs the correct way BUT the string stays the same.
Debugger shows:
\b in some of the outputs, what is this? And how do I avoid it?
Any ideas?
I replaced the end with -1 like in the answers but it still fails to delete:
return stringToRemoveCharFrom.substring(0, stringToRemoveCharFrom.length() - 1);
It seems for some reason JAVA is entering weird characters that cannot be deleted. such as \b.
If I do the following at the start:
stringToRemoveCharFrom = stringToRemoveCharFrom.replaceAll("\b", "");
it works. But I'm wondering what this char is?
stringToRemoveCharFrom.substring(0, stringToRemoveCharFrom.length())
will return the entire String. What you should be doing is:
stringToRemoveCharFrom.substring(0, stringToRemoveCharFrom.length() - 1)
This is because substring(int start, int end) returns a substring starting at "start", and ending at the index 1 before "end". The starting index is inclusive, the end is exclusive.
You forgot to subtract one from the length:
public String removeLastChar(String stringToRemoveCharFrom)
{
if(stringToRemoveCharFrom.length() > 0)
{
return stringToRemoveCharFrom.substring
(0, stringToRemoveCharFrom.length() - 1);
}
else{
return stringToRemoveCharFrom;
}
}
stringToRemoveCharFrom.substring(0, stringToRemoveCharFrom.length());
Is a copy of the string, if you want to strip the last character, use:
stringToRemoveCharFrom.substring(0, stringToRemoveCharFrom.length() - 1);
Related
The task is to shift a number within a string to the beginning of the string with a recursion. So if I feed "ba3nana" to the code it should return "3banana". Did some recursive tasks already but this one I am stuck on.
I tried I guess already 50 different combinations but so far my code only returns "banana3" so I go the opposite way with my number. Does anyone see the mistake in my code?
The call of the method looks like this:
System.out.println(shiftDigitLeft("ba3nana"));
This is the code so far:
private static String shiftDigitLeft(String text) {
if (text.isEmpty()) {
return text;
} else {
if (text.charAt(0) >= '\u0030' && text.charAt(0) <= '\u0039') {
return shiftDigitLeft(text.substring(1)) + text.charAt(0);
} else {
return text.charAt(0) + shiftDigitLeft(text.substring(1));
}
}
}
Thanks in advance!
The pseudocode for what you've written would look like this
String shiftDigitLeft(String text) {
if the text is empty
return empty
else
if the first character is a digit
return shiftDigitLeft(the rest of the string) + the digit
else
return the letter + shiftDigitLeft(the rest of the string)
}
It should be obvious from this that digits never get moved to the left, only to the right.
You should probably invert your approach so that you look whether the last character is a digit, and if it is then move it to the beginning.
What does that mean? The length of the string is too long or there is error in my code?
public class Program {
public static String flipEndChars(String s) {
if(s.charAt(0) == s.charAt(s.length())){
return "Two's a pair.";
}
else if(s.length()<3){
return "incompatible";
}
else
return s.charAt(s.length()) + s.substring(1,s.length()) + s.charAt(0);
}
}
the issue is with this part :
s.charAt(s.length())
It's trying to access a character beyond the length of your string. The indexation is zero based, so the last character of a string is always at index s.length() - 1
String.charAt(int) returns the char at the specified index, where 0 is the first character, 1 is the second character, 2 is the third, and so on.
"hello".charAt(0) returns the character h.
String.length() returns the length of the string.
"hello".length() returns 5. So if you call "hello.charAt(5)", this will get the 6th character in the String "hello", which does not exist. This will throw an IndexOutOfBoundsException.
I hope this helps.
Disclaimer: This is a bit of a homework question. I'm attempting to write a contains(java.lang.String subString) method , that returns an int value representing the index of the comparison string within the primary string, for a custom-made String class.
Some of the rules:
No collection classes
Only charAt() and toCharArray() are allowed from the java String class (but methods from other classes are allowed)
Assume length() returns the length of the primary string (which is exactly what it does)
My Code:
public int contains(java.lang.String subString) {
this.subString = subString;
char[] arrSubStr = this.subString.toCharArray();
//Create initial fail
int index = -1;
//Make sure comparison subString is the same length or shorter than the primary string
if(arrSubStr.length > length()) {
return index;
}
//Steps to perform if initial conditions are met
else {
//Compare first character of subString to each character in primary string
for(int i = 0; i < length(); i++) {
//When a match is found...
if(arrSubStr[0] == this.content[i]) {
//...make sure that the subString is not longer than the remaining length of the primary string
if(arrSubStr.length > length() - i) {
return index;
}
//Proceed matching remainder of subString
else {
//Record the index of the beginning of the subString contained in primary string
index = i;
//Starting with second character of subString...
for(int j = 1; j < arrSubStr.length;) {
//...compare with subsequent chars of primary string,
//and if a failure of match is found, reset index to failure (-1)
if(arrSubStr[j] != this.content[j+i]) {
index = -1;
return index;
}
//If we get here, it means whole subString match found
//Return the index (=i) we set earlier
else {
return index;
}
}
}
}
}
}
return index;
}
Results from testing:
Primary string: asdfg
Comparison string: donkey
Result: -1 [PASS]
Primary string: asdfg
Comparison string: asdfg
Result: 0 [PASS]
Primary string: asdfg
Comparison string: g
Result: 4 [PASS]
Primary string: asasasf
Comparison string: asd
Result: 0 [FAIL] (should be -1)
Primary string: asasasf
Comparison string: asf
Result: 0 [FAIL] (should be 4)
The comments reflect how the code is intended to work. However its clear that when it reaches the second for loop, the logic is breaking down somehow to give the results above. But I can't see the problem. Could I get a second set of eyes on this?
//If we get here, it means whole subString match found
//Return the index (=i) we set earlier
else {
return index;
}
This assumption is not correct unfortunately. If you get there, it means that the second character of both substrings are identical since the if-else statement will only get executed once and both ends contains a return.
The way to solve this is probably easy now that I've diagnosed the problem but I want to go a bit further with this. The way we try to write code on a daily basis is a way in which the code we use can be maintainable, reusable and testable.
This means basically that the function we have here could be easily sliced up in different little functions invoked one after the other for which we could write unit tests and receive a quick feedback on whether a set of logical statements fit or not.
With suggestions from Jai and azurefrog in the comments, I was able to solve the issues by re-writing the logic to the following (somewhat abridged):
if(arrSubStr.length > length()) {
return index;
}
//Steps to perform if initial conditions are met
else {
//Compare first character of subString to each character in primary string
for(int i = 0; i < length(); i++) {
//When a match is found...
if(arrSubStr[0] == this.content[i]) {
//...make sure that the subString is not longer than the remaining length of the primary string
if(arrSubStr.length <= length() - i) {
//Record the index of the beginning of the subString contained in primary string
index = i;
//Starting with second character of subString...
for(int j = 1; j < arrSubStr.length; j++) {
//...compare with subsequent chars of primary string,
//and if a failure of match is found, reset index to failure (-1)
if(arrSubStr[j] != this.content[j+i]) {
index = -1;
break;
}
}
}
}
}
}
return index;
Essentially, I removed all of the return statements from within the loops. Simply setting the index value appropriately and making use of the final (outside) return statement was, in hindsight, the correct way to approach the problem. I then also added a break; to the inner for loop to make sure that a failure to match would continue the loop ticking through. I'm sure there's still unnecessary code in there, but while its still passing the requisite tests, I'm encouraged to leave it the hell alone. :)
I'm still a novice at Java, so I hope this explanation made sense.
There last 2 days I am 100% brain dead and cant find where the error is... Can anyone give me a tip >>
for(String inputString : word)
{
StringBuilder sb = new StringBuilder(inputString);
if(inputString.charAt(inputString.length()-1) == ']')
{
sb.deleteCharAt(inputString.length());
}
else if(inputString.charAt(0) == '[')
{
sb.deleteCharAt(0);
}
breaker.add(sb.toString());
}
It was suppose to be a simple function to remove the [ ] characters from a string but everytime I run it I get
Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
But only on the third or fourth pass never the first or second.
Confused.
sb.deleteCharAt(inputString.length());
should be
sb.deleteCharAt(inputString.length() - 1);
Because you want to remove the last character (you did it correctly in the test!)
You're deleting the last char at the StringBuilder's length, rather than length - 1.
StringBuilder, not unlike all String and array representations in Java, is 0-indexed.
Use the following idiom instead:
sb.deleteCharAt(sb.length() - 1);
The reason why the StringIndexOutOfBoundsException is only thrown arbitrarily in your execution is likely because of the condition checking for the ] character, which may not always hold true (hence the offending code would not execute).
public static int getIndexOf(char ch, String str) {
if (str == null || str.equals("")) {
return 0;
//base case
}else{
char first = str.charAt(0);
if (ch != first) {
return -1;
//returns -1 when the character cannot be found within the string
}else{
int rest = str.length() - 1;
if (str.charAt(rest) == ch) {
return rest;
}
return lastIndexOf(ch, str.substring(0, rest));
//recursive case
}
}
}
This my method which returns the index of the input character of the input string. However, when I run it in the interaction plane, it returns wrong number. For example, when I enter 'a' and "peach", it is supposed to return 2, but it returns -1. This method should return -1 only when the character cannot be found in the string. Can anyone tell me how to deal with it?
Thank you!
Well why don't you step through the logic and see what happens.
getIndexOf('a', "peach")
Method goes in, string isn't null or empty so it falls through to the next line of code.
char first = str.charAt(0); // this is 'p'
if (ch != first) { // is 'p' equal to 'a'? no. so return -1
return -1;
And then the rest of your logic will never execute. Can you see how to fix this problem?
your following portion of code means that it will check for the first character of the string if it is matching otherwise it will return -1.
char first = str.charAt(0);
if (ch != first) {
return -1;
this says that if character at 0th index doesn't match then send -1 so as 'p' in "peach" isn't matching with 'a' so it is return -1.
did you get it?
The output's not wrong, the implementation is!
Think in words first. If the desired character is the first character in the string, then the result is zero. Otherwise it's (1 + the index in the string that remains after cutting off the first character). Now code the words:
return (str.charAt(0) == ch) ? 0 : 1 + getIndexOf(ch, str.substring(1));
This doesn't yet handle the case where the character is not in the string at all. Here the charAt(0) call will eventually throw IndexOutOfBoundsException because str doesn't have one!
The cleanest way to handle this case is to catch the exception. So you's have two functions: mustGetIndexOf, which is the recursive relation above, and getIndexOf, which calls the one above inside a try {} catch() {}, returning -1 in that case.
Of course if you don't want to allow the exception, you can test the recursive call's result with if for the special case of -1. The code is uglier, but it will work. Whenever a -1 is seen, return -1 again. This propagates the -1 all the way back to the caller. The exception "unwinds" the recursive calls on the stack in a similar manner, just with one chop instead of the gradual call-by-call way your if statements will do it.
I won't give you full code so you can continue to learn.