首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >检查ints的列表是否成对排序。

检查ints的列表是否成对排序。
EN

Code Review用户
提问于 2017-11-09 16:27:50
回答 2查看 577关注 0票数 4

在类中,我们创建了自己的ArrayList类;我编写的代码旨在与ArrayIntList类交互。我正在寻找一般性的反馈意见,以帮助我下次编写代码。我还想知道在我的方法中更改size变量的值是否“安全”(size表示ArrayIntList的当前大小)。

编写一个方法isPairwiseSorted,返回一个整数列表是否成对排序(如果是,否则为false )。如果每一对连续的数字都是按排序(不递减)顺序排列的,则认为列表是成对排序的。例如,如果一个名为list的变量存储以下值序列:3,8,2,5,19,24,-3,0,4,8,205,42,那么list.isPairwiseSorted()调用应该返回true,因为这个列表的连续对都是排序的:(3,8),(2,5),(19,24),(-3,0),(4,4),(8,205)。注意,最后的额外值42对结果没有影响,因为它不是对的一部分。如果列表存储了以下内容:1,9,3,17,4,28,-5,-3,0,42,308,408,19,17,2,4,那么该方法应该返回false,因为这对(19,17)没有排序。如果一个列表太短以至于没有对,那么它就被认为是成对排序的。如果列表的长度为奇数,则应该忽略最后一个元素,因为它没有对。换句话说,如果列表的其余部分是成对排序的,直到最后一个未配对元素,那么您的方法应该返回true。假设在ArrayIntList类中添加了以下字段:公共类ArrayIntList {私有int[] elementData;私有int大小;//您的代码在这里}

这是我的密码:

代码语言:javascript
运行
复制
public boolean isPairwiseSorted() {
    if (size <= 1) {
        // Pairwise sorted for lists smaller than two elements
        return true;
    }
    boolean reIncrementSize = false;
    if (size % 2 != 0) {
        reIncrementSize = true;
        size--;
    }
    for(int i = 0; i < size; i+=2) {
        // Pairwise sorted if elements are in increasing order
        if (elementData[i] > elementData[i + 1]) {
            return false;
        }
    }
    if (reIncrementSize) {
        size++;
    }
    return true;
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2017-11-09 17:00:11

if (size <= 1) { // Pairwise sorted for lists smaller than two elements return true; }

特殊情况有时是有用的,但是KISS:这是简化代码还是使代码变得更复杂而没有好处?

boolean reIncrementSize = false; if (size % 2 != 0) { reIncrementSize = true; size--; } .... if (reIncrementSize) { size++; }

呀!确实不应该对类的状态进行临时更改。但是,如果您确实必须这样做,您应该使用try ... finally来保证它们是撤消的。这里的临时更改引入了一个bug:如果我们点击return false,那么大小就会永久减少。

for(int i = 0; i < size; i+=2) { // Pairwise sorted if elements are in increasing order if (elementData[i] > elementData[i + 1]) { return false; } }

为什么size会暂时减少?我认为这是为了避免elementData[i + 1]中的越界数组访问。但你也可以做得很好,让它成为你的防守条件:

代码语言:javascript
运行
复制
    for(int i = 0; i + 1 < size; i+=2) {
票数 6
EN

Code Review用户

发布于 2017-11-09 17:40:38

boolean reIncrementSize = false; if (size % 2 != 0) { reIncrementSize = true; size--; }

您可以创建一个新的变量来跟踪您是否进行了更改。考虑一下

代码语言:javascript
运行
复制
    int pairedSize = (pairedSize % 2 == 0) ? size : size - 1;

现在你可以改变了

for(int i = 0; i < size; i+=2) {

代码语言:javascript
运行
复制
    for (int i = 0; i < pairedSize; i += 2) {

移除

if (reIncrementSize) { size++; }

临时变量就会消失。你不需要更新。

我们不知道编译器是如何优化的,但是考虑到如果size存储在内存中,它仍然需要加载到处理器可以直接访问的东西中。因此,我们可以将size加载到寄存器中,更新该寄存器,然后不将寄存器保存回size。这比这做的工作要少。

很明显,您的方法并不是线程安全的。如果在运行此方法时访问了size,则它的值可能与它应该的值不匹配。

有时更新然后恢复是有意义的,但这似乎不是其中之一。即使您修复了return不恢复中的错误,也存在其他危险。这是更多的工作。

您希望更改是临时的,并且不管如何,都必须创建一个临时变量。因此,只需对临时变量进行临时更改。这给了你确切的改变,你想要没有额外的脚手架,使其工作。该代码既短又健壮。

这也更具可读性。现在有人可以看到,我们的新值是一个pairedSize,它总是偶数。

// Pairwise sorted if elements are in increasing order if (elementData[i] > elementData[i + 1]) { return false; }

注释与代码不匹配。考虑一下

代码语言:javascript
运行
复制
        if (elementData[i] > elementData[i + 1]) {
            // Not pairwise sorted if elements are in decreasing order
            return false;
        }

另一种说法是正确的,但令人困惑,因为它没有描述随后的代码。

实际上,如果没有评论的话,阅读起来可能会更容易。然后,我们将从一个名为false的方法返回isPairwiseSorted,因为ith元素大于下一个元素。这应该告诉我们,如果减少,就不会按两两排序。

在原来的代码中,您应该对reIncrementSize有一个注释。这是令人困惑的,因为您将它设置为一个位置,并在另一个地方使用它,而真正的效果是size中的临时更改。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/180016

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档