Чтение стека Java из массива вызывает исключение ArrayIndexOutOfBoundsException

StackOverflow https://stackoverflow.com/questions/9492667

Вопрос

Мне нужно заполнить стек из массива, затем распечатать элементы по порядку, а затем снова изменить порядок.У меня проблемы с тем, что я получаю исключение ArrayIndexOutOfBoundsException и не могу понять, откуда оно взялось.Я попробовал запустить отладку, и оказалось, что, когда я вытаскиваю элементы, он никогда не достигает последнего элемента.Ниже мой код:

public class arrayStack {

    private int top;
    private String[] storage;

    public arrayStack(int capacity)
    {
        storage = new String[capacity];
        top = -1;
    }

    public boolean isEmpty() {
        return (top == 0);
    }

    String peek() {
        return storage[top];    
    }

    String pop() {
        top--;
        return storage[top];
    }

    public void push(String str) {
        top++;
        storage[top] = str;
    }

}

StackMain.java:

public class StackMain {

    public static void main(String[] args) {
        //int j = 5;
        String[] list = new String[5];

        list[0] = "Beware";
        list[1] = "The";
        list[2] = "Ides";
        list[3] = "Of";
        list[4] = "March";

        arrayStack stack = new arrayStack(5);

        for(int i = 0; i < list.length; i++)
        {
            stack.push(list[i]);
        }

        for(int j = 0; j < list.length; j++)
            System.out.println(stack.pop());

    }

}
Это было полезно?

Решение

В pop(), вам нужно вернуть извлеченный элемент, то есть элемент с индексом старого значения top.Самый чистый способ - изменить функцию на

String pop() {
    return storage[top--];
}

Редактировать
Вам также необходимо изменить isEmpty() к return (top == -1).Вы также можете изменить реализацию для использования size (количество элементов) вместо top (индекс высшего элемента), как и другие упомянутые.

Другие советы

В вашем конструкторе для arrayStack, вам следует установить top до 0, а не до -1.В вашей isEmpty метод, вы даже проверьте это top == 0, так ясно top == 0 означает пустой, а не top == -1.Вот почему вы всегда пропускаете последний элемент при извлечении значений из стека;установка приращений первого элемента top до 0.

О, и я пропустил то, что сказал Том ниже:уменьшение top прежде чем вы найдете значение вверху, вы вернете неправильный элемент.Приведенный ниже код предпочтительнее, но новичку может быть проще его понять:

public String pop() {
    String topValue = storage[top];
    top--;
    return topValue;
}

Если вы push(String) только один элемент с инициализацией top равным -1, каково будет значение top после нажатия?

Теперь посмотри на свой pop() функция, она уменьшает вершину до пытается получить запрошенный элемент, так к какому индексу массива он будет пытаться получить доступ, если вы вставили только один элемент?

С тех пор, как вы начинаете top в -1, как только вы добавите 5 элементов из массива String top будет 4, что неверно, поскольку у вас 5 элементов.

Затем, когда вы попытаетесь вытащить стек 5 раз, top возвращается к -1 и storage[-1] не существует, поэтому вы получаете ArrayIndexOutOfBoundsException

Начинать top в 0.

Альтернативно, если вы уменьшаете top после того, как вы получите элемент из стека, вы не получите ошибку;но лучше бы начать top в 0, потому что top на самом деле представляет количество элементов в вашем стеке.

Пожалуйста, отметьте вопрос как домашнее задание.И что касается проблемы, проблема заключается в функции pop().Сначала вы уменьшаете значение top, а затем возвращаете элемент.Но когда вы проверяете функцию push(), вы сначала увеличиваете, а затем добавляете элемент.Итак, если вы переместите top-- после получения элемента из стека ваша проблема будет решена.

Ваш поп-метод неверный.В вашем коде здесь топ начинается с отрицательной 1.

Когда вы нажимаете элемент, верх становится 0. Когда вы попмете элемент, верх становится -1, прежде чем получить доступ к элементу.

Кроме того, ваш пустой метод неверный.В исходном состоянии стека, Top= -1 и ustemy Creams, если он возвращает 0. Первоначально стек должен быть пустым.

Ваша функция POP () должна быть изменена.Вы должны хранить хранилище [POP] во временной переменной, а затем уменьшить верхнюю часть на 1, а затем вернуть временную переменную

Было бы здорово, если вы сможете включить Java 1.5 Generics Facility для реализации стека. Затем ваш стек будет более гибким. Это может удерживать любой тип объектов (в вашем случае только строки) И еще один совет находится в способе POP, вы должны сказать сборщику мусора, чтобы выбросить пополнить объект следующим образом.(В случае, если вы используете дженерики) Ниже приведен более гибкий режим реализации стека, который упомянул в эффективном Java Edition 2.

// Initial attempt to generify Stack = won’t compile!
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = (E[])new E[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size==0)
throw new EmptyStackException();
E result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top