Need to handle ArrayIndexOutOfBoundsException for stack array, without program ending - java

I am doing a pretty simple program, where a user will be prompted to enter up to 80 characters. We need to build our own stack and push each character onto the stack. Then pop and display the characters in reversed order. Thought I was done, but my instructor wants me to do something if a user enters more than 80 characters. Basically, I need to ignore all characters over 80. How would I go about doing this? I have been trying to figure this out, but can't get it. I am sure it will be something simple that I completely missed. Any help, suggestions, are appreciated!
stackUser
import java.util.Scanner;
public class stackUser {
public static void main(String[] args){
System.out.println("\nPlease enter up to 80 characters and I will reverse them: ");
Scanner key = new Scanner(System.in);
String input = key.nextLine();
myStack stack = new myStack();
for(int i = 0; i < input.length(); i++){
char c = input.charAt(i);
stack.push(c);
}
if(stack.isEmpty()){
System.out.println("Stack is empty!");
}else{
while(!stack.isEmpty()){
char rev = stack.pop();
System.out.print(rev);
}
}
}
}
myStack
public class myStack {
private int max = 80;
private char[] Stack = new char[max];
private int top = -1;
public void push(char input){
top++;
Stack[top] = input;
}
public char pop(){
char popped = Stack[top];
top --;
return popped;
}
public boolean isEmpty(){
boolean empty;
if(top == -1){
empty = true;
}else{
empty = false;
}
return empty;
}
}

Handle ArrayIndexOutOfBoundsException is bad idea, you need to check current top value with max value. Because ArrayIndexOutOfBoundsException is unchecked exception, and it means that error of developer.

I would declare the push method like this to indicate that it will throw an exception if the max is reached:
public void push(char input) throws ArrayIndexOutOfBoundsException{
top++;
Stack[top] = input;
}
Then in the main method you can use a try/catch block to handle the exception:
try{
stack.push(c);
}catch (ArrayIndexOutOfBoundsException ex){
System.out.println("too much!");
}

A try catch loop around anything that will throw an IndexOutOfBounds
try {
...code here
}
catch (ArrayIndexOutOfBoundsException e) {
...whatever you want to do in event of exception
}

Related

Java- function seems to mess up the console, nothing will be printed out after calling the function

I was asked to program a method that receives a scanner, and returns a sorted array of words which contain only letters, with no repetitions (and no bigger in length than 3000). Then, I was asked to program a method that checks whether a certain given string is contained in a given vocabulary. I used a simple binary search method.
This is what I've done:
public static String[] scanVocabulary(Scanner scanner){
String[] array= new String[3000];
int i=0;
String word;
while (scanner.hasNext() && i<3000) {
word=scanner.next();
if (word.matches("[a-zA-Z]+")){
array[i]=word.toLowerCase();
i++;
}
}int size=0;
while (size<3000 && array[size]!=null ) {
size++;
}
String[] words=Arrays.copyOf(array, size);
if (words.length==0 || words.length==1) {
return words;
}
else {
Arrays.sort(words);
int end= removeDuplicatesSortedArr(words);
return Arrays.copyOf(words, end);
}
}
private static int removeDuplicatesSortedArr(String[] array) { //must be a sorted array. returns size of the new array
int n= array.length;
int j=0;
for (int i=0; i<n-1; i++) {
if (!array[i].equals(array[i+1])) {
array[j++]=array[i];
}
}
array[j++]=array[n-1];
return j;
}
public static boolean isInVocabulary(String[] vocabulary, String word){
//binary search
int n=vocabulary.length;
int left= 0;
int right=n-1;
while (left<=right) {
int mid=(left+right)/2;
if (vocabulary[mid].equals(word)){
return true;
}
else if (vocabulary[mid].compareTo(word)>0) {
right=mid-1;
}else {
right=mid+1;
}
}
return false;
}
while trying the following code:
public static void main(String[] args) {
String vocabularyText = "I look at the floor and I see it needs sweeping while my guitar gently weeps";
Scanner vocabularyScanner = new Scanner(vocabularyText);
String[] vocabulary = scanVocabulary(vocabularyScanner);
System.out.println(Arrays.toString(vocabulary));
boolean t=isInVocabulary(vocabulary, "while");
System.out.println(t);
System.out.println("123");
}
I get nothing but-
[and, at, floor, gently, guitar, i, it, look, my, needs, see, sweeping, the, weeps, while]
nothing else is printed out nor returned. Both functions seem to be working fine separately, so I don't get what I'm doing wrong.
I would be very happy to hear your thoughts, thanks in advance :)
This has nothing to do with the console. Your isInVocabulary method is entering an infinite loop in this block:
if (!isInVocabulary(vocabulary, "while")) {
System.out.println("Error");
}
If you were to debug through isInVocabulary, you would see that after a few iterations of the while loop,
left = 0;
right = 2;
mid = 1;
if (vocabulary[mid].equals(word)){
// it doesn't
} else if (vocabulary[mid].compareTo("while") > 0) {
// it doesn't
} else {
right = mid + 1;
// this is the same as saying right = 1 + 1, i.e. 2
}
So you'll loop forever.

