我正在上课。我要排序一副牌(不需要担心西装)我试着做出评论来尽我所能解释它。我试图让这种方式起作用。它只能查看前两张牌并可以根据需要进行交换,并可以将顶牌移动到底部。我想要前面最高的数字。
关于第18行(我的第一个for循环),我试图做的是使用带有int i的for语句循环遍历数组。带有int j的嵌套for循环应该检查前两个,如果top(索引0)大于下一个(索引1),那么它交换两个,所以较大的是现在在索引1而较小的是在索引0(顶部)它然后将顶部(现在较小的数字)移动到底部,使得较大的数字现在位于顶部)并且它执行此次数与数组中的数字减去1.然后我前进并且top现在应该在索引1而不是索引0然后它再次循环嵌套循环,依此类推。至少这是我想要做的。
为什么我的循环没有通过数组前进?
package algs21;
import stdlib.*;
// Exercise 2.1.14
/**
* Complete the following method to sort a deck of cards,
* with the restriction that the only allowed operations are to look
* at the values of the top two cards, to exchange the top two cards,
* and to move the top card to the bottom of the deck.
*/
public class MyDeckSort {
public static void sort (MyDeck d) {
// TODO
// You must sort the Deck using only the public methods of Deck:
// d.size ();
// d.isSorted ();
// d.topGreaterThanNext ();
// d.swapTopTwo ();
boolean notSorted=true;
while(notSorted){
notSorted=false;
for (int i=0; i<d.size();i++){
if (d.topGreaterThanNext()){
d.moveTopToBottom();
notSorted=true;
}
else{
for(int j=0;j<d.size()-1;j++){
if(!d.topGreaterThanNext()){
d.swapTopTwo();
d.moveTopToBottom();
notSorted=true;
}
}
d.moveTopToBottom();
notSorted=true;
}
//StdOut.printf ("i=%-3d %s\n", i, d.toString ());
}
}
private static double time;
private static void countops (MyDeck d) {
boolean print = true;
if (print) StdOut.println (d.toString ());
d.moveTopToBottom ();
if (print) StdOut.println (d.toString ());
Stopwatch sw = new Stopwatch ();
sort (d);
time = sw.elapsedTime ();
if (print) StdOut.println (d.toString ());
d.isSorted ();
}
public static void main (String[] args) {
int N = 10;
MyDeck d = new MyDeck (N);
countops (d);
//System.exit (0); // Comment this out to do a doubling test!
double prevOps = d.ops ();
double prevTime = time;
for (int i = 0; i < 10; i++) {
N *= 2;
d = new MyDeck (N);
countops (d);
StdOut.printf ("%8d %10d %5.1f [%5.3f %5.3f]\n", N, d.ops (), d.ops () / prevOps, time, time / prevTime);
prevOps = d.ops ();
prevTime = time;
}
}
}
/**
* The Deck class has the following API:
*
* <pre>
* MyDeck (int N) // create a randomized Deck of size N
* int size () // return the size of N
* int ops () // return the number of operations performed on this Deck
* boolean topGreaterThanNext () // compare top two items
* void swapTopTwo () // swap top two itens
* void moveTopToBottom () // move top item to bottom
* void isSorted () // check if isSorted (throws exception if not)
* </pre>
*/
class MyDeck {
private int N;
private int top;
private long ops;
private int[] a;
public long ops () {
return ops;
}
public int size () {
return N;
}
public MyDeck (int N) {
this.N = N;
this.top = 0;
this.ops = 0;
this.a = new int[N];
for (int i = 0; i < N; i++)
a[i] = i;
StdRandom.shuffle (a);
}
public boolean topGreaterThanNext () {
int i = a[top];
int j = a[(top + 1) % N];
ops += 2;
return i > j;
}
public void swapTopTwo () {
int i = a[top];
int j = a[(top + 1) % N];
a[top] = j;
a[(top + 1) % N] = i;
ops += 4;
}
public void moveTopToBottom () {
top = (top + 1) % N;
ops += 1;
}
public String toString () {
StringBuilder b = new StringBuilder ();
b.append ('[');
for (int i = top;;) {
b.append (a[i]);
i = (i + 1) % N;
if (i == top) return b.append (']').toString ();
b.append (", ");
}
}
public void isSorted () {
boolean print = false;
long theOps = ops; // don't count the operations require by isSorted
for (int i = 1; i < N; i++) {
if (print) StdOut.printf ("i=%-3d %s\n", i, toString ());
if (topGreaterThanNext ()) throw new Error ();
moveTopToBottom ();
}
if (print) StdOut.printf ("i=%-3d %s\n", N, toString ());
moveTopToBottom ();
if (print) StdOut.printf ("i=%-3d %s\n", N + 1, toString ());
ops = theOps;
}
}
答案 0 :(得分:0)
你没有在这个任务中处理数组 - 总是只是打包顶级卡。该卡只能移动到底部或切换到下一个。你需要考虑到这一点。你这里不需要数组。
编辑:编辑了我关于标记变量的注释。你已经有了一个isSorted()方法,所以不需要这样做。在卡片组上的每次迭代之后,你需要检查你是否已经排序并退出循环。
Edit2:好的,如果该方法无效,这仍然适用: 当您在包中循环卡片时,您应该有一个标记变量,用于指示该轮次中的更改。如果没有任何改变,你的包装是有序的。如果某些事情发生了变化,你需要开始另一个循环。