好吧,尽管这个话题可能很模糊,但让我首先承认这是一个与家庭作业有关的问题。所以,如果你对这些问题有一些有趣的报复,请注意。
不过,我已经和它坐了好几个小时了,我很不好意思还没有"得到它"。
所以我希望你们中的一些人能告诉我我错过了什么。
我要创建一个类,它存储一个变量,并记住该类的下一个对象。
以下是我的主要课程:
public class SticksAndStones {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String response = "n";
Stick currentStick = null;
int numberOfSticks = 0;
while (response.equals("n")) {
System.out.println("What diameter should the stick have?");
response = Integer.toString(scan.nextInt());
currentStick = new Stick(Integer.parseInt(response), currentStick);
numberOfSticks++;
System.out.println("Are you done adding sticks? ('n' or 'y')");
response = scan.next();
while (!response.equals("y") && !response.equals("n")) {
System.out.println("Please type 'y' for yes, or 'n' for no.");
response = scan.next();
}
}
for (int i = 0; i < numberOfSticks; i++) {
System.out.println(currentStick.getDiameter());
currentStick = currentStick.getNext();
}
}
}
我的Stick类看起来像:
public class Stick {
int diameter;
Stick stick;
public Stick(int diameter, Stick stick) {
this.diameter = diameter;
this.stick = stick;
}
public int getDiameter() {
return diameter;
}
public Stick getNextStick() {
return stick;
}
现在,正如你所看到的,我的班级似乎能够记住上一棒,但无论如何都记不住下一棒。
这是一个问题,因为在我的SticksAndStones课程的底部,我试图打印出每个棍子的直径,但它们没有按正确的顺序打印出来。换句话说,第一根棍子是最后一根出来的,最后一根棍子是第一根出来的。
我不需要。我需要他们从另一个方向出来。第一次坚持,就像第一次坚持。
我们在这项任务中唯一的限制是,我们不能使用任何形式的数组、列表、表或数据库
我是不是错过了一些非常简单的东西?
PS:会使用"作业"标签,但不允许。
更新
新贴纸和石头类:
import java.util.Scanner;
public class SticksAndStones {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String response = "n";
int numberOfSticks = 0;
Stick firstStick = null;
Stick currentStick = null;
;
Stick prevStick = null;
while (response.equals("n")) {
System.out.println("What diameter should the stick have?");
response = Integer.toString(scan.nextInt());
if (firstStick == null) {
firstStick = new Stick(Integer.parseInt(response));
prevStick = firstStick;
} else {
currentStick = new Stick(Integer.parseInt(response));
prevStick.setNextStick(currentStick);
prevStick = currentStick;
}
numberOfSticks++;
System.out.println("Are you done adding sticks? ('n' or 'y')");
response = scan.next();
while (!response.equals("y") && !response.equals("n")) {
System.out.println("Please type 'y' for yes, or 'n' for no.");
response = scan.next();
}
}
currentStick = firstStick;
for (int i = 0; i < numberOfSticks; i++) {
System.out.println(currentStick.getDiameter());
currentStick = currentStick.getNextStick();
}
}
}
我的贴纸类:
public class Stick {
int diameter;
Stick stick;
Stick nextStick;
public Stick(int diameter, Stick stick) {
this.diameter = diameter;
this.stick = stick;
}
public Stick(int diameter) {
this.diameter = diameter;
}
public int getDiameter() {
return diameter;
}
public Stick getNextStick() {
return stick;
}
public void setNextStick(Stick nextStick) {
this.nextStick = nextStick;
}
}
一个微笑和一个拥抱,谁能告诉我为什么我打了一个NullPointerException。
一点点重构会有很大帮助:
由于不可能知道构造时间next
Stick是什么,构造函数不应将其作为参数,或者至少可以选择创建没有nextStick
的对象
public Stick(int diameter) {
this.diameter = diameter;
}
在你开始循环添加贴纸之前,你保留了3个参考:
Stick firstStick = null;
Stick currentStick;
Stick prevStick = null;
在你的while loop
中,在你询问直径后,你会检查初始棒是否已经定义,或者你是否在不断添加棒。。。
if (firstStick == null) {
firstStick = new Stick(Integer.parseInt(response));
prevStick = firstStick;
} else {
currentStick = new Stick(Integer.parseInt(response));
prevStick.setNextStick(currentStick);
prevStick = currentStick;
}
在循环外打印信息时,您将currentStick
设置为指向firstStick
,并始终循环
currentStick = firstStick;
for (int i = 0; i < numberOfSticks; i++) {
System.out.println(currentStick.getDiameter());
currentStick = currentStick.getNextStick();
}
更新
根据您对Stick
级的更改
这应该是的样子
public class Stick {
int diameter;
Stick stick;
public Stick(int diameter) {
this.diameter = diameter;
}
public int getDiameter() {
return diameter;
}
public Stick getNextStick() {
return stick;
}
public void setNextStick(Stick stick) {
this.stick = stick;
}
}
很明显,当第一次创建下一个棒时,Stick
无法"记住"它,因为还没有下一个。但是,如果唯一的Stick
构造函数将前一个stick作为参数,那么——尽管它很难看——它可以修改前一个tick以引用新的stick:
public Stick(int diameter, Stick previousStick) {
this.diameter = diameter;
this.previous = previousStick;
previousStick.next = this;
}
当然,假设Stick类中有一个新的和一个重命名的字段。
然而,最好在创建新的Stick
之后添加前向引用,这样Stick
构造函数就不会修改其参数:
public Stick(int diameter, Stick previousStick) {
this.diameter = diameter;
this.previous = previousStick;
}
// ... main() ...
Stick newStick = new Stick(Integer.parseInt(response), currentStick);
currentStick.setNext(newStick);
此外,如果您希望能够向前遍历链表(这就是您正在创建的),那么您需要在某个位置保留对第一个Stick
的引用。如果不需要反向遍历列表,则可以省略对该引用的跟踪(在这种情况下,Stick
构造函数不需要将Stick
作为参数)。剩下的我交给你解决。
避免添加第二个引用以使每个Stick记住前一个引用的另一个选项是编写一个递归方法,对Stick链进行订单后遍历:
public static void printSticks(Stick s) {
if (s != null) {
printSticks(s.getNextStick());
System.out.println(s.getDiameter());
}
}
这种方法不适合很长的列表,因为它会出现堆栈溢出错误,但它是一个例子,说明了如何使用递归算法来绕过您一直在使用的数据结构的限制。
您可以让您的班级了解上一小节和下一小节。
public class Stick {
private int diameter;
private Stick previousStick;
private Stick nextStick;
public Stick(int diameter, Stick previousStick, Stick nextStick) {
setDiameter(diameter);
setPreviousStick(previousStick);
setNextStick(nextStick);
}
//getters and setters
}
然后在您的主方法中,您需要适当地设置它们。这是你应该"做作业"的地方。以下是一些入门帮助。思考如何使用它。
Stick lastStick;
Stick currentStick;
lastStick = currentStick;
currentStick = new Stick(diameter, lastStick, null);
lastStick.setNextStick(currentStick);