receive multiple char input from a single line in java

I am writing a stack data structure in java using arrays. The problem is when I try to push the users char input it doesn't display. The problem is with this code.
public static void preSuf(Stack stack) {
Scanner key = new Scanner(System.in);
System.out.println("enter the values");
while(key.hasNext()){
char c = key.next().charAt(0);
stack.push(c);
}
}
When I change the while(key.hasNext()) to if(key.hasNext()) it works but it only prints one time and doesnt itterate. How can I fix this problem thank you.
Edit: Here is the whole code
import java.util.Scanner;
public class Stack {
private int top;
private char[] container;
private int size;
public static int pos = 0;
// constructor
public Stack(int N) {
container = new char[N];
size = N;
top = 0;
}
public boolean isFull() {
return (size == top);
}
public void push(char string) {
if (!isFull()) {
container[top] = string;
top++;
} else {
return;
}
}
public int pop() {
int drop;
drop = container[top - 1];
container[top] = 0;
top--;
return drop;
}
public int peek() {
int drop2;
drop2 = container[top - 1];
return drop2;
}
public void display() {
for (int i = 0; i < container.length; i++) {
if (container[i] != 0) {
System.out.print(container[i]);
}
}
}
public static void preSuf(Stack stack) {
Scanner key = new Scanner(System.in);
System.out.println("enter the values");
while(key.hasNext()){
char c = key.next().charAt(0);
stack.push(c);
}
}
public static void main(String args[]) {
Stack stack = new Stack(3);
preSuf(stack);
stack.display();
stack.display();
System.out.println();
}
}
The problem is that you haven't written any code to actually print the contents of your stack.
You could write a loop after your while loop to iterate over the stack and print out each character.
You'll also need a way of exiting your while loop. You can do this either with a special character, eg. if(c == '.') break; or you can just press Ctrl+Z.
EDIT: Based on the edit to the question and the full code being presented, I think the suggestion of needing the extra loop is now redundant. You have that in stack.display(). You just need to get out of your while loop.
you haven't determined when the loop should end.
you'd think if you press enter without entering anything the loop
would break but that's not how next operates. if you press enter
without entering anything or input data which consists of only whitespaces, next will block while waiting for input to
scan, even if a previous invocation of hasNext() returned true.
the solution is to include a condition at which control should break out of the loop.

Using Java Stack with String elements

