【问题标题】:Defining more efficient logic for given scenario为给定场景定义更有效的逻辑
【发布时间】:2015-08-31 14:20:53
【问题描述】:

有一些有趣的逻辑,我试图以最有效和可读的方式进行编码。我将在下面列出场景(带有模拟/虚拟上下文)

我有一个银行及其柜员评论的数据存储(1-5 个整数字段)。柜员可以选择拥有客户选择赢家 (CCW) 字段。我的要求如下,为给定的银行选择最多 5 个柜员显示给用户:

  1. 如果柜员是 CCW,请选择它。如果多个柜员有 CCW,请使用柜员评论来打破平局
  2. 当没有 CCW 时,选择柜员评分最高的 4 级柜员。

我必须为 5 家银行执行上述操作。我得到的逻辑是有一个 for 循环遍历 5 个银行,并在每个循环中,遍历每个银行的所有柜员 5 次(选择 5 个柜员)。在我看来,这确实效率低下且不清楚。这就是我的意思:

foreach (Bank b : banks) {
    List<Tellers> tellers = b.getTellers();

    foreach (Teller t : tellers) {
        List<Reviews> reviews = t.getReviews();

        ...// get 4 reviews following the above logic.
    }
}

谁能帮我写出更清晰、更有效的方法?

谢谢!

【问题讨论】:

  • 有什么原因不能由数据库(SQL或其他)完成吗?
  • 柜员是否包含所有银行的所有柜员?或者特别是每个透视银行的出纳员?
  • 对 java 8 是的,并且要求不要在 SQL 中这样做(不取决于我)
  • @DrewB b.getTellers() 调用获取特定银行 b 的所有柜员。
  • 你说 " for a given bank" 但遍历每个银行。它是哪一个?银行是不是方法参数

标签: java logic


【解决方案1】:

最好的解决方案是对 List

进行排序

您必须通过实现 Comparable 接口为 Teller 对象定义一个比较函数。

这将使您在恒定时间内运行您的算法(O(25),因为 5 个银行的 5 个柜员,这实际上是 O(1))

以第一次排序为代价,将是 O(nlogn)

Teller 类的示例代码:

public class Teller implements Comparable
{

    private boolean ccw = false;
    private int rating;

    public boolean hasCCW() { return ccw; }
    public int getRating() { return rating; }

    //... your code

    @Override
    public int compareTo(Object o) 
    {
        Teller that = (Teller)o;
        //if this has ccw and that doesn't, this < that
        if(this.hasCCW() && !that.hasCCW()) 
        {
            return -1;
        }
        //else if this does not have ccw, and that does, this > that
        else if(!this.hasCCW() && that.hasCCW())
        {
            return 1;
        }
        //else they both have ccw, so compare ratings
        else
        {
            return Integer.compare(this.getRating(), that.getRating());
        }
    }

}

然后,您的算法只需要获取每家银行的前 5 个柜员即可。

示例:

//Sort the tellers:
//ideally, call this only once, and insert future Tellers in order (to maintain ordering)
for(Bank bank : banks)
{
    for(List<Teller> tellers : bank.getTellers())
    {
        Collections.sort(tellers);
    }
}

//then, to get your top tellers:
for(Bank bank : banks)
{
    Teller bestTeller = bank.getTeller(0);
    Teller secondBestTeller = bank.getTeller(1);
    //...
}

【讨论】:

  • 如果我唯一要做的事情是出纳员的评论,那将起作用。但是每个柜员都有一个额外的 CCW 字段,也必须检查。比如说,我有 40 个柜员,其中 5 个是 CCW,algo 应该返回这 5 个。如果有 3 个 CCW,algo 应该根据谁拥有最多 4 星评论返回这 3 个和另外 2 个。如果柜员有 6 个 CCW,则使用审查计数返回 6 个 CCW 中的前 5 个柜员。这仍然适用于这些场景吗?
  • 我觉得我需要一种清晰的方法来将此逻辑放入代码中,然后将其作为第二步进行优化。在我们进行运行时分析之前有什么帮助吗?
  • 是的。您在 compare 函数中定义了刚才所说的所有内容。如果要比较的两个 Teller 对象都有 CCW,则检查它们的等级。定义方法后,您将能够简单地调用 Collections.sort(tellers),它会在内部处理排序。
  • 你能发布一个关于如何完成这个的代码 sn-p 吗?我第一次做这样的事情。
  • 然后您应该用一些代码替换 Integer.compare 方法调用,执行您刚才描述的操作。你应该能够解决这个问题。 compare 方法将 this(当前对象)与参数对象进行比较。如果在此之前,则如果它们相同,则需要返回 -1...0,如果在此之后,则需要返回 1。阅读 Comparator / Comparable 的文档了解更多信息
猜你喜欢
  • 1970-01-01
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多