[英]return the index of doubly-linked list starting from the end (backwards)
I am trying to write undo and redo functions using the doubly-linked list that adds actions(nodes) in the front of the list_1 when doAction() is called, stores actions in list_2 when undo() is called, and adds the action back to list_1 when redo() is called.我正在尝试使用双向链表编写撤消和重做函数,该双向链表在调用doAction()时在 list_1 的前面添加动作(节点),在调用undo()时将动作存储在 list_2 中,然后将动作添加回来调用redo()时到 list_1。 All elements in both of the lists are added to the front of the list (stack).
两个列表中的所有元素都添加到列表(堆栈)的前面。 I am not allowed to import any additional Java packages.
我不允许导入任何额外的 Java 包。
public class StringDoublyLinkedList {公共 class StringDoublyLinkedList {
/**
* A private class to represent a link in the linked list.
*/
private class Node {
String value;
Node next;
Node prev;
Node(String value) {
this.value = value;
this.next = null;
this.prev = null;
}
}
private int size = 0;
private Node head = null;
private Node tail = null;
private Node head_2 = null;
/**
* Add a String to the end of the list.
*
* @param value The String to add.
*/
public void add(String value) {
Node newNode = new Node(value);
if (this.size == 0) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
newNode.prev = this.tail;
this.tail = newNode;
}
this.size += 1;
}
/**
* Get the number of elements in the list.
*
* @return The number of elements in the list.
*/
public int size() {
return this.size;
}
public String get(int index) {
return this.getNode(index).value;
}
public void remove(int index) {
Node curr = this.head;
if (index == 0) {
this.head = curr.next;
} else {
Node node = this.getNode(index - 1);
node.next = node.next.next;
if (node.next == tail) {
this.tail = node;
}
}
this.size -= 1;
}
private Node getNode(int index) {
Node curr = head;
for (int i = 0; i < index; i++) {
curr = curr.next;
}
return curr;
}
public boolean undo() {
Node curr = this.head;
if (this.size > 0) {
curr.next.prev = null;
this.head = curr.next;
this.head_2 = curr;
} else if (this.size == 0) {
return false;
}
this.size -= 1;
return true;
}
public boolean redo() {
Node curr = this.head;
Node curr_2 = this.head_2;
if (this.size > 0) {
curr_2.next.prev = null;
this.head_2 = curr_2.next;
curr.next = this.head;
this.head.prev = curr;
this.head = curr;
} if (this.size == 0) {
return false;
}
this.size += 1;
return false;
}
/**
* Record an action.
*
* @param action The action to record.
*/
public void doAction(String action) {
Node newNode = new Node(action);
if (this.size == 0) {
this.head = newNode;
this.tail = newNode;
} else {
this.head.prev = newNode;
newNode.next = this.head;
this.head = newNode;
}
this.size += 1;
}
/**
* Get the number of actions recorded. Does *not* include actions that were undone.
*
* @return The number of actions recorded.
*/
public int getNumActions() { //FIXME
int count = 1;
int i;
for (int i = getNumActions() - 1; i >=0 ; i--) { // second option you have provided
count++;
}
return count;
}
/**
* Get the action at the specified index.
*
* Assumes the index < this.getNumActions().
*
* @param index The index of the desired action.
* @return The action (String).
*/
public String getAction(int index) { //FIXME
int i;
for (i = 0; i < this.size(); i++) {
index = this.size() - index - 1;
}
String Actions = this.get(index);
return Actions;
}
public void print() {
Node curr = this.head;
while (curr != null) {
System.out.print(curr.value);
System.out.print(", ");
curr = curr.next;
}
System.out.println();
}
} }
This is the test case:这是测试用例:
public static void main(String[] args) {
StringDoublyLinkedList actions = new StringDoublyLinkedList();
actions.doAction("create outline");
actions.doAction("write introduction paragraph");
actions.doAction("write paragraph 1a");
actions.undo();
actions.doAction("write paragraph 1b");
actions.doAction("write paragraph 2a");
actions.undo();
actions.undo();
actions.redo();
actions.doAction("write paragraph 2b");
actions.doAction("write paragraph 3");
actions.doAction("write paragraph 4");
actions.undo();
actions.doAction("write conclusion paragraph");
actions.doAction("add expletive about how long this assignment took");
actions.undo();
String[] correctActions = {
"create outline",
"write introduction paragraph",
/*"write paragraph 1a",
"write paragraph 2b",
"write paragraph 3",
"write conclusion paragraph" */
};
// create a variable for overall correctness
boolean allCorrect;
// check the number of actions
System.out.println(
"Expected " + Integer.toString(correctActions.length) + " actions " +
"and found " + Integer.toString(actions.getNumActions())
);
allCorrect = (actions.getNumActions() == correctActions.length);
// if the number of actions is correct, check each action
if (allCorrect) {
for (int i = 0; i < correctActions.length; i++) {
// get the expected and action actions
String expectedAction = correctActions[i];
String actualAction = actions.getAction(i);
// compare them
boolean correct = (expectedAction == actualAction);
// print them out
System.out.println(
"(" + (correct ? "correct" : "incorrect") + ") " +
"Action " + Integer.toString(i) + " should be \"" + correctActions[i] + "\" " +
"and got \"" + actions.getAction(i) + "\"."
);
// update the overall correctness
allCorrect = (allCorrect && correct);
}
}
// give a summary correct/incorrect judgment
if (allCorrect) {
System.out.println("CORRECT!");
} else {
System.out.println("INCORRECT!");
}
}
} }
The code I wrote in the getAction() returns the actions starting from index[0] of the list, but I want it to return the actions backwards (starting from the end of the list).我在getAction()中编写的代码返回从列表的 index[0] 开始的操作,但我希望它向后返回操作(从列表的末尾开始)。
Using my test case as an example:以我的测试用例为例:
(incorrect) Action 0 should be "create outline" and got "write introduction paragraph". (不正确)动作 0 应该是“创建大纲”并得到“写介绍段落”。
(incorrect) Action 1 should be "write introduction paragraph" and got "create outline". (不正确)动作1应该是“写介绍段落”并得到“创建大纲”。
public int getNumActions() { //FIXME
int count = 1;
int i;
for (int i = getNumActions() - 1; i >=0 ; i--) { // error
count++;
}
return count;
}
public String getAction(int index) { //FIXME
int i;
for (i = 0; i < this.size(); i++) {
index = this.size() - index - 1;
}
String Actions = this.get(index);
return Actions;
}
Okay, then each time you call getAction(int)
, call it like this:好的,那么每次调用
getAction(int)
时,都可以这样调用:
getAction((some size variable) - index)
(I would recommend giving your Node
sa length or size variable) getAction((some size variable) - index)
(我建议给你的Node
sa 长度或大小变量)
Instead of this而不是这个
getAction(some size variable)
In a for loop, you can also do for(int i=(some size variable)-1; i>=0; i--)
to start from the end.在 for 循环中,您还可以执行
for(int i=(some size variable)-1; i>=0; i--)
从末尾开始。
Probably this is off topic, but I think that using recursion to count elements in a LinkedList
is a quite complex solution.可能这是题外话,但我认为使用递归来计算
LinkedList
中的元素是一个非常复杂的解决方案。
I think you should split two logical objects in your program first:我认为您应该首先在程序中拆分两个逻辑对象:
LinkedList
implementation with basic methods like getSize()
, add(String)
and remove(String)
; LinkedList
实现与基本方法,如getSize()
, add(String)
和remove(String)
;ActionManager
implementation with methods like doAction(Stirng)
, undo(String)
and redo(String)
.doAction(Stirng)
、 undo(String)
和redo(String)
等方法的ActionManager
实现。 In this case, you have a better quality of your program and bug-free.在这种情况下,您的程序质量更好并且没有错误。
public final class LinkedList {
private Node head;
private int size;
public int getSize() {
return size;
}
public void add(String value) {
Node node = new Node(value);
if (size == 0)
head = node;
else {
Node tail = getTail();
tail.next = node;
node.prev = tail;
}
size++;
}
public String remove() {
if (size == 0)
throw new IllegalArgumentException();
String value;
if (size == 1) {
value = head.value;
head = null;
} else {
Node tail = getTail();
value = tail.value;
tail.prev.next = null;
tail.prev = null;
}
size--;
return value;
}
private Node getTail() {
Node node = head;
while (node != null && node.next != null)
node = node.next;
return node;
}
private static final class Node {
private final String value;
private Node next;
private Node prev;
public Node(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}
}
public final class ActionManager {
private final LinkedList actions = new LinkedList();
private final LinkedList undoActions = new LinkedList();
public int getTotalActions() {
return actions.getSize();
}
public void doAction(String action) {
actions.add(action);
}
public void undo() {
if (actions.getSize() == 0)
throw new IllegalArgumentException();
undoActions.add(actions.remove());
}
public void redo() {
if (undoActions.getSize() == 0)
throw new IllegalArgumentException();
actions.add(undoActions.remove());
}
@Override
public String toString() {
return "total: " + actions.getSize() + ", undo: " + undoActions.getSize();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.