【发布时间】:2015-11-17 06:12:50
【问题描述】:
我正在做一项课堂作业。我要对一副纸牌进行分类(不必担心西装)我试图让 cmets 尽可能地解释它。我正试图让这种工作正常。它只能查看前两张卡,如果需要,可以交换它们,并且可以将顶部的卡移动到底部。我想要最高的数字在前面。
在大约第 18 行(我的第一个 for 循环)上,我试图做的是使用带有 int i 的 for 语句循环遍历数组。带有 int j 的嵌套 for 循环应该检查前两个,如果顶部(索引 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;
}
}
【问题讨论】:
-
你有什么证据表明“循环没有通过阵列推进”?
-
我的建议:去维基百科查找“冒泡排序”。然后根据任务进行调整。问问自己,你怎么知道什么时候停下来?您实际上似乎走在了正确的轨道上,但是尝试考虑数组索引
i和j只会让您感到困惑,因为您根本没有处理典型的数组并且您不能使用索引。 -
我想我已经接近我刚刚提出的内容了。唯一的事情是我希望它在未排序时执行我的循环。 isSorted 方法是无效的,所以我不能做 while(!d.isSorted)。所以我必须弄清楚这一点。如果我能做 while(!d.isSorted) 我认为它会起作用。
-
将
isSorted设为void方法是您的想法,还是讲师的想法?如果是教练的想法,要么是一个非常糟糕的主意,要么是他为了使其更具挑战性而投入的扳手。您可以使用isSorted,但您必须意识到它通过使用异常“返回”其结果。您必须使用try...catch块才能使用它。 -
导师成功了。我刚刚创建了自己的布尔变量“notSorted”,并在我的排序方法中将其设置为 true。然后将 for 循环包装在 while 循环中,检查 notSorted 是否为 true,默认情况下为 true。它所做的第一件事是将 notSorted 设置为 false。现在我只需要弄清楚我在什么时候将 notSorted 设置为 true。 (我认为)