Сравнение Java-Стека
мне интересно, как это сделать:
- сравнить два объекта стека
- сделать это рекурсивно
- после метода, это завершено, стопки остаются такими, какими они были вначале (т. е. тот же порядок, те же предметы).
только push
, pop
и isEmpty
методы Stack
доступно.
Я больше ищу теоретическую помощь, чем помощь в кодировании, но любое понимание будет оценено.
3 ответов
в псевдо-коде вы можете сделать что-то вроде этого:
boolean compareStacks(a, b) {
if (a.isEmpty() != b.isEmpty()) return false; // check if one is empty
if (a.isEmpty() && b.isEmpty()) return true; // check if both are empty
element_a = a.pop(); // grab elements and compare them
element_b = b.pop();
if (((element_a==null) && (element_b!=null)) || !element_a.equals(element_b)) {
a.push(element_a); // if they are not equal, restore them and return false
b.push(element_b);
return false;
}
result = compareStacks(a, b); // compare shortened stacks recursively
a.push(element_a); // restore elements
b.push(element_b);
return result; // return result from recursive call
}
два стека идентичны, если их элементы верхнего уровня идентичны, а остальные стеки идентичны (а именно рекурсивное условие).
теперь подумайте, что делать непосредственно перед возвращением из вызова метода, чтобы оставить стеки так же, как они были заданы во время вызова.
---редактировать---
рабочий код Java (производный от Маркус А. решение, но с интересным использованием "наконец" и с дженерики):
static <T> boolean compareStacks(Stack<T> a, Stack<T> b) {
if (a.isEmpty() != b.isEmpty()) return false;
if (a.isEmpty() && b.isEmpty()) return true;
T element_a = a.pop();
T element_b = b.pop();
try {
if (((element_a==null) && (element_b!=null)) || (!element_a.equals(element_b)))
return false;
return compareStacks(a, b);
} finally { // restore elements
a.push(element_a);
b.push(element_b);
}
}
с рекурсией всегда помогает думать об этом как о 2 частях, "настройке" и рекурсивной функции. Ваша настройка создаст правильную ситуацию (создайте два стека, передайте их и т. д.), а затем вызовет рекурсивный метод, и когда рекурсивный метод будет выполнен, сообщите о результатах.
в вашем случае вам, вероятно, нужна эта подпись для "рекурсивного" метода:
public boolean compareStacks(Stack one, Stack two)
если этот метод pops & сравнивает верхние элементы буксировки стека, он может вернуть false прямо тогда (говоря, что они не сравнивают). Если да, то теперь у вас есть две стопки, каждая из которых короче, чем раньше. Вы уже знаете, как сравнить эти два стека, правильно (вы только что написали метод для этого!).
в конце вы можете "нажать" один элемент обратно в каждый стек, чтобы восстановить его предыдущее состояние перед возвратом.
будет немного хитрости в восстановлении стека в случае, когда они не сравниваются, и гарантируя, что если compareStack вы вызываете не удается правильно передать это до предыдущего состояния, даже если" текущий " compareStack преуспевает, но это детали реализации-просто подумал, что я упомянул бы их, чтобы вы не упускали их из виду.
есть симпатичное решение с Try / finally (нет улова, возврат изнутри try и возврат в стек в finally), которое сделало бы код довольно скользким, но это достаточно легко без него.