Weird IndexOutofBoundsException? - java

why is there an IndexOutofBoundsException? It seems as if there is no variable that index may be out of bounds. This program is supposed to convert patterns. Could this have something to do with how I read my file? Thanks.
static int checkNestedParenFront(String line){
int count=0;
for(int i=0;i<line.length();i++ ){
if(line.charAt(i)=='(')
count++;
if(line.charAt(i)==')'&&count==0)
return i;
if(line.charAt(i)==')')
count--;
}
return 0;
}
String line = new String(Files.readAllBytes(Paths.get("new.txt")));
PrintWriter writer = new PrintWriter("old.txt");
while(line.contains("F_4")){
while(line.contains("$F_4$")) {
line=line.replace("$F_4$", "$\\AppellFiv");
}
int posAppell = line.indexOf("F_4");
int posSemi = line.indexOf(';', posAppell);
posSemi = line.indexOf(';', posSemi);
int posComma = line.indexOf(',', posSemi);
String check = line.substring(posComma+1);
int i = checkNestedParenFront(check);
String lastAppel = line.substring(posComma, i);
String beforeAppel=line.substring(0, posComma);
String afterAppel = line.substring(i+1);
line = line.replaceAll("F_4[^(]*\\(([^,]+),([^;]+);([^,]+),([^;]+);([^,]+),", "\\AppellFiv#{$1}{$2}{$3}{$4}{$5}");
line = beforeAppel + "{" + lastAppel + "}" + afterAppel;
}

Your problem is that when you call checkNestedParenFront(check), you're returning the count in check of that last parenthesis, which is not the same as the count in line, because check starts partway through line.
Then when you call line.substring(posComma, i), you have i less than posComma, and that causes the exception.
I think you mean to have line.substring(posComma, posComma + i + 1) - but I'm not quite sure about the +1, since it's not clear exactly what you're trying to achieve.

Related

Count Words Using indexOf

I can't use arrays, only simple Java (if, for, while, substring, length, indexOf)
public int howManyWords(String s){
myString = "I have a dream";
int count = 1;
int length = 0;
while(count>=0){
count = myString.substring(String.valueOf(length),myString.indexOf(" "));
count++;
length = myString.indexOf(" ");
}
return count;
}
Should return 4
First of all, you made infinite loop, because count is 1, and you just increase it.
Second, you haven't even try to write this code in some IDE, because it would throw you a syntax error, because you are assigning string to int, when you do count = myString.substring()
So, instead of using count in loop, you can use myString.indexOf
something like this could work if you don't care what is going to happen with myString
int count = 0;
while(myString.indexOf(" ") >= 0) {
count++;
myString = myString.substring(myString.indexOf(" ") + 1)
}
return count;
Let's assume that the string you are testing does not contain leading or trailing spaces, because that affects the solution. The example string in your question does not contain leading or trailing spaces.
Simply call method indexOf(String, int) in a loop and in each iteration you set the int parameter to one more than what you got in the previous iteration. Once the value returned by method indexOf() is -1 (minus one), you are done. But don't forget to add the last word after you exit the loop.
String myString = "I have a dream";
int count = 0;
int index = 0;
while (index >= 0 && index < myString.length()) {
index = myString.indexOf(" ", index);
System.out.println("index = " + index);
if (index >= 0) {
index++;
count++;
}
}
if (index < 0) {
count++;
}
System.out.println("count = " + count);
Edited : Added missing else case.
Try the following code :
Remove the counted words from your string using the substring and indexOf, and increment the count in each iteration.
public int countWords(String s){
String myString = "I have a dream";
int count = 0;
int length = myString.length();
while(length>0){
if((myString.indexOf(" ")!=-1) && (myString.indexOf(" ")+1)<length){
myString = myString.subString(myString.indexOf(" ")+1);
count++;
length = myString.length();
}
else {
length = 0;
break;
}
}
return count;
}
PS: Conventionally, your method names should denote actions, hence I suggested it to be countWords instead of howManyWords.

Repeatedly removing a substring from a string

