我想不出在 Gradually Decreasing Carousel 应用程序中增加递减量的条件

I can't think of a condition to increase the decrement in Gradually Decreasing Carousel app

Decrementing Carousel是一个容器,接受int元素。 DecrementingCarousel 具有最大容量,通过构造函数指定。 DecrementingCarousel在创建时处于累加状态:可以通过addElement方法添加元素,通过run方法可以产生一个CarouselRun对象。一旦 run 方法被调用,DecrementingCarousel 处于 运行ning 状态:它拒绝添加更多元素。

CarouselRun 允许迭代轮播的元素,使用 next 方法将它们一个一个递减。 next returns 当前元素的值。

CarouselRun 按照元素的插入顺序遍历元素。 当一个元素减少到零时,CarouselRun 将在进一步的迭代中跳过它。当没有更多元素可用于递减时,CarouselRun returns -1.

CarouselRun还有isFinished方法,表示轮播是否有运行个元素要减。

规格详情

boolean addElement(int element) - 添加一个元素。如果元素为负或零,则不添加该元素。如果容器已满,则不要添加该元素。如果调用了 运行 方法来创建 CarouselRun,则不要添加该元素。如果元素添加成功,return true。 Return false 否则。 CarouselRun run() - returns 一个 CarouselRun 来迭代元素。如果之前已经调用了运行方法,那么它必须return nullDecrementingCarousel可能只会生成一个CarouselRun对象。

CarouselRun 有两个 public 方法:

int next() - returns当前元素的当前值,然后将当前元素减一并切换到插入顺序的下一个元素。跳过零元素。当没有更多元素减少时,returns -1。 boolean isFinished() - 当没有更多的元素要减少时,returns true。否则,returns false代码:

public class DecrementingCarousel {
    private final int capacity;
    static int[] carousel;
    int index;
    boolean isRun;

    {
        index = 0;
        isRun = false;
    }

    public DecrementingCarousel(int capacity) {
        this.capacity = capacity;
        carousel = new int[capacity];
    }

    public boolean addElement(int element){
        if (element > 0 && index < capacity && !isRun) {
            carousel[index++] = element;
            return true;
        }
        return false;
    }

    public CarouselRun run() {
        if (!isRun) {
            isRun = true;
            return new CarouselRun();
        }
        return null;
    }
}

CarouselRun 中的方法:

public class CarouselRun {
    protected final int[] array = DecrementingCarousel.carousel.clone();
    protected int position = 0;

    public int next() {
        if (isFinished())
            return -1;
        else {
            while (array[position %= array.length] <= 0) {
                position++;
            }
        }
        return array[position++]--;
    }

    public boolean isFinished() {
        for (int el : array)
            if (el > 0)
                return false;
        return true;
    }
}

所以这个子类必须通过逐渐递增的递减来递减元素。当你第一次需要递减一个元素时,把它减1。下次你需要递减同一个元素时,把它减2。下次减3,然后减4,依此类推。

public class GraduallyDecreasingCarousel extends DecrementingCarousel{
    public GraduallyDecreasingCarousel(final int capacity) {
        super(capacity);
    }

    @Override
    public CarouselRun run() {
        if (!isRun) {
            isRun = true;
            return new GraduallyDecreasingCarouselRun();
        }
        return null;
    }
}

public class GraduallyDecreasingCarouselRun extends CarouselRun {
    int decrement = 1;

    @Override
    public int next() {
        int beforeDecreasing;
        if (isFinished())
            return -1;
        else {
            while (array[position %= array.length] <= 0) {
                position++;
                if (position == array.length) {
                    decrement++;
                }
            }
        }
        beforeDecreasing = array[position];
        array[position++] -= decrement;
        return beforeDecreasing;
    }

主要方法:

public class Main {
    public static void main(String[] args) {
        DecrementingCarousel carousel = new GraduallyDecreasingCarousel(7);

        carousel.addElement(20);
        carousel.addElement(30);
        carousel.addElement(10);

        CarouselRun run = carousel.run();

        System.out.println(run.isFinished()); //false

        System.out.println(run.next()); //20
        System.out.println(run.next()); //30
        System.out.println(run.next()); //10

        System.out.println(">>>>>>>>>>");

        System.out.println(run.next()); //19
        System.out.println(run.next()); //29
        System.out.println(run.next()); //9

        System.out.println(">>>>>>>>>>");

        System.out.println(run.next()); //17
        System.out.println(run.next()); //27
        System.out.println(run.next()); //7

        System.out.println(">>>>>>>>>>");

        System.out.println(run.next()); //14
        System.out.println(run.next()); //24
        System.out.println(run.next()); //4

        System.out.println(">>>>>>>>>>");

        System.out.println(run.next()); //10
        System.out.println(run.next()); //20

        System.out.println(">>>>>>>>>>");

        System.out.println(run.next()); //5
        System.out.println(run.next()); //15

        System.out.println(">>>>>>>>>>");

        System.out.println(run.next()); //9

        System.out.println(">>>>>>>>>>");

        System.out.println(run.next()); //2

        System.out.println(run.isFinished()); //true
        System.out.println(run.next()); //-1
    }
}

它在 main 中运行良好,但无法通过测试 IDK 如何在 GraduallyDecreasingCarouselRun

中更改下一个方法

尝试对下一次调用进行计数,并在其大于要减少的元素数量时重置计数器,但当有一个元素离开时它无法正常工作

哇。需要很长时间才能完全理解这个问题。 当您完全填满阵列的容量时会出现此问题。

在这种情况下,您检查在 while 循环内递增 decrease 的值可能会失败,因为取模赋值会将位置“重置”为 0 而无需进入循环,因此会跳过递增的decrease.

使代码更容易理解的解决方案是将模赋值与 while 条件分离。这速度较慢并且使用更多代码,但更容易理解并且也将 position 处理为规范中所述的“下一个”位置。优化是可能的,但我只是 post 未优化的代码:

public int next() {
    int beforeDecreasing;
    if (isFinished())
        return -1;
    else {
        beforeDecreasing = array[position];
        array[position] -= decrement;
        do {
            position++;
            if (position == array.length) {
                decrement++;
                position = 0;
            }
        } while ((array[position] <= 0) && !isFinished());
    }
    return beforeDecreasing;
}

为了“快速获胜”,我建议另一种解决方案:更改位置并检查 decrease 的增量:(仅来自 else 分支内的片段)

int oldPosition = position;
while (array[position %= array.length] <= 0) {
    position++;
}
if (oldPosition > position) {
    decrement++;
}

这个练习中最复杂的问题是如何跟踪轮播的索引。我建议从 next() 方法中解耦索引跟踪。这种特征应该基于存储“旧减量位置”和“新减量位置”的值。这样,您可以更好地控制何时将“递减”变量从 -1 减少到 -2(并且程序知道在数组中的下一个值等于 0 时该怎么做)。在提出的解决方案中,索引跟踪功能是通过 calculateNewIndexDecrementPosition() 方法引入的。我还展示了 next() 和 isFinished() 方法,使整个 CarouselRun class 实现更清晰。

