I am having a problem where when I am trying to calculate a scientific expression, it compiles however, it crashes when I run it. The way my program works is that it receives a string containing a mathematical expression which needs to be evaluated. Firstly, it is split into an ArrayList containing numbers and operators separately. It is then searched for any brackets which allows the program to work with the expressions within the brackets first. Then it calls calculate which calculates the answer. The error I keep receiving however is " Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsExcepton: Index:0, Size:0" I assume it has something to do with my sizes of the arraylist however, I cannot spot the error, can anyone else help me figure it out please? I believe the issue is most likely with the methods splitLabel and calculate
public ArrayList<String> splitLabel(String val){
ArrayList<String> label_split = new ArrayList<String>();
String value = "";
String op = "";
for (int i = 0; i< val.length(); i++){
boolean isDigit = Character.toString(val.charAt(i)).matches("[0123456789.]+");
boolean isOperator = Character.toString(val.charAt(i)).matches("[+*/^-]+");
boolean isSin = (Character.toString(val.charAt(i)).equals("s") && Character.toString(val.charAt(i+1)).equals("i") && Character.toString(val.charAt(i+2)).equals("n"));
boolean isCos = (Character.toString(val.charAt(i)).equals("c") && Character.toString(val.charAt(i+1)).equals("o") && Character.toString(val.charAt(i+2)).equals("s"));
boolean isTan = (Character.toString(val.charAt(i)).equals("t") && Character.toString(val.charAt(i+1)).equals("a") && Character.toString(val.charAt(i+2)).equals("n"));
boolean isOpBracket = Character.toString(val.charAt(i)).equals("(");
boolean isClBracket = Character.toString(val.charAt(i)).equals(")");
if (isOperator && !value.equals("")){
op = Character.toString(val.charAt(i));
label_split.add(value);
label_split.add(op);
op = "";
value = "";
} else if (isOperator && value.equals("")){
if (Character.toString(val.charAt(i)).equals("-")){
value = Character.toString(val.charAt(i));
}
} else if (isSin){
label_split.add("sin");
}else if (isCos){
label_split.add("cos");
}else if (isTan){
label_split.add("tan");
} else if (isOpBracket && !value.equals("")){
label_split.add(value);
label_split.add("(");
value = "";
} else if (isOpBracket && value.equals("")){
label_split.add("(");
} else if (isClBracket && !value.equals("")){
label_split.add(value);
label_split.add(")");
value = "";
}
if (i== val.length()-1 && !value.equals("")){
label_split.add(value);
} else if (i== val.length()-1 && Character.toString(val.charAt(i)).equals(")")){
label_split.add(")");
}
} return label_split;
}
public String bracket(ArrayList<String> label_split){
ArrayList<Integer> opBra = new ArrayList<Integer>();
ArrayList<Integer> clBra = new ArrayList<Integer>();
ArrayList<String> calculation = new ArrayList<String>();
int counter = 0;
int counter1 = 0;
if (label_split.contains("(") && label_split.contains(")")){
for (int j=0; j<label_split.size(); j++){
if (label_split.get(j).equals("(")){
counter = counter + 1;
opBra.add(j);
} else if (label_split.get(j).equals(")")){
counter1 = counter1 + 1;
clBra.add(j);
}
}
if (counter1 != counter){
return "error missing bracket";
} else {
for (int j=opBra.size(); j>0; j--){
int opBraPos = opBra.get(j) + 1; //+1 and -1 so it doesn't include ()
int clBraPos = clBra.get(opBra.size()-j) - 1;
opBra.remove(j);
clBra.remove(opBra.size()-j);
for(int t = 0; t < (clBraPos - opBraPos); t++){
calculation.add(label_split.get(t+opBraPos));
}
String value = calculate(calculation);
label_split.set(j , value);
calculation.clear();
for (int n = 0; n < ((clBraPos+1) - opBraPos); n++){
label_split.remove(n);
}
}
}
return calculate(label_split);
} else{
return calculate(label_split);
}
}
public String calculate(ArrayList<String> calculation){
double value = 0.0;
String value1 = "";
boolean isOperator = calculation.contains("[+*/^-]+");
boolean isSin = calculation.contains("sin"); //...ETC
for (int i=0; i < calculation.size(); i++){
if (calculation.get(i).equals("^") && i < calculation.size() && i < 0){
boolean isDigit1 = calculation.get(i-1).matches("[0123456789.-]+");
boolean isDigit2 = calculation.get(i+1).matches("[0123456789.-]+");
if (isDigit1 && isDigit2){
value = Math.pow(Double.parseDouble(calculation.get(i-1)), Double.parseDouble(calculation.get(i+1)));
value1 = Double.toString(value);
calculation.set(i,value1);
calculation.remove(i-1);
calculation.remove(i+1);
}
}
}
for (int a=0; a < calculation.size(); a++){
if ( (calculation.get(a)).equals("sin") && a < calculation.size() && a < 0){
boolean isDigit1 = calculation.get(a+1).matches("[0123456789.-]+");
if (isDigit1){
value = Math.sin(Double.parseDouble(calculation.get(a+1)));
value1 = Double.toString(value);
calculation.set(a,value1);
calculation.remove(a+1);
}
}
}
for (int b=0; b < calculation.size(); b++){
if ( (calculation.get(b)).equals("cos") && b < calculation.size() && b < 0){
boolean isDigit1 = calculation.get(b+1).matches("[0123456789.-]+");
if (isDigit1){
value = Math.cos(Double.parseDouble(calculation.get(b+1)));
value1 = Double.toString(value);
calculation.set(b,value1);
calculation.remove(b+1);
}
}
} // ETC
return calculation.get(0);
}
This is not your problem, but it certainly seems wrong:
calculation.set(i,value1);
calculation.remove(i-1);
calculation.remove(i+1);
The problem is that remove(i-1) is going to cause the index of everything from i onwards to be decremented by one. Then remove(i+1) is going to remove the element that was previously at index i+2.
Then there is this:
for (int i=0; i < calculation.size(); i++){
if (calculation.get(i).equals("^") &&
i < calculation.size() &&
i < 0) {
Think about it. If i starts at zero and is incremented up to size() which is non-negative, how can i ever be less than zero. And if i is never less than zero, how can the if test ever succeed. (You repeat this pattern in other places.)
However, the real problem is that somehow you are calling calculate on an empty list.
I think it is time that you learned to use a debugger .....
Related
I write this code but I don't know why doesn't work.
static boolean findeText(String text1, String text2) {
char c1[] = text1.toCharArray();
char c2[] = text2.toCharArray();
boolean b = false;
for (int i = 0; i <= c1.length - c2.length; i++) {
for (int j = 0, h = i; j <= c2.length; j++, h++) {
if (i == c2.length) {
return true;
}
if (c1[h] != c2[j]) {
b = false;
break;
}
}
}
return b;
}
I want find text 2 in text 1 and after that return true or false.
if you want to check if some string contains any other string, just use contains() method.
In your case that would be
return text1.contains(text2);
Plus you should always write your code in defensive way. That means you should always make sure there will be no NullPointerException etc. So in your particular case if someone pass either null text1 or null text2, your program will crash.
Above you had NPE in line
if (c1[h] != c2[j])
I have modified your code slightly to get output as requirement.
static boolean findeText(String text1, String text2) {
if ((text1== null) ||(text2==null) || (text1.isEmpty()) || (text2.isEmpty())) {
System.out.println("Invalid input");
return false;
}
char c1[] = text1.toCharArray();
char c2[] = text2.toCharArray();
for (int i = 0; i <= c1.length - c2.length; i++) {
int count = 0;
for (int j = 0; j < c2.length; j++) {
if (c1[i + j] == c2[j]) {
count = count + 1;
}
if (count == c2.length) {
return true;
}
}
}
return false;
}
I'm currently writing a HugeInteger class that can take in 40 digits, and I have a few comparison tests that are already written. The thing I'm having most trouble with is adding and subtraction methods. I was able to get two values to add, but don't know how to implement a negate function if one of the values are negative. My subtraction method doesn't seem to work either.
public void add(HugeInteger hi) {
if (digits[NUM_DIGITS] < 0) {
negate();
this.subtract(hi);
}
int carry = 0;
for(int i = digits.length-1; i >=0 ;i--) {
int cur = this.digits[i] + hi.digits[i] + carry;
if (cur >= 10){
cur= cur-10;
resultAdd[i] = cur;
carry = 1;
} else{
resultAdd[i] = cur;
carry = 0;
}
}
StringBuilder builder = new StringBuilder();
int j=0;
for (int i : resultAdd) {
builder.append(i);
this.digits[j] = i;
j++;
}
this.hi = builder.toString().replace("0", "");
}
public void subtract(HugeInteger hi) {
for(int i = digits.length-1; i >=0 ;i--) {
if (this.digits[i] - hi.digits[i] < 0){
this.digits[i-1]--;
this.digits[i]+=10;
}
int cur = this.digits[i] - hi.digits[i];
this.digits[i] = cur;
}
StringBuilder builder = new StringBuilder();
int j=0;
for (int i : resultAdd) {
builder.append(i);
this.digits[j] = i;
j++;
}
this.hi = builder.toString().replace("0", "");
}
public void negate() {
if(this.positive){
this.positive = false;
} else{
this.positive = true;
this.hi = this.hi.replace("-", "");
}
}
So I'm writing a mersense script for codeeval in java to get some practice with the language (I'm fairly new to it). At one point I'm checking if the number is prime and in my method I do the normal checks and everything looks great
public static boolean isPrime (int testValue){
if (testValue < 4){
return true;
} else if (testValue % 2 == 0){
return false;
} else {
for (int I = 1; I < Math.sqrt (testValue); I++){
if (testValue % I == 0 ){
return false;
}
}
return true;
}
}
however the only things getting through seem to be 1 and 3. Can I not do that return after the for loop is that what's wrong? Any ideas?
Edit:
Here is the full code:
import java.io.*;
import java.lang.Math;
public class Main{
public static void main(String[] args) throws IOException {
File file = new File(args[0]);
BufferedReader buffer = new BufferedReader(new FileReader(file));
String line;
int n;
StringBuilder result = new StringBuilder();
int candidate;
while((line = buffer.readLine()) != null){
n = Integer.parseInt(line.trim());
for(int i = 1; i < n; i++){
candidate = mersenne(i);
if(isPrime(candidate)){
System.out.println(candidate + " "+ isPrime(candidate));
if((i+1) >= n){
result.append(candidate);
}else{
result.append(candidate + ", ");
}
}
}
System.out.println(result.toString());
result = new StringBuilder();
}
}
public static int mersenne (int testValue){
return (int)Math.pow(2,testValue) - 1;
}
public static boolean isPrime(int testValue){
if(testValue < 4 && testValue > 1){
return true;
}else if(testValue % 2 == 0){
return false;
}else{
for(int i = 3; i <= Math.sqrt(testValue); i++){
if(testValue % i == 0){
return false;
}
}
return true;
}
}
}
You're starting the loop at 1. Everything % 1 is 0. Start at 3.
your code in the else block:
for (int I = 1; I < Math.sqrt (testValue); I++){
if (testValue % I == 0 ){
return false;
}
}
you should start with I=3:
for (int I = 3; I < Math.sqrt (testValue); I++)
Since every number % 1 equals to 0 so false will be returned.
Array Processing
Hi! I need to create a boolean method that processes two strings and returns if one is a subset of another. Example
if AAC is a subset of AAABBCK return true/
I currently have
for (int i = 0; i < shorterArray.length; i++) {
for (int j = 0; j < longerArray.length; j++) {
if longerArray[j] == shorterArray[i] {
count++
}
}
if (count == shorterArray.length) {
return true
) else {
return fasle;
}
}
However this doesn't take into account the repetitions
return longerString.indexOf(shorterString) > -1;
Never mind, thanks to Joachim for correcting me on the definition of subset. Now I have to provide the correct answer.
public boolean isSubset(String subset, String superset)
{
boolean[] used = new boolean[superset.length()];
iLoop:
for (int i = 0; i < subset.length(); i++) {
for (int j = 0; j < superset.length(); j++) {
if (!used[j] && subset.charAt(i) == superset.charAt(j)) {
used[j] = true;
continue iLoop;
}
}
return false;
}
return true;
}
If you can use the built in methods within the String class :
String input="your input string with substring";
CharSequence findMe="substring";
boolean retval = input.contains(findMe);
I have variable number of input values.
Like input is an array with variable values like [6,23,6] or [8,3,97].. like that and also i need to check it against another array.
Hence, I form a condition like this,
StringBuilder formStmt= new StringBuilder("");
for (int i = 0; i < input.size(); i++) {
formStmt= formStmt.append("input[" + i + "] != anotherArray[" +i+ "] &&");
}
formStmt= formStmt.delete(formStmt.length()-2, formStmt.length());
How to check formStmt inside if?
The Thing is I'm forming the if statement using formStmt. I'm forming
formStmt = input[0] !=anotherArray[i] && input[1] != anotherArray[i]
and placing it inside if.. like
if (formStmt){
//code
}
Edit:
I have updated the question. The right side value also is an array. Thats why I go for a stmt like this.?
as far as I understand, you want to check every input[i]'s value against 0. try this :
bool status=true;
for (int i = 0; i < input.size(); i++) {
if(input[i] == 0)
{
status=false;
break;
}
}
if(status)
{ // do your stuff}
so according to your updated question, you will need a nested loop. something like this :
bool status=true;
for (int i = 0; i < input.length && status; i++)
{
for(j = 0; j < anotherArray.length; j++)
{
if(input[i] == anotherArray[j])
{
status=false;
break; // you can use a labeled break if you want
}
}
if(status)
{ // do your stuff}
Don't build up code in a String.
You want to check that all of the elements of the Collection are non-zero.
boolean valid = true;
for (int i = 0; i < input.size(); i++) {
if (input.get(i) == 0) {
valid = false;
break;
}
}