我在处理我正在制作的计划时遇到了一些困难。我试图从一些同行那里得到帮助,但我们无法弄明白。我确定它很简单,但我没有足够的经验来解决这个问题。这是作业:
在古老的土地上,美丽的公主夏娃有许多追求者。她决定采用以下程序来确定她会嫁给哪个追求者。首先,所有的追求者将一个接一个地排队并分配号码。第一个追求者是数字1,第二个数字是2,依此类推到最后一个追求者,数字n。从第一个位置的追求者开始,她将计算三个追求者(由于她名字中的三个字母),并且第三个追求者将被取消赢得她的手并从线上移除。然后夏娃会继续,再计算三个追求者,并消除每三个追求者。当她到达终点时,她会从头开始计算。
例如,如果有六个追求者,则淘汰过程将如下进行:
123456 Initial list of suitors: start counting from 1.
12456 Suitor 3 eliminated: continue counting from 4.
1245 Suitor 6 eliminated: continue counting from 1.
125 Suitor 4 eliminated: continue counting from 5.
15 Suitor 2 eliminated: continue counting from 5.
1 Suitor 5 eliminated: 1 is the lucky winner.
编写一个程序,创建一个循环的节点链表,以确定如果有n个追求者,你应该站在哪个位置与公主结婚。您的程序应该通过删除与过程中每个步骤中消除的suitor相对应的节点来模拟消除过程。
这是我到目前为止所拥有的:
public class CircularLinkedList
{
private class Node
{
private int candidate;
private Node next;
public Node()
{
candidate = 0;
next = null;
}
public Node(int newCandidate)
{
candidate = newCandidate;
next = null;
}
public Node(int newCandidate, Node nextValue)
{
candidate = newCandidate;
next = nextValue;
}
}//end inner class
private Node first;
private Node last;
public CircularLinkedList()
{
first = null;
last = null;
}
public boolean isEmpty() //checks to see if the list is empty
{
return first == null;
}
public int size() //checks the size
{
int count = 0;
Node p = first;
while(p != last)
{
count++;
p = p.next;
}
return count;
}
public void add(int e) //adds a Node to the list
{
Node newEntry = new Node(e, first);
if(first==null)
{
last = newEntry;
first = last;
}
else
{
last.next = newEntry;
last = last.next;
}
}
public void removeAfter(Node e) //removes the Node after the current Node
{
e.next = e.next.next;
}
public void remove() //removes every third Node
{
Node curNode = first;
int size = size();
while(size>1)
{
curNode = curNode.next;
removeAfter(curNode);
size -= 1;
}
}
public void print() //prints the list
{
Node ref = first;
for(int index = -1;index<size();index++)
{
System.out.print(ref.candidate + " ");
ref = ref.next;
}
}
}
主要方法......
import java.util.Scanner;
public class CircularDemo
{
public static void main(String[] args)
{
CircularLinkedList c = new CircularLinkedList();
System.out.println("How many candidates are there?");
Scanner keyboard = new Scanner(System.in);
int input = keyboard.nextInt();
if(input<=0)
System.out.println("No candidates presented.");
else if(input==1)
System.out.println("Candidate 1 is the only candidate and the winner.");
else
{
for(int i = 1; i<=input; i++)
{
c.add(i);
}
System.out.print("The candidates are: ");
c.print();
System.out.println("\n" + c.size()); //tests size
while(c.size()!=1)
{
c.remove();
c.print();
}
System.out.print("\nThe winner is: ");
c.print();
}
}
}
我遇到的主要问题是它试图删除main方法中的每个第3个节点的部分(while(c.size()!= 1))。它会在此之前正确打印所有内容。一旦达到这一点,它就像程序死了。如果我取出while循环,胜利者部分将打印出来,因此循环中的某些内容正在搞乱。
我想我知道问题出在哪里。第一个是size()方法。它比实际打印少一个。如果我放6,它认为有5个。由于这是一个循环链表,我不能让它继续计数,直到它达到空。永远不会有一个。这是一个问题,但我不确定如何解决它。
第二,我认为是在remove()和removeAfter()方法中。我试过测试它,但程序只是在尝试读取它时结束。我不确定这些程序是怎么回事,而且我有足够的时间试图弄清楚如何创建它......所以这是最大的问题。
另外还有我迄今为止得到的输出,只是为了给你一个想法:
How many candidates are there?
6 //user input
The candidates are: 1 2 3 4 5 6
5 //output for size()
1 2 6 //output first time through while loop
//output for winner still not showing up
编辑1 - 在删除循环时更新。输出已更新。
答案 0 :(得分:2)
尝试将最后一个节点分配给第一个节点,以使其成为循环链接列表。 (在add()中分配last.next = first)
答案 1 :(得分:0)
这是要点,使用OOP方法和一些输入验证。
public class SuitorProblem
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int totalSuitors = 0;
boolean goodInput;
System.out.print("Enter the number of suitors: ");
//************************************ INPUT VALIDATION ***********************************************
do
{
try
{
totalSuitors = sc.nextInt();
while (totalSuitors <= 0)
{
System.out.print("Enter a positive integer value greater than 0: ");
totalSuitors = sc.nextInt();
}
goodInput = true;
}
catch (InputMismatchException e) // if not integer, prompt the user to go back
{
System.out.print("Enter a positive integer value greater than 0: ");
sc.nextLine(); // clear input
goodInput = false;
}
} while (!goodInput);
//********************************************************************************************************
ListOfSuitors suitorList = new ListOfSuitors();
for (int i = 1; i <= totalSuitors; i++)
suitorList.addEnd(i);
System.out.print("Before elimination process, the line-up of suitors is: ");
System.out.print(suitorList.toString());
System.out.println();
suitorList.deleteSuitors();
System.out.print("After elimination process, the winning suitor is: ");
System.out.print(suitorList.toString());
}
}
// I use an extension of CircularLinkedList of type Integer, so I can have access to the methods in CircularLinkedList to manipulate the ListOfSuitors, which is a LinkedList of ints.
class ListOfSuitors extends CircularLinkedList<Integer>
{
// default constructor
public ListOfSuitors()
{
}
// This method is used to find the next index that needs to be deleted
private int findIndexOfLoser(int element)
{
Node<Integer> current = head;
int index = 0;
while (current.element != element)
{
current = current.next;
index++;
}
return index;
}
// This method counts 3 spaces over then deletes a suitor by calling the delete method on the deletionIndex
public void deleteSuitors()
{
Node<Integer> current = head;
while (size != 1)
{
for (int i = 1; i < 3; i++)
{
current = current.next;
}
int deletionIndex = findIndexOfLoser(current.element);
current = current.next;
delete(deletionIndex);
}
}
}
// This is the generic circular linkedList that I extend my ListOfSuitors class from, and which holds the methods needed to manipulate the ListOfSuitors
class CircularLinkedList<E>
{
// since these will only be accessed by the subclass listOfSuitors, they are declared protected to increase security.
protected Node<E> head = null;
protected Node<E> tail = null;
protected int size;
public CircularLinkedList()
{
}
// method for adding a new end Node in circularLinkedList
public void addEnd(E element) // adapted from ch24 PowerPoint
{
if (size == 0)
{
head = tail = new Node<E>(element, head);
}
else
{
tail = tail.next = new Node<E>(element, head);
}
size++;
}
// Method for deleting a Node at a specified index in the circularLinkedList. May cause IndexOutOfBounds, so that must be handled within the method
public void delete(int index)
{
if (index < 0 || index > size - 1)
throw new IndexOutOfBoundsException("That's not a correct index.");
else if (index == 0)
deleteFirst();
else if (index == size - 1)
deleteEnd();
else
{
Node<E> previous = head;
Node<E> current = head.next;
for (int i = 1; i < index; i++)
{
previous = previous.next;
current = current.next;
}
previous.next = current.next;
current.next = null;
size--;
}
}
// method for deleting the end Node in circularLinkedList
public void deleteEnd()
{
if (size == 1)
{
head = tail;
tail.next = null;
} else if (size > 1)
{
Node<E> current = head;
while (current.next != tail)
current = current.next;
tail.next = null;
current.next = head;
tail = current;
}
size--;
}
// method for deleting the first Node in circularLinkedList
public void deleteFirst()
{
if (size == 1)
{
head = tail;
tail.next = null;
} else if (size > 1)
{
Node<E> current = head;
head = head.next;
current.next = null;
tail.next = head;
}
size--;
}
// In this method, I create my own toString in order to elegantly print the output of the suitorList in an efficient way, using StringBuilder.
public String toString()
{
Node<E> current = head;
StringBuilder suitorList = new StringBuilder();
if (size >= 1)
{
suitorList.append(current.element);
current = current.next;
}
for (int i = 1; i < size; i++)
{
suitorList.append(" ").append(current.element.toString());
current = current.next;
}
return suitorList.toString();
}
}
// this class is for the Node, which is what each int suitor is turned into when it is added to the ListOfSuitors
class Node<E>
{
protected E element = null;
protected Node<E> next = null;
// default constructor
public Node()
{
}
// overloaded constructor
public Node(E element, Node<E> next)
{
this.element = element;
this.next = next;
}
public Node(E element)
{
this.element = element;
}
public Node(Node<E> next)
{
this.next = next;
}
}