【问题标题】:Not sure why I am not moving through array不知道为什么我不通过阵列移动
【发布时间】: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;
    }
}

【问题讨论】:

  • 你有什么证据表明“循环没有通过阵列推进”?
  • 我的建议:去维基百科查找“冒泡排序”。然后根据任务进行调整。问问自己,你怎么知道什么时候停下来?您实际上似乎走在了正确的轨道上,但是尝试考虑数组索引 ij 只会让您感到困惑,因为您根本没有处理典型的数组并且您不能使用索引。
  • 我想我已经接近我刚刚提出的内容了。唯一的事情是我希望它在未排序时执行我的循环。 isSorted 方法是无效的,所以我不能做 while(!d.isSorted)。所以我必须弄清楚这一点。如果我能做 while(!d.isSorted) 我认为它会起作用。
  • isSorted 设为void 方法是您的想法,还是讲师的想法?如果是教练的想法,要么是一个非常糟糕的主意,要么是他为了使其更具挑战性而投入的扳手。您可以使用isSorted,但您必须意识到它通过使用异常“返回”其结果。您必须使用 try...catch 块才能使用它。
  • 导师成功了。我刚刚创建了自己的布尔变量“notSorted”,并在我的排序方法中将其设置为 true。然后将 for 循环包装在 while 循环中,检查 notSorted 是否为 true,默认情况下为 true。它所做的第一件事是将 notSorted 设置为 false。现在我只需要弄清楚我在什么时候将 notSorted 设置为 true。 (我认为)

标签: java arrays sorting


【解决方案1】:

在这个作业中你不是在处理数组 - 总是只是最上面的卡片。那张牌你只能移动到底部或与下一张交换。你需要从这个角度思考。这里不需要数组。

编辑:编辑了我关于标记变量的注释。您已经有一个 isSorted() 方法,所以不需要它。在卡片组上的每次迭代之后,您需要检查您是否已排序并退出循环。

Edit2:好的,如果该方法无效,这仍然适用: 当您循环卡片中的卡片时,您应该有一个标记变量,您可以使用它来指示该轮发生的某些变化。如果什么都没有改变,那么你的包就正常了。如果有什么改变,你需要开始另一个循环。

【讨论】:

  • 我想我已经接近我刚刚提出的内容了。唯一的事情是我希望它在未排序时执行我的循环。 isSorted 方法是无效的,所以我不能做 while(!isSorted)。所以我必须弄清楚这一点。如果我能做 while(!isSorted) 我认为它会起作用。
  • @iggyami 好的。我想知道它为什么存在:) 但是你需要这个变量,是的。
  • 好的,所以我添加了自己的标记,但我很确定我处于无限循环中,因为我认为无论 ti 做什么,它都会将 notsorted 设置为 true。它也可能需要一段时间。所以我必须弄清楚在哪里放置 notSorted=true 以及我可以从当前代码中删除的位置。不过,我走在正确的轨道上吗?
  • 是的,无限循环是肯定的。它的排序,然后只是永远循环数字
  • 不确定我的答案是否可行。我试过在几个不同的地方将标记设置回真,只在一个地方和多个地方。到目前为止都给出了无限循环,否则它将运行很长时间。排序时。
猜你喜欢
  • 1970-01-01
  • 2022-11-20
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多