【问题标题】:How to conditionally update counter algorithmically Java如何有条件地更新计数器算法Java
【发布时间】:2018-09-26 22:46:09
【问题描述】:

这个问题有点混乱,所以我将尝试通过代码和示例进行解释。

如果满足条件,我如何减少计数器?听起来很简单吧?但是,如果该方法在 for 循环中不断被调用,以便传递给它的值被重置怎么办?

示例: 我有一个包含几页的文档,但是其中一些页面是空白的,我不想计算它们。

对于第一页为空白的 5 页文档。我想完成以下行为:

page 1: nothing...
page 2: 1 of 4
page 3: 2 of 4
page 4: 3 of 4
page 5: 4 of 4

目前它包括空白页作为页数的一部分。

这是一个代码示例:

static main() {
    // et cetera
    for(Page page : pages) {
        int pageNumber = page.getPageNo();
        int pageCount = page.getTotalPageCount();
        form.getTemplate().writePageNumber(page, pageNumber,pageCount);
    }
}

因此,在主程序中,我在 for 循环中调用了一个名为 writePageNumber() 的方法,在该循环中我传入了 currentPageNumber 和 totalPage 计数。

public boolean writePageNumber(Page page, int currentPageNo, int totalPageCount) {
    if ( !page.isBlank() ) {
        this.write(currentPageNo, totalPageCount);
    }
    else if ( page.isBlank() ){
        currentPageNo--;
        totalPageCount--;
    }

    // et cetera
}

现在在 writePageNumber() 方法中,我获取页面上下文并进行处理。我检查页面是否不空白然后我写totalPages的currentPage,如果它是空白那么我减少currentPage No和totalPage计数......以便不计算空白页面......这是正确的方法去做吧?不确定

由于该方法是在for循环中调用的,我递减后的值会被重置,如何维护递减的值?

可能有更好的方法来做到这一点,任何帮助将不胜感激。

编辑:

为了清楚起见,问题在于 writePageNumber() 是从 for 循环中调用的,因此下次调用 writePageNumber 时,值会被重置,因此在第二次迭代期间 else if 条件不再为真,第一个条件为真所以写错页码

【问题讨论】:

  • 对不起,但不明白问题出在哪里......无论如何,如果你需要返回两个值,你可以用类包装它
  • 试试这个: if ( !page.isBlank() ) { this.write(page.getPageNo(), page.getTotalPageCount()); } else if ( page.isBlank() ){ page.getPageNo()--; page.getTotalPageCount()--; }
  • @AsfK 我编辑了我的问题并添加了细节,希望现在应该更清楚
  • @dkb 问题是从 for 循环中调用,因此下次调用 writePageNumber 时,值会被重置,因此在第二次迭代期间 else if 条件不再为真,第一个条件为true 所以写错页码
  • 在您的更新版本中,方法调用的参数与其参数不匹配。

标签: java algorithm for-loop counter decrement


【解决方案1】:

问题是在您当前的代码中,变量currentPageNototalPageCount 在堆栈上,这意味着它们的值在方法返回后被丢弃。解决您的问题的一种方法是将writePageNumber 的主体提取到您的for 循环中。因此,与其拥有类似的东西,

Page page = /* ... */
int totalPages = 5;
for (int currentPage = 1; currentPage <= totalPages; i++) {
    writePageNumber(page, currentPage, totalPages);
};

您的代码可能如下所示:

Page page = /* ... */
int totalPages = 5;
for (int currentPage = 1; currentPage <= totalPages; i++) {
    if (!page.isBlank()) {
       // ...
    } else {
      currentPage--;
      totalPages--;
    }
    // ...
}

编辑:您提到不破坏代码模式,但在这种情况下您可能不得不妥协。目前,您期望writePageNumber 是一个函数,它接受两个整数参数,修改它们,并为下一个函数调用以某种方式返回它们的更新值。您不能从 Java 中的函数返回多个值。您需要让这些值在方法调用中保持不变,因此它们需要在方法范围之外声明(或者,就像我建议的那样,您将方法提取到循环中),这意味着使用一个字段.

【讨论】:

  • 谢谢。但是我想保持我当前的模式,因为我正在使用的这段代码非常遗留,我担心会破坏一些东西...... +1 好主意
  • writePageNumber 位于不同的类中。调用者不应该知道该类如何实现编写页码的实现。我给出的示例是说明问题的简单示例。我认为为了修复错误而打破设计模式并不是一个好的做法,并且打破了关注点分离的基本计算机科学原则
【解决方案2】:

我认为问题在于:
您有数 (5) 个页面对象;每个对象都有自己的currentPagetotalPageCount,如下所示:
对象 1:Page: current = 1; total = 5;
对象 2:Page: current = 2; total = 5;
对象 3:Page: current = 3; total = 5;
对象 4:Page: current = 4; total = 5;
对象 5:Page: current = 5; total = 5;

在您的代码中,您正在更新currenttotal(不在对象中,而只是在它们正在使用的上下文中本地),但这些值不会在其余对象中更新; for 循环遍历这些未更新的剩余对象。
我建议你这样做:

private int blanks = 0;
public boolean writePageNumber(Page page, int currentPageNo, int totalPageCount) {
    if ( page.isBlank() ) {
        blanks++;
        // etcetera
    } else {
        this.write(currentPageNo - blanks, totalPageCount - blanks);
    }

    // et cetera
}

编辑

您应该首先遍历所有页面以获得总空白页,以获得固定的totalPageCount,然后删除上面totalPageCount - blanks中的- blanks,否则您将获得如下数据:

对象 1:Page: current = 1; total = 5;
对象 2:Page: current = BLANK; total = 5;
对象 3:Page: current = 2; total = 4;
对象 4:Page: current = BLANK; total = 4;
对象 5:Page: current = 3; total = 3;

注意总数是如何不断变化的。
还有一点需要注意的是,totalPageCount 不是页面的属性,因此不应该属于 Page 对象,而是属于 book 对象。看看这让事情变得多么复杂?!

【讨论】:

  • 如果你想更新page对象,我建议定义setter方法,比如setPageNo(int no)setTotalPageCount(int count)
  • 我喜欢你的减去空白的想法,但是如果说文档流中间有空白,它可能会打印错误的页面。然后 blank 将增加到 2 然后 this.write(currentPageNo - 2, totalPageCount - 2) 并且 totalPageCount 可能会有所不同,因为当遇到空白时空白会增加
  • 另外,在 writePageNumber 方法返回给调用者后,空格的值似乎不会持续存在,所以在下一次调用中,blanks 将再次成为 0
  • 至于您的第一点,我同意,这就是我编辑答案的原因。我相信即使你的代码也会有同样的问题。为了克服这个问题,您必须先遍历页面一次才能计算所有空白页面。
  • 如果从类中创建单个对象,其中定义了方法writePageNumber,并在循环中重新使用,那么blanks 不应失去其价值。如果我能看到这两个类,我可以更好地帮助你:一个 github repo 可能吗?一种解决方法(可行,但根据您的类结构可能在逻辑上是错误的)是使blanks 像这样static int blanks = 0 静态
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-27
  • 2022-11-02
  • 1970-01-01
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
相关资源
最近更新 更多