How to fix this Run time error? - java

I am trying to make a java program which will find and remove repetative characters in string. Like if user types "baloon", the output should be "balon". I used String variable for input and copied its content to Char array so that I can analyze each character. I get ArrayIndexOutOfBoundsException. Here is my code
class doubleKiller{
private String inputStr = " ";
private char[] catchStr = new char[inputStr.length()];
private String modifiedStr;
//Accessor method
public void getString(String inputStr)
{
this.inputStr = inputStr;
}
public String killRepeater()
{
//copying string data to char array
this.inputStr.getChars(0 , this.inputStr.length() , catchStr , 0);
//------------------
for(int counter = 0 ; counter < this.inputStr.length() ; counter++)
{
if(catchStr[counter] != catchStr[counter - 1])
{
modifiedStr = modifiedStr + catchStr[counter];
}
}
return modifiedStr;
}
}
Here is Output when killRepeater() is called.
java.lang.ArrayIndexOutOfBoundsException: src.length=5 srcPos=0 dst.length=1 dstPos=0 length=4
at java.lang.System.arraycopy(Native Method)
at java.lang.String.getChars(String.java:894)
at doubleKiller.killRepeater(Main.java:23)
at useThings.main(Main.java:49)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.aide.ui.build.java.RunJavaActivity$1.run(SourceFile:108)
at java.lang.Thread.run(Thread.java:862)
Tell me my error...Thanks in advance