I'm trying to use a java Stack to push String values:names into it, derived from input from a Scanner method. I'd then want to pop the names from the stack, and after show the logical and physical elements of the stack. I believe I should be using an Array Stack but not entirely sure as I don't have much quidance or experience with Stacks.
Currently I am getting the following error when compiling the Stack.java file.
Stack.java:24: cannot find symbol
symbol : method push(java.lang.String)
location: class java.lang.String[]
stack.push(s);
I've been researching this and trying different code for days, but as I am very new to this, and I have run out of ways to manipulate the code to make it work.
I would highly appreciate some advice...tnx!
Here is my Stack Class code:
import java.lang.*;
import java.util.*;
public class Stack { //Create Class
private String stack[] ;
private int top;
private static final int SIZE = 5;
String name;
Scanner scan = new Scanner(System.in);
public Stack(int SIZE){
stack = new String [SIZE];
top = 0;
}
public void push(String s) { //Method to Insert
if (isStackFull())
System.out.println ("Stack is Full "); //If Stack full Print Full
else {
while (scan.hasNextLine()){
s = scan.nextLine();
stack.push(s);
}
stack[top] = s;
top++;
}
}
public String pop() { //Method to Delete
if (isStackEmpty())
System.out.println ("Stack is Empty "); //If Stack empty print Empty
else{
String value = stack[top];
top--;
return value;
}
return stack[top];
}
public String toString( ){ //Method print Logical Stack
if (isStackEmpty( ))
System.out.println ("Stack is Empty "); //If Stack empty print Empty
else
System.out.println("\nThe Stack");
String result = "";
for (int j=0; j < top; j++)
result = result + stack[j].toString() + "\n";
return result;
}
public boolean isStackEmpty() { //Method boolean type to check empty Stack
return (top == 0);
}
public boolean isStackFull() { //Method boolean type to check full Stack
return (top == (SIZE-1));
}
}
For the StackTest Code, generally I call the methods in Stack. Eg.
public class StackTest { //Create class
public static void main(String[] args){ //Main Method
Stack n = new Stack(); //Declare variables
Scanner in = new Scanner(System.in);
String response;
char x;
and
while(x != 'q' && x != 'Q'){ //While loop initiates if no q or Q char input
switch(x){ //Start of swtich for insert, delete, print physical, logical or default quite
case 'i':
n.push();
System.out.println ("Inserted item from Stack");
break;
case 'd':
n.pop();
System.out.println ("Deleted item from Stack");
break;
case 'p':
n.toString();
System.out.println ("Printed Physical Stack ");
break;
Your push(String s) is method is calling push() on String which is incorrect, moreover the logic for push(String s) is complicated, rather it is simple as shown below in the code with comments:
public void push(String s) {
if (isStackFull())
System.out.println ("Stack is Full "); //If Stack full Print Full
else {
stack[top] = s; //just add the string to the top of the stack
top++; //increment top
}
}
In the push method itself you are trying to call stack.push hence it is throwing error. replace the stack.push to stack[top_index]= the string.

My program keeps returning a StringIndexOutOfBounds Exception regardess of what I do

import java.io.*;
public class runner{
//Translates from infix to postfix
//Evaluates the postfix expression
public static tokenlist xform(String input){
//operand get pushed automatically onto linked list
//operator we will see;
tokenlist postfix=new tokenlist();
stack stack=new stack();
int c=0;
while(input.substring(c,c) != null){
if(prec.isoper(input.substring(c,c))==false){
postfix.push(input.substring(c,c),false);
}else{
if(stack.inspect()==null){
stack.push(input.substring(c,c));
}else{
if(prec.inprec(input.substring(c,c))>prec.stackprec(stack.inspect())){
while(prec.inprec(input.substring(c,c))>prec.stackprec(stack.inspect())){
String s=stack.pop();
postfix.push(s,true);
}
}else{
stack.push(input.substring(c,c));
}
}
}
c++;
}
return postfix;
}
public static double eval(tokenlist postfix){
astack numbers=new astack();
Double ans=0.0;
numbers.push(Double.parseDouble(postfix.getTing()));
while(numbers.isEmpty() != true){
if(postfix.getFunc()== false){
numbers.push(Double.parseDouble(postfix.getTing()));
}else{
double c=0.0;
double a=numbers.pop();
double b=numbers.pop();
if(postfix.getTing()=="+"){
c=a+b;
numbers.push(c);
}
if(postfix.getTing()=="-"){
c=b-a;
numbers.push(c);
}
if(postfix.getTing()=="*"){
c=a*b;
numbers.push(c);
}
if(postfix.getTing()=="/"){
c=b/a;
numbers.push(c);
}
if(postfix.getTing()=="^"){
double store;
double rep=0.0;
while(rep<=a){
c=b*b;
store=c;
rep=rep+1.0;
}
numbers.push(c);
}
if(postfix.getTing()=="\\"){
c=Math.abs(b-a);
numbers.push(c);
}
}
ans=numbers.pop();
}
return ans;
}
public static void main(String[] args){
try{
tokenlist postfix=xform(args[0]);
postfix.printlist();
double d=eval(postfix);
System.out.println(d);
}catch(Exception e){System.out.print(e);}
}
}
Regardless of what number is within args[#] in the main, I keep geting the above exception and String index out of range: Whatever number is in args[#] in the main. I already checked in the xform and it takes in the input as a string and the substring starts at 0. Still it doesn't work. I f anyone could have an explanation or tips they would be greatly appreciated.
You're code contains the line while(input.substring(c,c) != null)
This is basically an endless loop until c is higher that the length of your string which causes the exception.
Try to change it to while(c < input.length()) and you should be good to go.
Furthermore I hope you are aware of the fact that substring(c,c) will always return an empty string.
If you want a single character either use .charAt(c) or .substring(c, c+1)

Syntax errors in parametrizing stacks

I'm a computer science student that just started my sophomore programming class and I'm having some real issues with a project that deals with Stacks and collections.
Basically, this is a project that relies on the ArrayStack Class(ArrayStack, to be specific) to convert mathematical expressions between postfix and infix forms.
Basically, ArrayStack is used to take in an expression like 45 * (26 - 5) / 54, turn it into a collection, then rewrite in a postfix form like 45 26 5 - * 54 /
The problem is, first of all, whenever I try to substitute with Character in the main method(since the stack needs to store both operators and operands, maybe there's a better data type I'm missing here), I get some strange syntax error, usually involving the program thinking that ArrayStack.System is somehow a statement(System.out.println is right below an ArrayStack statement, which suggests there's some kind of syntax problem)
Here's the code I have so far:
public class ArrayStack<T> implements StackADT<T>
{
private static final int DEFAULT_CAPACITY = 100;
private int top;
private T[] stack;
public ArrayStack() {
top = -1;
stack = (T[]) (new Object[DEFAULT_CAPACITY]);
}
public void push(T element) {
stack[top+1] = element;
top++;
}
public T pop() {
T element = stack[top];
stack[top] = null;
top--;
return element;
}
public T peek() {
return stack[top];
}
public boolean isEmpty() {
if(stack[0]==null)
return true;
else{
return false;
}
}
public int size() {
int length = 0;
for(int count=0;count<stack.length;count++) {
if(stack[count]!=null) {
length++;
}
else if(stack[count]==null) {
break;
}
}
return length;
}
public String toString() {
String array = "";
for(int count=0;count<stack.length;count++) {
array = array+stack[count]+" ";
}
return array;
}
}
And for the main method:
public class StackTester {
public static void main(String[] args) {
boolean quit = false;
int input;
String expression;
do {
System.out.println("1. Convert infix to postfix");
System.out.println("2. Convert postfix to infix");
System.out.println("3. Exit.");
java.util.Scanner keyboard = new java.util.Scanner(System.in);
input = keyboard.nextInt();
switch(input) {
case 1:
//ArrayStack stack = new ArrayStack();
//System.out.println("Enter an infix expression: ");
expression = keyboard.next();
for(int count=0;count<expression.length();count++) {
Character a = expression.charAt(count);
stack.push(a);
}
for(int count=stack.size()-1;count>=0;count--) {
if(stack.peek()=='+') {
}
}
}
break;
}
while(!quit);
}
}
The error usually occurs at the lines marked with //, every time I try to insert something like or otherwise, the program gives some weird syntax error like its trying to read it together with the line below it. Any ideas what's going on here?

Categories