This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 6 years ago.
For input (1+3)*(1+3) I'm getting 1 3 + * 1 3 + for output, when it should be 1 3 + 1 3 + *. I have debugged and cannot figure out why multiplication does not hold until the end. Am I not comparing it the right way in checkOp()?
public String infixToPostfix() throws StackEmptyException{
Stack<String> s = new Stack<String>();
String expression = jtfInfix.getText();
String delims = "+-*/()123456789 ";
StringTokenizer strToken = new StringTokenizer(expression, delims, true);
String result = "";
while(strToken.hasMoreTokens()){
String token = strToken.nextToken();
if(token.equals("(")){
s.push(token);
}
else if(token.equals(")")){
while(s.peek().equals("(") != true){
result += " " + s.pop();
}
}//first elseif
else if (checkOp(token)){
if(s.isEmpty() == true) {
s.push(token);
}
else {
if(getOrder(token) < findOrder(s.peek())) {
result += " " + s.pop();
s.push(token);
}
else {
s.push(token);
}
}
}
else {
result += " " + token;
}
}
while(s.isEmpty()) {
result += s.pop();
}
return result;
}// infixToPostFix()
public int findOrder(String token) {
int order = 0;
if((token.equals("+")) || (token.equals("-"))) {
order = 1;
}
else if((token.equals("*")) || (token.equals("%"))) {
order = 2;
}
else if(token.equals(")")) {
order = 0;
}
return order;
}
public int getOrder(String token) {
int order = 0;
if((token.equals("+")) || (token.equals("-")) ) {
order = 1;
}
else if((token.equals("*")) || (token.equals("%")) ) {
order = 2;
}
return order;
}
private boolean checkOp(String token) {
return ((token.equals("+")) || (token.equals("-")) || (token.equals("*")) ||
(token.equals("%")) );
}
There are a couple of errors
First you need to pop the parenthesis once it has been matched
while(s.peek().equals("(") != true){
result += " " + s.pop();
}
s.pop(); // pop the matching left parenthesis
and you want to pop everything off the stack once you have finished
while(s.isEmpty()) {
result += s.pop();
}
should be
while(!s.isEmpty()) {
result += " " + s.pop();
}
as a comment logging is helpful to see what is happebing.
Related
I'm trying to figure out how to do the different traversals through an expression tree. For example, if I type in " - + 10 * 2 8 3 ", I want it to print out the prefix, postfix, and infix versions of that expression.
I also need to calculate the result of the expression through a postorder traversal, which should be the evaluate function.
However, when I run my program, I only get the first character of each expression. Is my understanding of how these traversals work wrong?
EDIT: Following suggestions, I saved the result of the buildtree and also changed sc.next to sc.nextLine.
Also, every method should be recursive.
Given "- + 10 * 2 8 3", the expected answer would be:
prefix expression:
- + 10 * 2 8 3
postfix expression:
10 2 8 * + 3 -
infix expression:
( ( 10 + ( 2 * 8 ) ) - 3 )
Result = 23
I understand I haven't implemented anything with parentheses for the infix expression, but that's okay for now.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter a prefix expression: ");
Node root = buildTree(sc);
System.out.println("prefix expression: ");
infix(root);
System.out.println("postfix expression: ");
postfix(root);
System.out.println("infix expression: ");
infix(root);
System.out.print("Result = ");
evaluate(root);
}
static Node buildTree(Scanner sc) {
Node n = new Node(null);
int i = 0;
String prefixExpression = sc.nextLine();
String[] temp = prefixExpression.split(" ");
if(n.isLeaf()) {
n.value = temp[i];
n.left = null;
n.right = null;
i++;
}
return n;
}
static void infix(Node node) {
if(node.isLeaf()){
System.out.println(node.value);
}
else {
infix(node.left);
System.out.println(node.value + " ");
infix(node.right);
}
}
void prefix(Node node) {
if(node.isLeaf()){
System.out.println(node.value);
}
else {
switch(node.value) {
case "+":
System.out.print("+");
break;
case "-":
System.out.print("-");
break;
case "*":
System.out.print("*");
break;
case "/":
System.out.print("/");
break;
}
}
prefix(node.left);
System.out.print(" ");
prefix(node.right);
}
static void postfix(Node node) {
if(node.isLeaf()){
System.out.println(node.value);
}
else {
postfix(node.left);
postfix(node.right);
switch (node.value) {
case "+":
System.out.print("+");
break;
case "-":
System.out.print("-");
break;
case "*":
System.out.print("*");
break;
case "/":
System.out.print("/");
break;
}
}
}
public static int evaluate(Node node) {
if(node.isLeaf()) {
return Integer.parseInt(node.value);
}
else {
int leftHandSide = evaluate(node.getLeft());
int rightHandSide = evaluate(node.getRight());
String operator = node.getValue();
if("+".equals(operator)) {
return leftHandSide + rightHandSide;
}
else if("-".equals(operator)) {
return leftHandSide - rightHandSide;
}
else if("*".equals(operator)) {
return leftHandSide * rightHandSide;
}
else if("/".equals(operator)) {
return leftHandSide / rightHandSide;
}
else {
System.out.println("Unexpected problem. Error.");
}
return 0;
}
}
}
Here is Node.java, There's getters and setters too.
public class Node<E> {
String value;
Node<E> left;
Node<E> right;
Node(String value){
left = null;
right = null;
this.value = value;
}
Node(String value, Node<E> left, Node<E> right) {
this.value = value;
this.left = left;
this.right = right;
}
boolean isLeaf() {
return (left == null && right == null);
}
EDIT:
Since your question says "How to do different traversals of an expression tree?, The problem I can see in your code is building the tree ( i.e. buildTree() method).
In order to correct this, I have used buildExpressionTree(array) method to convert your prefix input to an expression tree using Stack data structure.
Construction of Expression Tree:
For constructing expression tree I have use a stack. Since in your case input is in prefix form so Loop in reverse through input expression and do following for every character.
If character is operand push that into stack
If character is operator pop two values from stack make them its
child and push current node again.
At the end only element of stack will be root of expression tree.
Also while printing different traversals, you do not need all those if conditions to check for different operators.You can simply do the traversal as shown in my code below.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a prefix expression: ");
String prefixExpression = sc.nextLine();
String[] temp = prefixExpression.split(" ");
Node n = null;
n = buildExpressionTree(temp);
System.out.println("prefix expression: ");
prefix(n);
System.out.println();
System.out.println("postfix expression: ");
postfix(n);
System.out.println();
System.out.println("infix expression: ");
infix(n);
System.out.println();
int result = evaluate(n);
System.out.print("Result = "+ result);
}
static Node buildExpressionTree(String[] input) {
Stack<Node> st = new Stack();
Node t, t1, t2;
// Traverse through every character of
// input expression
for (int i = (input.length-1); i >= 0; i--) {
// If operand, simply push into stack
if (isNumber(input[i])) {
t = new Node(input[i]);
st.push(t);
} else // operator
{
t = new Node(input[i]);
// Pop two top nodes
// Store top
t1 = st.pop(); // Remove top
t2 = st.pop();
// make them children
t.left = t1;
t.right = t2;
st.push(t);
}
}
t = st.peek();
st.pop();
return t;
}
static boolean isNumber(String s) {
boolean numeric = true;
try {
Integer num = Integer.parseInt(s);
} catch (NumberFormatException e) {
numeric = false;
}
return numeric;
}
static void infix(Node node) {
if( null == node) {
return;
}
infix(node.left);
System.out.print(node.value + " ");
infix(node.right);
}
static void prefix(Node node) {
if( null == node) {
return;
}
System.out.print(node.value+ " ");
prefix(node.left);
prefix(node.right);
}
static void postfix(Node node) {
if( null == node) {
return;
}
postfix(node.left);
postfix(node.right);
System.out.print(node.value+ " ");
}
public static int evaluate(Node node) {
if(node.isLeaf()) {
return Integer.parseInt(node.value);
}
else {
int leftHandSide = evaluate(node.left);
int rightHandSide = evaluate(node.right);
String operator = node.value;
if("+".equals(operator)) {
return leftHandSide + rightHandSide;
}
else if("-".equals(operator)) {
return leftHandSide - rightHandSide;
}
else if("*".equals(operator)) {
return leftHandSide * rightHandSide;
}
else if("/".equals(operator)) {
return leftHandSide / rightHandSide;
}
else {
System.out.println("Unexpected problem. Error.");
}
return 0;
}
}
OUTPUT:
Enter a prefix expression:
- + 10 * 2 8 3
prefix expression:
- + 10 * 2 8 3
postfix expression:
10 2 8 * + 3 -
infix expression:
10 + 2 * 8 - 3
Result = 23
So while I was typing this question, I found a workaround for a "missing return statement" error. But I still don't think this is the proper way of doing it. As you can see I have some nested if statements. I want both conditions to be met before returning anything, but I had to place the return statements outside of the nested if statements. If the last condition isn't met doubt this should cause much problem since an empty string will be returned, but I just feel as if this isn't the best way of going about doing things.
1st Edit: with my current update, i'm still missing a return statement. I could do the same fix i applied but I feel as if it is innapropriate.
public String findProtein(String dna) {
int start = dna.indexOf("atg");
int stop1 = dna.indexOf("tag", start + 3);
int stop2 = dna.indexOf("tga", start + 3);
int stop3 = dna.indexOf("taa", start + 3);
String subStr1 = dna.substring(start, stop1);
String subStr2 = dna.substring(start, stop2);
String subStr3 = dna.substring(start, stop3);
boolean geneFound = false;
if (subStr1.length() % 3 == 0) {
geneFound = true;
return subStr1;
}
if (geneFound == false) {
if (subStr2.length() % 3 == 0) {
geneFound = true;
}
return subStr2;
}
if (geneFound == false) {
if (subStr3.length() % 3 == 0) {
geneFound = true;
}
return subStr3;
}
if (geneFound == false) {
return "";
}
}
2nd Edit: additional code
private void stopCodon(String gene){
//This prints out the last 3 characters of the gene
String stopCodon = gene.substring(gene.length() - 3);
System.out.println(stopCodon);
}
public void testing() {
String a = "ataaactatgttttaaatgt";
String result = findProtein(a);
stopCodon(result);
}
If it were me, I would edit the following logic
if( subStr1.length() % 3 ==0 ){
geneFound = true;
return subStr1;
}
if(geneFound == false){
if(subStr2.length( )% 3 ==0 ){
geneFound = true;
}return subStr2;
}
if(geneFound == false){
if(subStr3.length( )% 3 ==0 ){
geneFound = true;
}
return subStr3;
}
if (geneFound == false){
return "";
}
To the following using else if statements:
if( subStr1.length() % 3 ==0 ){
return subStr1;
} else if (substr2.length()%3==0){
return substr2;
} else if (substr3.length()%3 == 0) {
return substr3;
} else {
return null;
}
I'm also not sure if String subStr1 = dna.substring(start,stop1); is something you want since an Exception will be thrown if the stop codon doesn't exist, but it would be hard to judge without you giving us additional information.
Added
Kind of saw this coming, but if you look at the description for indexOf
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int)
the index of the first occurrence of the character in the character sequence represented by this object, or -1 if the character does not occur.
If you want to check if the substring exists, you check if the index is -1
I'm only gonna go through an example for the first substring
int stop1 = dna.indexOf("tag", start + 3);
if(stop != -1) {
return dna.substring(start, stop1);
}
You should start by checking if the start codon exists at all and return null if it doesn't exist immediately, since locations of stop codons are useless without start codons.
Hopefully this helps
if( subStr1.length() % 3 ==0 ){
geneFound = true;
result = subStr1;
}else if(geneFound == false){
if(subStr2.length( )% 3 ==0 ){
geneFound = true;
}
result = subStr2;
}else if(geneFound == false)
if(subStr3.length( )% 3 ==0 ){
geneFound = true;
}
result = subStr3;
}
if (geneFound == false){
result = "";
}
return result;
result is of type String.
However any one of three if statements will return the value. If not fourth if statement will return the value.
You can assign the result to a variable and return it at the end
Why don't you return something like this ?
public String findProtein(String dna) {
String valueToBeReturned = "";
if(condition 1){
valueToBeReturned = "value1"
}
if(condition 2){
valueToBeReturned = "value2"
}
//Rest of the conditions
return valueToBeReturned; //Finally return the specific value
}
How about remove unnecessary block of code?
if (geneFound == false) {
return "";
}
Since you return a value and the boolean is a local variable, it doesn't really matter if you change the boolean value or not in this code. I really don't see a use for it at the time. I simplified the code following your logic!
public String findProtein(String dna) {
int start = dna.indexOf("atg");
int stop1 = dna.indexOf("tag", start+3);
int stop2 = dna.indexOf("tga",start+3);
int stop3 = dna.indexOf("taa",start+3);
String subStr1 = dna.substring(start,stop1);
String subStr2 = dna.substring(start,stop2);
String subStr3 = dna.substring(start,stop3);
if(subStr1.length() % 3 == 0 ) {
return subStr1;
}
if(subStr2.length() % 3 == 0 ){
return subStr2;
}
if(subStr3.length( )% 3 ==0 ){
return subStr3;
}
return "";
}
I have a method getRPNString(), which returns Reverse Polish Notation string. I want to split this string by spacebars to calculate it. Now I can't understand how to add spacebars in my RNP string right, because it's not working with two digits numbers.
public class Calc1 {
public static void main(String[] args) {
String in = "((5+3*(4+2)*12)+3)/(1+3)+5";
String out = getRPNString(in);
System.out.println(out);
}
private static String getRPNString(String in) {
LinkedList<Character> oplist = new LinkedList<>();
StringBuilder out = new StringBuilder();
for (int i = 0; i < in.length(); i++) {
char op = in.charAt(i);
if (op == ')') {
while (oplist.getLast() != '(') {
out.append(oplist.removeLast());
}
oplist.removeLast();
}
if (Character.isDigit(op)) {
out.append(op);
/*int j = i + 1;
for (; j < in.length(); j++) {
if (!Character.isDigit(j)) {
break;
}
i++;
}
out.append(in.substring(i, j));*/
}
if (op == '(') {
oplist.add(op);
}
if (isOperator(op)) {
if (oplist.isEmpty()) {
oplist.add(op);
} else {
int priority = getPriority(op);
if (priority > getPriority(oplist.getLast())) {
oplist.add(op);
} else {
while (!oplist.isEmpty()
&& priority <= getPriority(oplist.getLast())) {
out.append(oplist.removeLast());
}
oplist.add(op);
}
}
}
}
while (!oplist.isEmpty()) {
out.append(oplist.removeLast());
}
return out.toString();
}
private static boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '%';
}
private static int getPriority(char op) {
switch (op) {
case '*':
case '/':
return 3;
case '+':
case '-':
return 2;
case '(':
return 1;
default:
return -1;
}
}
}
I tried to add spacebars by append(' ') in my StringBuilder variable out. But it' s not right with two digits. I think I totally do not understand how to make it.
For example if input is String in = "((5+3*(4+2)*12)+3)/(1+3)+5"; the out will be 5342+12+3+13+/5+, when I add spacebars to all calls out.append(' ')**out is **5 3 4 2 + * 1 2 * + 3 + 1 3 + / 5 +, so numbers like "12" became "1 2".
Can you help?
Just change the code that you have commented out, right after Character.isDigit(op) to:
int j = i + 1;
int oldI = i;//this is so you save the old value
for (; j < in.length(); j++) {
if (!Character.isDigit(in.charAt(j))) {
break;
}
i++;
}
out.append(in.substring(oldI, j));
out.append(' ');
I changed my method, now it works fine. I fonded my mistake when I wroted
!Character.isDigit(j) but need !Character.isDigit(in.charAt(j)).
private static String getRPNString(String in) {
LinkedList<Character> oplist = new LinkedList<>();
StringBuilder out = new StringBuilder();
for (int i = 0; i < in.length(); i++) {
char op = in.charAt(i);
if (op == ')') {
while (oplist.getLast() != '(') {
out.append(oplist.removeLast()).append(' ');
}
oplist.removeLast();
}
if (Character.isDigit(op)) {
int j = i + 1;
int oldI = i;//this is so you save the old value
for (; j < in.length(); j++) {
if (!Character.isDigit(in.charAt(j))) {
break;
}
i++;
}
out.append(in.substring(oldI, j));
out.append(' ');
}
if (op == '(') {
oplist.add(op);
}
if (isOperator(op)) {
if (oplist.isEmpty()) {
oplist.add(op);
} else {
int priority = getPriority(op);
if (priority > getPriority(oplist.getLast())) {
oplist.add(op);
} else {
while (!oplist.isEmpty()
&& priority <= getPriority(oplist.getLast())) {
out.append(oplist.removeLast()).append(' ');
}
oplist.add(op);
}
}
}
}
while (!oplist.isEmpty()) {
out.append(oplist.removeLast()).append(' ');
}
return out.toString();
}
Now it produce right expression.
Test: input: ((5+3*(4+2)*12)+3)/(1+3)+5
output : 5 3 4 2 + * 12 * + 3 + 1 3 + / 5 +
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have this really weird issue with my program and the test class provided. The goal is to return a string in the exact format provided. However, when I run the test class, it tells me my string is wrong, even though it is exactly the same as the string in the test class. I am not sure why it is coming up as an incorrect string, even though the string is correct. Thanks!
This is the class:
public class RecursionLinkedList
{
private Node firstNode;
private int numberOfEntries;
public RecursionLinkedList()
{
firstNode = null;
numberOfEntries = 0;
}
public void add(int aData)
{
if(numberOfEntries == 0)
{
firstNode = new Node(aData);
}
else
{
firstNode = new Node(aData, firstNode);
}
numberOfEntries++;
}
/**
* boolean contains(int aData)
*
* See whether this RecursionLinkedList contains aData
* #param aData a data to be located
* #return true if this RecursionLinkedList contains aData,
* or false otherwise.
*/
public boolean contains(int aData)
{
Node currentNode = firstNode;
if(currentNode == null) {
return false;
}
if(currentNode.data == aData) {
return true;
}
else {
return contains1(aData, currentNode);
}
}
/**
* int getFrequencyOf(int aData)
*
* Counts the number of times a given data appears in this
* RecursionLinkedList.
*
* #param aData the data to be counted
* #return the number of times aData appears in this RecursionLinkedList
*/
public int getFrequencyOf(int aData)
{
Node currentNode = firstNode;
int frequency = 0;
if(currentNode == null) {
return frequency;
}
else {
frequency = getFrequencyOf1(aData, currentNode);
return frequency;
}
}
/**
* String toString()
*
* Return a string representation of this RecursionLinkedList. For example,
* if this RecursionLinkedList contains 1, 2, 3, 5, 2 and 3 from the first
* index to the last index, the returned string should be
* "[1,2,3,5,2,3]"
* #return the string representation of this RecursionLinkedList.
*/
public String toString()
{
Node currentNode = firstNode;
String str1 = "[";
String str = toString1(currentNode);
String str2 = "]";
return str1 + str + str2;
}
/**
* int getIndexOf(int aData)
*
* Return the index of the first aData where the first index of
* the first item in this RecursionLinkedList is 0.
*
* #param aData the data to be located
* #return the index of the first aData.
*/
public int getIndexOf(int aData)
{
Node currentNode = firstNode;
int index = 0;
if(currentNode == null) {
return 0;
}
else {
index = getIndexOf1(aData, currentNode);
return index;
}
}
public boolean contains1(int aData, Node node)
{
Node currentNode = node;
if(currentNode == null) {
return false;
}
if(currentNode.data == aData) {
return true;
}
else {
return contains1(aData, currentNode.next);
}
}
public int getFrequencyOf1(int aData, Node node)
{
Node currentNode = node;
int frequency = 0;
if(currentNode == null) {
return frequency;
}
if(currentNode.data == aData) {
frequency = 1 + getFrequencyOf1(aData, currentNode.next);
}
else {
frequency = getFrequencyOf1(aData, currentNode.next);
}
return frequency;
}
public String toString1(Node node)
{
Node currentNode = node;
if(currentNode == null) {
return "\b";
}
else {
int i = currentNode.data;
String str = Integer.toString(i);
String str1 = str + ","+toString1(currentNode.next);
return str1;
}
}
public int getIndexOf1(int aData, Node node)
{
Node currentNode = node;
int index = 0;
if(currentNode == null) {
return 0;
}
if(currentNode.data == aData) {
return index;
}
else {
index = 1 + getIndexOf1(aData, currentNode.next);
return index;
}
}
private class Node
{
private int data;
private Node next;
private Node(int aData, Node nextNode)
{
data = aData;
next = nextNode;
}
private Node(int aData)
{
this(aData, null);
}
}
}
And this is the test class:
import java.util.Random;
public class RecursionLLTester
{
public static void main(String[] args)
{
RecursionLinkedList rll = new RecursionLinkedList();
int point = 0;
boolean isError = false;
System.out.println("Create an empty RecursionLinkedList named rll.");
System.out.print("Test the method contains() on an empty RecursionLinkedList: ");
if(rll.contains(5) != false)
{
System.out.println("FAIL");
System.out.println("Nothing is added into RecursionLinkedList rll.");
System.out.println("rll.contains(5) should return 0.");
System.out.println("But your rll.contains(5) returns " + rll.contains(5) + ".");
}
else
{
System.out.println("PASS");
point++;
}
System.out.print("Test the method getFrequencyOf() on an empty RecursionLinkedList: ");
if(rll.getFrequencyOf(5) != 0)
{
System.out.println("FAIL");
System.out.println("Nothing is added into RecursionLinkedList rll.");
System.out.println("rll.getFrequencyOf(5) should return 0.");
System.out.println("But your rll.getFrequencyOf(5) returns " + rll.getFrequencyOf(5) + ".");
}
else
{
System.out.println("PASS");
point++;
}
Random rand = new Random();
int num = 20;
int[] array = new int[5];
for(int i = 0; i < 5; i++)
{
array[i] = 0;
}
System.out.println("Add the following integer into rll:");
String s = "]";
for(int i = 0; i < num - 1; i++)
{
int temp = rand.nextInt(5);
System.out.print(temp + " ");
s = "," + temp + s;
array[temp]++;
rll.add(temp);
}
int temp = rand.nextInt(5);
System.out.println(temp);
s = "[" + temp + s;
array[temp]++;
rll.add(temp);
System.out.println("\nTest the method contains() on a non-empty RecursionLinkedList");
System.out.print(" - Test rll.contains(-1): ");
if(rll.contains(-1) != false)
{
System.out.println("FAIL");
System.out.println("No -1 has been added into the RecursionLinkedList rll.");
System.out.println("rll.contains(-1) should return 0.");
System.out.println("But your rll.contains(-1) returns " + rll.contains(-1));
}
else
{
System.out.println("PASS");
point++;
}
for(int i = 0; i < 5; i++)
{
System.out.print(" - Test rll.contains(" + i + "): ");
if(rll.contains(i) != (array[i] != 0))
{
System.out.println("FAIL");
System.out.println("There are " + array[i] + " in RecursiveLinkedList rll.");
System.out.println("rll.contains(" + i + ") should return " + (array[i] != 0));
System.out.println("But your rll.contains(" + i + ") returns " + rll.contains(i));
isError = true;
}
else
{
System.out.println("PASS");
}
}
if(!isError)
{
point++;
isError = false;
}
System.out.print(" - Test rll.contains(5): ");
if(rll.contains(5) != false)
{
System.out.println("FAIL");
System.out.println("No 5 has been added into the RecursionLinkedList rll.");
System.out.println("rll.contains(5) should return 0.");
System.out.println("But your rll.contains(5) returns " + rll.contains(5));
}
else
{
System.out.println("PASS");
point++;
}
System.out.println("Test the method getFrequencyOf() on a non-empty RecursionLinkedList");
System.out.print(" - Test rll.getFrequencyOf(-1): ");
if(rll.getFrequencyOf(-1) != 0)
{
System.out.println("FAIL");
System.out.println("No -1 has been added into the RecursionLinkedList rll.");
System.out.println("rll.getFrequencyOf(-1) should return 0.");
System.out.println("But your rll.getFrequencyOf(-1) returns " + rll.getFrequencyOf(-1));
}
else
{
System.out.println("PASS");
point++;
}
for(int i = 0; i < 5; i++)
{
System.out.print(" - Test rll.getFrequencyOf(" + i + "): ");
if(rll.getFrequencyOf(i) != array[i])
{
System.out.println("FAIL");
System.out.println(i + " has been added to the RecursionLinkedList " + array[i] + " times.");
System.out.println("rll.getFrequencyOf(" + i + ") should return " + array[i] + ".");
System.out.println("But your rll.getFrequencyOf(" + i + ") returns " + rll.getFrequencyOf(i));
isError = true;
}
else
{
System.out.println("PASS");
}
}
if(!isError)
{
point++;
isError = false;
}
System.out.print(" - Test rll.getFrequencyOf(5): ");
if(rll.getFrequencyOf(5) != 0)
{
System.out.println("FAIL");
System.out.println("No 5 has been added into the RecursionLinkedList rll.");
System.out.println("rll.getFrequencyOf(5) should return 0.");
System.out.println("But your rll.getFrequencyOf(5) returns " + rll.getFrequencyOf(5));
}
else
{
System.out.println("PASS");
point++;
}
System.out.print("Test the method toString(): ");
if(!s.equals(rll.toString()))
{
System.out.println("FAIL");
System.out.println("rll.toString() should return the string \"" + s + "\".");
System.out.println("But your rll.toString() returns the string \"" + rll.toString() + "\".");
}
else
{
System.out.println("PASS");
point++;
}
System.out.println("Test the method getIndexOf()");
System.out.println("Currently the rll is " + rll + ".");
String[] str = rll.toString().split(",");
str[0] = str[0].substring(1);
str[str.length - 1] = str[str.length - 1].substring(0, 1);
for(int i = -1; i <= 5; i++)
{
System.out.print("Test the method getIndexOf(" + i + "): ");
if(getIndex(str,i) != rll.getIndexOf(i))
{
System.out.println("FAIL");
System.out.println("The index of " + i + " should be " + getIndex(str,i) + ".");
System.out.println("But your rll.getIndexOf(" + i + ") returns " + rll.getIndexOf(i) + ".");
isError = true;
}
else
{
System.out.println("PASS");
}
}
if(!isError)
{
point++;
isError = false;
}
System.out.println("Your current point is " + point + ".");
}
public static int getIndex(String[] str, int s)
{
int result = -1;
for(int i = 0; i < str.length; i++)
{
if(s == Integer.parseInt(str[i]))
{
return i;
}
}
return result;
}
}
The problem is in your toString1(Node) method.
if (currentNode == null) {
return "\b";
}
The \b character is what you're seeing at the end in your test output.
rll.toString() should return the string "[1,1,1,3,4,2,2,1,0,1,2,1,0,4,4,4,2,1,1,2]".
But your rll.toString() returns the string "[1,1,1,3,4,2,2,1,0,1,2,1,0,4,4,4,2,1,1,2,?]".
With a slight adjustment to the method as follows, the test in question passes.
public String toString1(Node node)
{
Node currentNode = node;
if (currentNode == null) {
return "\b";
}
int i = currentNode.data;
String str = Integer.toString(i);
if (currentNode.next != null) {
str = str
+ "," + toString1(currentNode.next);
}
return str;
}
Though I would recommend you change a few things here:
Use a StringBuilder rather than all that thrashing on string concatenation.
Replace recursion with a loop. If your list gets too big you're going to run out of stack space with that recursive method.
I don't think you ever want to return that \b character, as it doesn't represent an integer and your indexOf() method seems to be choking on the concept as well.
I have a method that checks to see if an equation written is correct.
This method check for:
Multiple Parentheses
Excess operators
Double Digits
q's
and any character in a string that is not and of these:
.
private static final String operators = "-+/*%_";
private static final String operands = "0123456789x";
It was working fine, but then I added in modular to the operators and now whenever my code reaches the part in the method that checks to the left and the right of an operand to see if it is neither the end of the string or the beginning I get an error saying
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
My method and all it's additional methods.
private static final String operators = "-+/*%_";
private static final String operands = "0123456789x";
public Boolean errorChecker(String infixExpr)
{
char[] chars = infixExpr.toCharArray();
StringBuilder out = new StringBuilder();
for (int i = 0; i<chars.length; i++)
{
System.out.print(infixExpr.charAt(i));
if (isOperator(infixExpr.charAt(i)))
{
if (i == 0 || i == infixExpr.length())
{
out.append(infixExpr.charAt(i));
}
else if (isOperator(infixExpr.charAt(i + 1)) && isOperator(infixExpr.charAt(i - 1)))
{
System.out.println("To many Operators.");
return false;
}
else if (isOperator(infixExpr.charAt(i + 1)))
{
if (infixExpr.charAt(i) != '-' || infixExpr.charAt(i + 1) != '-')
{
System.out.println("To many Operators.");
return false;
}
}
else if (isOperator(infixExpr.charAt(i - 1)))
{
if (infixExpr.charAt(i) != '-' || infixExpr.charAt(i - 1) != '-')
{
System.out.println("To many Operators.");
return false;
}
}
}
else if (isOperand(infixExpr.charAt(i)))
{
if (i == 0 || i == infixExpr.length())
{
out.append(infixExpr.charAt(i));
}//THE LINE RIGHT BELOW THIS COMMENT THROWS THE ERROR!!!!!
else if (isOperand(infixExpr.charAt(i + 1)) || isOperand(infixExpr.charAt(i - 1)))
{
System.out.println("Double digits and Postfix form are not accepted.");
return false;
}
}
else if (infixExpr.charAt(i) == 'q')
{
System.out.println("Your meow is now false. Good-bye.");
System.exit(1);
}
else if(infixExpr.charAt(i) == '(' || infixExpr.charAt(i) == ')')
{
int p1 = 0;
int p2 = 0;
for (int p = 0; p<chars.length; p++)
{
if(infixExpr.charAt(p) == '(')
{
p1++;
}
if(infixExpr.charAt(p) == ')')
{
p2++;
}
}
if(p1 != p2)
{
System.out.println("To many parentheses.");
return false;
}
}
else
{
System.out.println("You have entered an invalid character.");
return false;
}
out.append(infixExpr.charAt(i));
}
return true;
}
private boolean isOperator(char val)
{
return operators.indexOf(val) >= 0;
}
private boolean isOperand(char val)
{
return operands.indexOf(val) >= 0;
}
My main portion that runs the method:
Boolean meow = true;
while(meow)
{
System.out.print("Enter infix expression: ");
infixExpr = scan.next();//THE LINE RIGHT BELOW THIS COMMENT THROWS THE ERROR!!!!!
if(makePostfix.errorChecker(infixExpr) == true)
{
System.out.println("Converted expressions: "
+ makePostfix.convert2Postfix(infixExpr));
meow = false;
}
}
It was working fine before, but now it won't even pass 1+2 which was previously working and I changed NONE of that you see. What's wrong!?!?
What looks like what's happening is that you check for the character at index (i + 1) several times in your code. Lets say you input a string with a length of five characters. The program goes through and reaches the line:
else if (isOperator(infixExpr.charAt(i + 1)) && isOperator(infixExpr.charAt(i - 1)))
If i == 4, this will cause the code:
infixExpr.charAt(i + 1)
to throw an index error.
In essance, you're checking for a character at index five (the sixth character) in a string with a maximum index index of four which is five characters in length. Also, your checking for
if(i==0 || i == infixExpr.length)
won't work as is. Maybe check for (i==infixExpr.length-1).