Problem: Remove the substring t from a string s, repeatedly and print the number of steps involved to do the same.
Example: t = ab, s = aabb. In the first step, we check if t is contained within s. Here, t is contained in the middle i.e. a(ab)b. So, we will remove it and the resultant will be ab and increment the count value by 1. We again check if t is contained within s. Now, t is equal to s i.e. (ab). So, we remove that from s and increment the count. So, since t is no more contained in s, we stop and print the count value, which is 2 in this case.
I tried to solve this using recursion
static int maxMoves(String s, String t) {
if ( null == s || "" == s || null == t || "" == t){
return 0;
}
int i = s.indexOf(t);
if(i != -1) {
return maxMoves(s.substring(0, i)+ s.substring(i+t.length(), s.length()), t) + 1;
} else {
return 0;
}
}
But I am only passing 9/14 test cases. I also tried this,
static int maxMoves(String s, String t) {
int count = 0,i;
while(true)
{
if(s.contains(t))
{
i = s.indexOf(t);
s = s.substring(0,i) + s.substring(i + t.length());
}
else break;
++count;
}
return count;
}
But that also only passed 9/14 cases.
Could anyone help me figure out which cases I am not covering?
Simply you can use String::replaceFirst with a while loop for example:
String s = "aabb";
String t = "ab";
int count = 0;
while (s.contains(t)) {
s = s.replaceFirst(Pattern.quote(t), "");
count++;
}
System.out.println(count);
Use String#replace
String s = "aabb";
String oldstr = s;
String x = "ab";
while(s.contains(x)){
s = s.replace(x, "");
}
System.out.println((oldstr.length()-s.length())/x.length());
An easy and efficient way is to accumulate the string character-by-character in a StringBuilder; if at any time its buffer ends with the string you want to replace, remove it:
StringBuilder sb = new StringBuilder();
int c = 0;
for (int i = 0; i < s.length(); ++i) {
sb.append(s.charAt(i));
int last = sb.length()-t.length();
if (last >= 0 && sb.indexOf(t, last) == last) {
sb.setLength(last);
++c;
}
}
// c is now the number of times you removed t from s.

Any idea why this scanner read next won't work

I am trying to make an Array that starts at an initial size, can have entries added to it. (I have to use an Array). To print the Array I have to following code :
public String printDirectory() {
int x = 0;
String print = String.format("%-15s" + "%-15s" + "%4s" + "\n", "Surname" , "Initials" , "Number");
// Sorts the array into alphabetical order
// Arrays.sort(Array);
while ( x < count ){
Scanner sc = new Scanner(Array[x]).useDelimiter("\\t");
secondName[x] = sc.next();
initials[x] = sc.next();
extension[x] = sc.next();
x++;
}
x = 0;
while ( x < count){
print += String.format("%-15s" + "%-15s" + "%4S" + "\n", secondName[x] , initials[x] , extension[x]);
x++;
}
return print + "" + Array.length;
}
Please ignore the extra Array.length, on the return statement.
Anyways this is working fine, firstly the Array reads a file which is formated like NameInitialsnumber on each line.
So I tried making a newEntry method and it causes problems when I want to print the Array. When I add a new entry, if the Array is too small, it will make the array bigger and add the entry. I made methods to make sure this worked and it does work. The following code for this method is:
public void newEntry(String surname, String in, String ext) {
if (count == Array.length) {
String entry = surname + "\t" + in + "\t" + ext;
int x = Array.length + 1;
String[] tempArray = new String[x];
System.arraycopy(Array, 0, tempArray, 0, Array.length);
Array = tempArray;
Array[count] = entry;
Arrays.sort(Array);
} else {
String entry = surname + "\t" + in + "\t" + ext;
Array[count] = entry;
Arrays.sort(Array);
}
count++;
}
The problem is when I then call the printDirectory method it has problems with sc.next(). The error message is as follows:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7
at ArrayDirectory.printDirectory(ArrayDirectory.java:106)
at ArrayDirectory.main(ArrayDirectory.java:165)
Im really new to coding and im not sure what is wrong. I know its something wrong with the new entry but im not sure what. Really grateful for any help. Thanks.
It seems that your other arrays secondName, initials, and extension are not large enough.
You need to make them bigger as well. Or even better, when you think a bit about it you will recognize that you do not need them at all.

