英文:
Linked List prepend and toString methods
问题
我正在尝试输出列表,我已经在列表前添加了3个字符串,但输出全部为空。代码似乎在添加和输出方面都是正确的,但它只是不输出数据。我关注的方法是prepend和toString。
public class StringList {
/* ------------------------------------------------------- *
* 内部类 *
* ------------------------------------------------------- */
/**
* StringList 使用的节点。
*/
private class StrNode {
String data;
StrNode next;
}
/* ------------------------------------------------------- *
* 实例变量 *
* ------------------------------------------------------- */
private StrNode head; // 单链表的头部。
/* ------------------------------------------------------- *
* 实例方法 *
* ------------------------------------------------------- */
/**
* 无参数构造函数。
*/
public StringList() {
head = null;
}
/**
* 在列表开头添加一个项目。
*
* @param s 要添加的项目
*/
public void prepend(String s) {
var newNode = new StrNode();
// TODO: 在列表开头添加一个项目。
if (head == null) {
head = newNode;
} else {
newNode.next = head.next;
head.next = newNode;
}
}
/**
* 在列表末尾添加一个项目。
*
* @param s 要添加的项目
*/
public void append(String s) {
// TODO: 在列表末尾添加一个项目。
}
/**
* 如果关键字存在,则在第一个关键字实例之后插入一个项目。
*
* @param s 要插入的项目
* @param key 要在其后插入项目的列表中的项目
* @return 插入是否成功
*/
public boolean insertAfter(String s, String key) {
// TODO: 如果关键字存在,则在第一个关键字实例之后插入一个项目。
return false;
}
/**
* 从列表中删除第一个项目实例。
*
* @param key 要从列表中删除的项目的值。
* @return 删除是否成功。
*/
public boolean delete(String key) {
// TODO: 从列表中删除第一个项目实例。
return false;
}
/**
* 返回列表中第n个项目的值。
*
* @param n 要返回的项目的从零开始的索引
* @return 第n个项目的值
*/
public String get(int n) {
// TODO: 返回列表中第n个项目的值。
// 注意:如果n超出界限,抛出IndexOutOfBoundsException。
return null;
}
/**
* 返回列表中的项目数。
*
* @return 列表中的项目数
*/
public int length() {
// TODO: 返回列表中的项目数。
int length = 0;
StrNode current = head;
while (current != null) {
length++;
current = current.next;
}
return length;
}
/**
* 返回由所有项目组成的字符串,由空格分隔。
*
* 最后一个项目后面也会有一个空格。
*
* @return 列表的值
*/
@Override
public String toString() {
// TODO: 返回由所有项目组成的字符串,由空格分隔。
String result = "{";
StrNode current = this.head;
while (current != null) {
result += current.data + " ";
current = current.next;
}
return result + "}";
}
}
驱动程序:
public class Main {
/**
* @param args 命令行参数
*/
public static void main(String[] args) {
StringList s = new StringList();
s.prepend("one");
s.prepend("two");
s.prepend("three");
System.out.println(s);
}
}
英文:
I am trying to output the list, I have prepended 3 strings to the list and it all outputs null. The code seems to prepend and output correctly, however it just doesn't output the data. The methods I am focusing on are prepend and toString.
``
public class StringList {
/* ------------------------------------------------------- *
* Inner classes *
* ------------------------------------------------------- */
/**
* The node used by StringList.
*/
private class StrNode {
String data;
StrNode next;
}
/* ------------------------------------------------------- *
* Instance variables *
* ------------------------------------------------------- */
private StrNode head; // the head of the singly-linked list.
/* ------------------------------------------------------- *
* Instance methods *
* ------------------------------------------------------- */
/**
* No-argument constructor.
*/
public StringList() {
head = null;
}
/**
* Adds an item to the start of the list.
*
* @param s the item to add
*/
public void prepend(String s) {
var newNode = new StrNode();
// TODO: Adds an item to the start of the list.
if(head == null) {
head = newNode;
}
else {
newNode.next = head.next;
head.next = newNode;
}
}
/**
* Adds an item to the end of the list.
*
* @param s the item to add
*/
public void append(String s) {
// TODO: Adds an item to the end of the list.
}
/**
* Inserts an item after the first instance of a key if the key exists.
*
* @param s the item to insert
* @param key the item in the list to insert after
* @return whether the insertion was successful
*/
public boolean insertAfter(String s, String key) {
// TODO: Inserts an item after the first instance of a key if the key exists.
return false;
}
/**
* Deletes the first instance of an item from the list.
*
* @param key the value of the item to delete from the list.
* @return whether the deletion was successful.
*/
public boolean delete(String key) {
// TODO: Deletes the first instance of an item from the list.
return false;
}
/**
* Returns the value of the nth item in the list.
*
* @param n the zero-based index of the item to return
* @return the value of the nth item
*/
public String get(int n) {
// TODO: Returns the value of the nth item in the list.
// Note: if n is out of bounds, raise an IndexOutOfBoundsException.
return null;
}
/**
* Returns the number of items in the list.
*
* @return the number of items in the list
*/
public int length() {
// TODO: Returns the number of items in the list.
int length = 0;
StrNode current = head;
while(current != null) {
length++;
current = current.next;
}
return length;
}
/**
* Returns a string of all the items in the list separated by a space.
*
* The last item will have a space after it too.
*
* @return list of the list's values
*/
@Override
public String toString() {
// TODO: Returns a string of all the items in the list separated by a space.
String result = "{";
StrNode current = this.head;
while(current != null) {
result += current.data + " ";
current = current.next;
}
return result + "}";
}
}
``
Driver:
``
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
StringList s = new StringList();
s.prepend("one");
s.prepend("two");
s.prepend("three");
System.out.println(s);
}
}
``
答案1
得分: 1
错误出现在你的prepend(String s)
方法中。仔细看一下 - 你从未使用过s
,也就是说,你传递给这个方法的字符串从未被存储。你只需要将newNode.data = s;
添加为第二行。然而,第二个错误是StrNode
对象未正确连接。
解决方案
public void prepend(String s) {
var newNode = new StrNode();
newNode.data = s;
if (head == null) {
head = newNode;
} else {
// 首先,我们将当前的头节点设置为新节点的后继节点
newNode.next = head;
// 然后,我们将新节点设置为头节点(因为我们在前面插入)
head = newNode;
}
}
然后输出如预期:
{three two one }
附加评论
你的toString()
方法在循环中使用了+
来连接字符串。这是低效的,应该用StringBuilder
来代替。StringBuilder
还可以方便地删除“one”后面的最后一个空格:
@Override
public String toString() {
StringBuilder result = new StringBuilder("{");
StrNode current = this.head;
while (current != null) {
result.append(current.data).append(" ");
current = current.next;
}
result.setLength(result.length() - 1);
return result + "}";
}
英文:
The error is in your prepend(String s)
method. Have a close look -you never use s
, i.e., the string which you pass to this method is never stored. You simply have to add newNode.data = s;
as the second line. However, there is also a second error as the StrNode
objects are not linked correctly.
Solution
public void prepend(String s) {
var newNode = new StrNode();
newNode.data = s;
if (head == null) {
head = newNode;
} else {
// First, we set the current head as the successor of the new newNode
newNode.next = head;
// Then, we set the new newNode as head (as we prepend)
head = newNode;
}
}
Then the output is as aspected:
{three two one }
Additional Comment
Your toString()
method concats strings in a loop with +
. That is inefficient and should be replaced by a StringBuilder
. The StringBuilder also allows easily to delete the last space after "one":
@Override
public String toString() {
StringBuilder result = new StringBuilder("{");
StrNode current = this.head;
while (current != null) {
result.append(current.data).append(" ");
current = current.next;
}
result.setLength(result.length() - 1);
return result + "}";
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论