You are doing
private String inputStr = " ";
private char[] catchStr = new char[inputStr.length()];
inputStr.length() returns 1, that is, the size from the string " ", so, you have a char array with size 1.
When you do:
for(int counter = 0 ; counter < this.inputStr.length() ; counter++){
if(catchStr[counter] != catchStr[counter - 1]){
With a inputStr.length() > 1 you have an ArrayIndexOutOfBoundsException.
Also, when run catchStr[counter - 1]) for the first time, counter-1 would generate -1, which isn't a valid index. Try running the counter from 1 to avoid this error.
Declare your array with a fixed size(e.g 200) or use an ArrayList. You could also put catchStr = new char[inputStr.length()] after taking the input of the String.

Good thing that you asking about specific problem, but in case you interested how to make this simpler, there is regex magic
String in = "ballooooon";
String out = in.replaceAll("(.)\\1+", "$1"); // balon
Which means
find any symbol, save it to group 1, if next symbol, or symbols are equal to group 1, delete them and leave just one from the group.

You are initializing catchStr with inputStr.length(). But at this time inputStr = " ". So catchStr has a length of 1. When you later populate inputStr to a bigger value, you try and copy that into a char[] of length 1 and it doesn't fit. Add catchStr = new char[inputStr.length()]; right before you do the copy.

When you initialise catchStr it will always have the value of 1, because inputStr is " " and therefore it's length is 1.
private String inputStr = " ";
private char[] catchStr = new char[inputStr.length()];
When you loop on counter in the method killRepeater() you will get an ArrayOutOfBoundsException because the string you pass in getString is probably greater than 1.
Consider moving new char[inputStr.length()] into getString.
public void getString(String inputStr) {
this.inputStr = inputStr;
this.catchStr = new char[inputStr.length()];
}
And, setting the attribute catchStr to uninitialised.
private char[] catchStr;
The second issue is with your for loop. You start the counter at 0 and use catchStr[counter - 1] to look back on the previous character. This will not work when counter = 0 because the index will evaluate to -1.
Consider starting your counter at 1, and continue to work on the method from there. You'll need to tweak it a little to get it output the desired string.
for (int counter = 1; counter < this.inputStr.length(); counter++) {
if (catchStr[counter] != catchStr[counter - 1]) {
modifiedStr = modifiedStr + catchStr[counter];
}
}

Related

Java String index out of bounds with text file input

I am trying to split a String input into two using the following code:
public TypeValue(String line) {
while (line.charAt(i) != ' ') {
i++;
System.out.println(i);
}
type = line.substring(0,i);
value = line.substring(i);
}
my input is a textfile that looks like this:
10 16
10 32
10 9024720
F 10
F 1
F 111111
F 100000
F 10110110100111001
However, I always get a java.lang.StringIndexOutOfBoundsException: String index out of range: 13. This only happens when I try to read the input from a text file. When I use the terminal to input the lines one by one it works just fine.
I have been looking for a couple hours but I cannot figure out what is causing this. It is also always "13", even when I delete all but the first line from the text file. Can anybody help me with this?
Edit: Thank you for the help everybody. The problem was with something else entirely. I didn't properly put my File in the Scanner in my main method...
You should simply use line.split(" ") which will return an array of String, then get either the first or the second value using respectively the index 0 and 1 of the resulting array as next:
String[] values = line.split(" ");
type = values[0];
value = values[1];
Another way could be to use line.indexOf(' ') to get the index of the space character in your String.
int index = line.indexOf(' ');
// From 0 to the index where we found the space
type = line.substring(0, index);
// Starts from index + 1 to skip the space
value = line.substring(index + 1);
You forgot to initialize i. Try this:
public TypeValue(String line) {
int i=0;
while (line.charAt(i) != ' ') {
i++;
System.out.println(i);
}
type = line.substring(0,i);
value = line.substring(i);
}
Try comparing raw ascii values than characters,
as in
public TypeValue(String line) {
int i=0;
//ascii value for space is 32
while ((int)line.charAt(i) != 32) {
i++;
System.out.println(i);
}
type = line.substring(0,i);
value = line.substring(i);
}

Java string get latest 4 char reverse loop

I cannot figure how to obtain latest 4 char of string before zeroes
String str = "41f1f3d1f10000000000000000000000000000000000"
I want: d1f1
I've tried to revert string string than do straight loop
public static boolean checklast4digit(String risposta) {
String crc = "";
risposta = reverseIt(risposta);
for (int i = 0; i < risposta.length(); i++) {
if (risposta.charAt(i) != '0') crc = Character.toString(risposta.charAt(i + 3)) + Character.toString(risposta.charAt(i + 2)) + Character.toString(risposta.charAt(i + 1)) + Character.toString(risposta.charAt(i));
}
Log.i("Crc letto: ", crc);
return true;
}
public static String reverseIt(String source) { //Inversione stringa
int i, len = source.length();
StringBuilder dest = new StringBuilder(len);
for (i = (len - 1); i >= 0; i--) {
dest.append(source.charAt(i));
}
return dest.toString();
}
Exception:
java.lang.StringIndexOutOfBoundsException
As mentioned in the comments, you are looping too far. If you want to access charAt(i+3) you should only loop until i < risposta.length() - 3
Also, you need to break out of your loop, once you have found your result:
for(int i=0 ;i < risposta.length() - 3 ;i++){
if(risposta.charAt(i) != '0') {
crc= Character.toString(risposta.charAt(i + 3)) + Character.toString(risposta.charAt(i+2)) + Character.toString(risposta.charAt(i+1)) + Character.toString(risposta.charAt(i));
break;
}
}
Note that this only gives you a result, if you have 4 non-zero characters before the zeros.
There are many ways to improve your code, one of which would be to just remove the trailing zeroes first, then reverse the remaining string and take the first 4 chars of it.
However, to point out errors in your code...
Take a look at the values you're using to get characters. While your loop is limited to i<risposta.length(), i+3 that you're using in the line below is not - it can go up to risposta.length()+2. If oyu want to fix the code, then change the loop condition to i+3<risposta.length().
It's not elegant and can be done better, but that would solve the immediate bug in your code.
Your IndexOutOfBoundsException is caused by:
risposta.charAt(i + 3)
risposta.charAt(i+2)
risposta.charAt(i+1)
If you take a look at your for loop:
for(int i=0 ; i < risposta.length(); i++){
}
You are iterating from index 0 to risposta.length() - 1. However because you are getting the char at i+3 when i is risposta.length() - 1 it tries to access the index risposta.length() + 2 which is out of bounds.
You ned to modify your loop so you only iterate up to risposta.length() - 3
Here you have a oneliner!
String a = new StringBuilder(new StringBuilder("41f1f3d1f10000000000000000000000000000000000".split("0")[0]).reverse().toString().substring(0, 4)).reverse().toString();
And the complete code looks like this:
package nl.testing.startingpoint;
public class Main {
public static void main(String args[]) {
String a = new StringBuilder(new StringBuilder("41f1f3d1f10000000000000000000000000000000000".split("0")[0]).reverse().toString().substring(0, 4)).reverse().toString();
System.out.println(a);
}
}
result: d1f1
Alternatively, you could strip the 0's with a replaceAll and then get the last 4 chars with a substring. That makes the code pretty simple:
public static void main(String[] args) {
String str = "41f1f3d1f10000000000000000000000000000000000";
str = str.replaceAll("0*$", "");
System.out.println(str.substring(str.length()-4));
}
First of all the StringBuilder has a reverse method, which you can use to revers a string. That would simplify the reversing quite a bit.
return new StringBuilder(source).reverse().toString();
and as the others pointed out your for loop probably causes the exception, as it iterates to long.
To remove all trailing zeros (as suggested by CptBartender) you can use regex.
risposta = risposta.replaceFirst("0+$");
Then you can reverse the string (as shown above) and get the first n characters using the substring method.
reversed.substring(0, Math.min(reversed.length(), 4));
Math.min() is used to ensure there is no error if there are less than 4 characters before the zeros.

How do you convert a number and store it in a char array and then convert the char array to String so that it prints the integer?

I have a char array with four characters stored, and I need to add an integer to the char array and then add .txt to the end of if, then render the whole thing as a string so I can use it to create a file object. But when I run the whole process it doesn't work. Using println to output what is going on at every step it shows me that the number stored in the char array is printing to string as this: ( 0001 ) instead of just this (1). Why is that and how do I work around it? I typed up a short version of the segment of code here to demonstrate the problem. The output of the printline statement below is this: temp 0001 .txt instead of temp1.txt which is what I'm trying to get. Thanks for any help you can offer.
public class Test {
public static void main(String[] args) {
int count = 4;
char[] temp = new char[count + 5];
char[] base = new char[] {'t', 'e', 'm', 'p'};
char[] extension = new char[] {'.', 't', 'x', 't'};
for (int i = 0; i < 4; i++)
temp[i] = base[i];
temp[count] = (char)1;
for (int k = 0; k < 4; k++)
temp[count + 1 + k] = extension[k];
String file = new String(temp);
System.out.println(file);
}
}
You don't need to take all the hassles with character arrays. Java has done most of the job for you with String. Try this simpler code, to create 10 file names. I think you are trying to create a number of files with numbered names having same base name.
public class Test {
public static void main(String[] args) {
String baseName = "temp";
String extension = ".txt";
// create 10 file names
for(int i=0; i<10; i++) {
String newName = baseName + (i+1) + extension;
System.out.println(newName);
}
}
}
Note the parenthesis around i+1. Without parenthesis, i and 1 are cast to string separately, and are then concated to the string. For example, if i is 5, then without parenthesis this gives 51, whereas with parenthesis you get 6.
Bonus:
You can pad the number part with 0s like this:
String newName = baseName + String.format("%04d", i+1) + extension;
With this, the numbered part is padded with zeros to make length 4 if the length is less than 4. However if the length if 4 or greater than 4, the number does not get stripped.
For example: 45 becomes 0045, 12345 stays 12345
This will insert the char with the value 1 instead of the character 1.
emp[count] = (char)1;
Try this instead:
emp[count] = '1';
Edit:
If you want it more dynamically
int i = ...
emp[count] = (char) ('0'+ i);
Remember that the + operator works specially with strings to concatentate them. On top of that, anything is automatically converted into a String when the other operand of + is a String. So you can do all of this in a single line:
String file = base + 1 + extension;
Notice that 1 is not special here. It is a value with type int. So you can easily replace it with a variable name instead.
The value that you are trying to assign to emp[count] is the ascii value of 1
What you want is the ascii value of 1 which is 49, so you could do
emp[count] = 49;
or
emp[count] = 48 + 1;
or
emp[count] = '1';
Edit As per your comments, if all that you are trying to do is created a new file name then these arrays are not even needed.
See the answer from #Code-Apprentice
String file = base + 1 + extension;

How to change a random element of an attribute?

I'm trying to select a random element in an attribute, and then reverse the value of that randomly selected element between 0 and n, and then reprint the whole attribute again, with the reversed element shown. The reverse value for 0 is 1, and for 1 is 0 in this case.
Here is what I've attempted:
String whatever = "11111";
int n = whatever.length();
//the UI class generates a random integer number between 0 and n
int p = CS2004.UI(0,n);
if (whatever.charAt(p)=='0') {
+= 1;
} else {
+= 0;
}
I'm lost on the adding the opposite number bit.
I should clarify that this is homework!
Strings are immutable in Java, but you could do
StringBuilder sb = new StringBuilder(whatever);
if (whatever.charAt(p)=='0') {
sb.setCharAt(p, '1');
} else {
sb.setCharAt(p, '0');
}
whatever = sb.toString();
OK, lets give this a try.
Firstly, you will need to change the name of your variable 5 - I don't think you're allowed to start variables with a number (see here)
I'm assuming that by 'attribute' you mean the length of the String? This is probably supposed to be the value of your 5 variable.
So, lets look at some modified code...
String whatever = "11111";
int n = whatever.length();
//the UI class generates a random integer number between 0 and n
int p = CS2004.UI(0,n);
StringBuilder sb = new StringBuilder(whatever);
if (whatever.charAt(p)=='0') {
sb.setCharAt(p, '1');
} else {
sb.setCharAt(p, '0');
}
whatever = sb.toString();
This code will change the value of the character in position p, and then convert it back to a String.
Basic StringBuilder usage with a ternary operator produces what you're looking for:
StringBuilder result = new StringBuilder();
result.append(whatever.substring(0, p));
result.append(whatever.charAt(p) == '0' ? "1" : "0");
result.append(whatever.substring(p + 1, whatever.length()));
System.out.println("Result = " + result.toString());
As others have noted, using the StringBuilder.setCharAt() method produces a more concise answer (with the ternary operator added, this is the shortest answer so far):
StringBuilder result = new StringBuilder(whatever);
result.setCharAt(p, whatever.charAt(p) == '0' ? '1' : '0');
System.out.println("Result = " + result.toString());
Strings in Java are immutable so you need to first convert them to some mutable structure before modifying them.
If you are trying to flip the characters at some position in a code then this code might be of help :
String whatever = "11111";
char[] charArray = whatever.toCharArray();
int n = whatever.length();
//the UI class generates a random integer number between 0 and n
int p = CS2004.UI(0,n);
if (charArray[p]=='0') {
charArray[p] = 1;
} else {
charArray[p] = 0;
}
Then you can modify whatever characters you wish to. Once you are done you can reconstruct a String from the charArray as follows :
String result = new String(charArray);
This can also be achieved using StringBuilder.

Getting the last integer from a string

Say I have a string 3 + 4 = 7 or 23 - 4 = 19. I'm wondering how I would go about getting the last integer from the string so that it can be compared to another int.
Ive used this code:
int first = Integer.parseInt(str.substring(0, str.indexOf(" ")));
int second = Integer.parseInt(result.substring(result.indexOf('+')+1 , result.indexOf('=')));
to get the first and second integers for computation, but I can't seem to get the last integer in string when I'm using the method above. Is it just something I'm doing wrong or is there something else I need to do?
I also cannot use arrays, regex, try/catch, or a SystemTokenizer.
And my strings will not always be in the a + b = c format with the spaces or a single digit integer.
the strings are taken from a text file that is imported by the scanner. Here's a sample of the equations in the file:
11 - 2 = 9
12 - 1 = 11
7 + 1 = 8
7 - 3 = 4
7 + 2 = 9
14 + 4 = 18
If all of your strings are in this format - a + b = c, then there is a simple way -
String[] parts = str.split("=");
String lastDigit = parts[parts.length - 1].trim();
int last = Integer.parseInt(lastDigit);
Check out the docs.
Update
As per your requirement of not wanting to use regex, you can do something like this -
public int getLastDigit(String expression) {
StringBuffer result = new StringBuffer();
for (int i = expression.length() - 1; i >= 0; i--) {
char c = expression.charAt(i);
if (c == '=') {
break;
}
else {
result.append(c);
}
}
return Integer.parseInt(result.reverse()
.toString()
.trim());
}
int last = getLastDigit("1 + 3 = 14");
System.out.println(last); // will print 14
This will work a lot easier:
String[] tokens = str.Split(" ");
int first = Integer.parseInt(tokens[0]);
int second = Integer.parseInt(tokens[1]);
int last = Integer.parseInt(tokens[3]);
Otherwise without arrays, use lastIndexOf:
int last = Integer.parseInt(str.substring(str.lastIndexOf(" "), str.length()));
simple use split and get index[1] to get last integer in string
just split with "="
Does this work?
int last = Integer.parseInt(str.substring(str.indexOf("=") + 1, str.length));
The idea is to get the index of the "=", and then parse the substring of there to the end.
I did "str.indexOf("=") + 1" so that it didn't include the "sign".
String [] tokens = str.split("=");
String finalDigit = tokens[tokens.length-1];
You would need trim the extracted digit, other wise it is possible to throw
Exception in thread "main" java.lang.NumberFormatException: For input
string: " 7"
To extract the last digit, you may follow the below code
String str1="3 + 4 = 7";
String str2= str1.substring(str1.lastIndexOf("=")+1).trim();
int i = Integer.parseInt(str2);
import java.io.*;
class GetString{
publice static void main(String []args)
{
string str,int x;
Scanner s = new Scanner(input).useDelimiter("\n"); //take each line
while((str=s.next())!=NULL)
{
str.trim();
int first = Integer.parseInt(str.substring(0, str.indexOf(" ")));
//Depending on weather the sign is '+' or '-' it will take the index of that
int second = Integer.parseInt(str.substring((x=str.indexOf('+')>-1?
str.indexOf('+'):str.indexOf('-'))+1 , result.indexOf('=')));
int Third= Integer.parseInt(str.substring(str.indexOf("="), str.Length-1))
}
s.close();
}
}
Its a general idea not a perfect code.Edits and suggestions are welcome.

Categories

Resources