    private int calculateNewIndexDecrementPosition(int currentIndexDecrementPostion) {
        int newIndexDecrementPosition;

//If no more elements to decrease are present. Meaning the situation where there are only zeroes in the array.
        if (elementsToDecreaseWhileRunning == 0) {
//Basically get out. Could be any other value in return statement.
            return 0;
        }
//If you reached end of the array, go back to the beginning (0 index). THIS IS THE PLACE WHERE YOU DECREASE THE VALUE FROM -1 TO -2, -2 T0 -3 AND SO ON...
        if (karuzel.size() - 1 == currentIndexDecrementPostion) {
            newIndexDecrementPosition = 0;
            this.amountToDecrease -= 1;
        } else {
//otherwise go through the elements in the increasing order
            newIndexDecrementPosition = currentIndexDecrementPostion + 1;
        }
//If the value of the next element in the array also equals zero, call the function again to recalculate (increment) the index.
        if (karuzel.get(newIndexDecrementPosition) == 0) {
            newIndexDecrementPosition = calculateNewIndexDecrementPosition(newIndexDecrementPosition);
        }
        return newIndexDecrementPosition;
    }



       public int next() {
//The value of elementsToDecreaseWhileRunning comes from the addElement(int element) method, which was defined in CarouselRun Class in the following way. Every time the new element has been added to the carousel the method increases ElementsToDecrease while running by one: carouselRun.setElementsToDecreaseWhileRunning(carouselRun.getElementsToDecreaseWhileRunning() + 1).
//The variable "elementsToDecreaseWhileRunning" stores the information about how many positive numbers are still in the array. The total amount of positive numbers in the array, allows to control when to stop the whole process of decrementing.
//If ElementsToDecreaseWhileRunning equals zero, it means that all the elements in the array were brought to value zero.
        if (karuzel.isEmpty() || elementsToDecreaseWhileRunning == 0) {
            return -1;
        }

        int oldValue = karuzel.get(currentIndexDecrementPostion);

//"newValue" initialization;
        int newValue = 0;

        if (typeOfCarousel.equals("decrementing")) {
            newValue = karuzel.get(currentIndexDecrementPostion) - 1;
        } else if (typeOfCarousel.equals("gradually")) {
            newValue = karuzel.get(currentIndexDecrementPostion) + this.amountToDecrease;

//Protects against undesired, negative values in the carousel
            if (newValue < 0) {
                newValue = 0;
            }
        }
        karuzel.set(currentIndexDecrementPostion, newValue);

//The value of elementsToDecreaseWhileRunning comes from the addElement(int element) method, which was defined in CarouselRun Class in the following way. Every time the new element has been added to the carousel, counter ElementsToDecrese increases: carouselRun.setElementsToDecreaseWhileRunning(carouselRun.getElementsToDecreaseWhileRunning() + 1);
//If new value equals zero, the value of "iteration until the end" (elementsToDecreaseWhileRunning) is decreased by one. It means that, there's one less positive element in the array. The total amount of positive numbers in the array, allows to control when to stop the whole process of decrementing.
        if (newValue == 0) {
            elementsToDecreaseWhileRunning--;
        }
 //Index tracking feature
        this.currentIndexDecrementPostion = calculateNewIndexDecrementPosition(this.currentIndexDecrementPostion);

//next() based on the instructions should return value of the current element
        return oldValue;
    }
      public boolean isFinished() {
            return this.elementsToDecreaseWhileRunning <= 0;
        }

我几乎在每一行代码中都添加了注释,因为我知道该练习来自 Java 培训计划,该计划也接受初级程序员。希望这样的解决方案能被大家理解。