get string between parentheses [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Regular Expression to find a string included between two characters, while EXCLUDING the delimiters
I'm using a method called Interpreter.eval() of external library "beanshell" that allows to make math operations with Strings and return the solution.
It works fine, but if I want to raise to the second power or get a square root out of this I have to modify the original String that is like
String st ="x = 2+4*a*(b+c)^2"
I need to get the charaters between parentheses to replace "(b+c)^2" to "(b+c)*(b+c)" or "Math.pow((b+c),2)"
How can I do this?
Thanks in advance!
----edit----
Finally I found the solution.
Interpreter interpreter = new Interpreter();
String st = "x = 2+4*1*(2*(1+1)^2)^2 + (4+5)^2";
int index = -2;
char prev;
char post;
int openPar = -1;
if (st.contains("^")) {
index = st.indexOf("^");
while (index != -1) {
prev = st.charAt(index - 1);
post = st.charAt(index + 1);
if (prev == ')') {
int match = 0;
int i = index - 2;
char check = '0';
boolean contiunar = true;
while (contiunar) {
check = st.charAt(i);
if (check == ')')
match++;
if (check == '(') {
if (match == 0) {
openPar = i;
contiunar = false;
} else
match = match - 1;
}
i = i - 1;
}
String rep = st.substring(openPar + 1, index - 1);
String resultado = "";
try {
interpreter.eval("r= Math.pow(" + rep + "," + post
+ ")");
resultado = interpreter.get("r").toString();
} catch (EvalError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
st = st.replace("(" + rep + ")^" + post, resultado);
} else {
st = st.replace(prev + "^" + post, prev + "*" + prev);
}
index = st.indexOf("^");
}
}
With this I modified the original String x = 2+4*1*(2*(1+1)^2)^2+(4+5)^2 (for example)
to x=2+4*1*64+81
first it search the first "^"
get previous char
and if there are ")"
search previous char while finds "(" But if finds ")" before of "(" has to find 2 "("; one to open internal parentheses and the second open the parentheses I want to pow.
This is in case of "(2+(3+4)+5)^2" ---> return "2+(3+4)+5" instead of "3+4)+5".
now replace to correct expresion Math.pow("result","2")" and calculate step by step
(1+1)^2 = 4
(2*4)^2 = 64
(4+5)^2 = 81
finally now I can calculate the retun with Interpreter.eval()
Thanks a lot for the answers!
try the following code to do your task
String originalString ="x = 2+4*a*(b+c)^2";
String stringToInsert = "Math.pow((b+c),2)";
int startIndex = originalString.indexOf("(");
int endIndex = originalString.indexOf(")");
String firstPortion = originalString.substring(0,startIndex);
String lastPortion = originalString.substring(endIndex+1);
String finalString = firstPortion + stringToInsert + lastPortion;
System.out.println("finalString : "+finalString);
You will need to parse the string. You could write a complete parser and go through it character by character.
Otherwise, if there is a specific flowchart you have in mind (using the operators), use the String.split(\"*(...) functionality where you can essentially create tokens based on whatever your delimeters are.
Hope this helps.
Of course you need to parse the String. You can convert it to intermediate state ( which you can execute after very quickly) . You can see the following link maybe it can help you http://en.wikipedia.org/wiki/Reverse_Polish_notation

Java JTextArea multiline help

one problem I'm having is i have 2 JTextAreas and i need to add a list of items to them.
The problem I'm running into is the string doesn't automatically move to the next line when it reaches the end of the JTextArea. So to solve this problem I tried this: (sorry if my code is kinda sloppy.)
public void setIncludeAndExclude(ArrayList<JComboBox> boxes){
String in = "",ex = "";
String[] inSplit, exSplit;
boolean[] include = new boolean[boxes.get(0).getModel().getSize()-1];
for(int i = 0; i < boxes.size(); i ++){
if(boxes.get(i).getSelectedIndex() != 0){
include[boxes.get(i).getSelectedIndex() -1] = true;
}
}
for(int i = 0; i < include.length; i ++){
if(include[i]){
//numToItem is a method that turns an int into a string e.g. 1 = "Acesss Doors"
in += (numToItem(i+1)+ ", ");
}else{
ex += (numToItem(i+1)+ ", ");
}
}
//take off the last comma
in = in.substring(0,in.lastIndexOf(","));
ex = ex.substring(0,ex.lastIndexOf(","));
//get how many lines there should be
inSplit = new String[(in.length()/100) +1];
exSplit = new String[(ex.length()/100) +1];
String temp;
int istart = 0, iend = Math.min(100, in.length()), estart = 0, eend = Math.min(100, ex.length());
for(int i = 0; i < inSplit.length; i ++){
try{
temp = in.substring(istart, iend);
int Iindex = temp.lastIndexOf(",");
temp = ex.substring(estart, eend);
int Eindex = temp.lastIndexOf(",");
inSplit[i] = in.substring(istart, Iindex);
exSplit[i] = ex.substring(estart, Eindex);
istart = Iindex; iend = Math.min(iend + 100, in.length());
estart = Eindex; eend = Math.min(eend + 100, ex.length());
}catch(Exception e){
e.printStackTrace();
}
}
//reset in and ex to ""
in = ""; ex = "";
//set in and ex to the new string with newline characters
for(int i = 0; i < inSplit.length; i ++){
in += inSplit[i] + "\n";
ex += exSplit[i] + "\n";
}
//set the text of the JTextAreas
Include.setText(in);
Exclude.setText(ex);
}
any help on what i could do different or change would be much appreciated
JTextArea has setLineWrap(...) and the setWrapStyleWord(...) methods. Perhaps all you need to do is call these on your JTextArea's setting both to true.
One bit of criticism: your code is very hard to interpret as you give no indication which variables are JTextAreas (which I'm guessing are "Include" and "Exclude"), and no comments as to what is doing what. Please write your questions here with the idea that we know nothing about your code and can't read minds. The clearer your question, usually the easier it is to answer. Thanks.
Maybe a better solution is to use JList. See How to Use Lists.
The code you posted is not complete. If you still want to use a text area solution then post your SSCCE that demonstrates the problem.

Categories