试图模仿Splitwise app逻辑 - 建议一种更好的方法来处理和解

时间:2018-03-29 05:37:58

标签: java algorithm logic

我正在尝试编写Splitwise等应用中使用的基本逻辑。

输入 - 旅行中的交易

a|a,b,c,d|120
b|a,b,d|210
c|a,b,c,d|40
a|a,b,c|60
  • abcd是旅途中的朋友
  • 第一笔交易中的
  • a为涉及所有四位朋友的交易支付了120个单位
  • 在第二笔交易中b为仅涉及abd
  • 的交易支付了210个单位
  • n个此类交易,可以有m个朋友

预期产出

a has to get 50
b has to get 80
c has to give 20
d has to give 110

d has to give 80 to b
d has to give 30 to a
c has to give 20 to a

这就是我尝试过的。 Person类是使用的pojo。

public class Person {
 private String name;
 private Integer totalExpense;
 private Integer totalSpent;
 private Integer balanceAmt;
}

这是结算操作的代码。

public void settle(Map<String, Person> personMap) {
 List<Person> getterList = new ArrayList<>();
 List<Person> giversList = new ArrayList<>();

 for (String key : personMap.keySet()) {
  Person user = personMap.get(key);
  int balanceAmt = user.getTotalSpent() - user.getTotalExpense();
  user.setBalanceAmt(Math.abs(balanceAmt));

  if (balanceAmt > 0) {
   System.out.println(key + " has to get " + balanceAmt);
   getterList.add(user);
  } else if (balanceAmt < 0) {
   System.out.println(key + " has to give " + Math.abs(balanceAmt));
   giversList.add(user);
  } else if (balanceAmt == 0) {
   System.out.println(key + " is all settled");
  }
 }

 getterList.sort((p2, p1) -> p1.getBalanceAmt().compareTo(p2.getBalanceAmt()));
 giversList.sort((p2, p1) -> p1.getBalanceAmt().compareTo(p2.getBalanceAmt()));

 giversList.forEach(giver -> {
  getterList.forEach(getter -> {                
   if (getter.getBalanceAmt() == 0) {
    return;
   }
   if (giver.getBalanceAmt() == getter.getBalanceAmt()) {
    System.out.println(giver.getName() + " has to give " + giver.getBalanceAmt() + " to " + getter.getName());
    giver.setBalanceAmt(0);
    getter.setBalanceAmt(0);
   } else if (giver.getBalanceAmt() > getter.getBalanceAmt()) {
    System.out.println(giver.getName() + " has to give " + getter.getBalanceAmt() + " to " + getter.getName());
    giver.setBalanceAmt(giver.getBalanceAmt() - getter.getBalanceAmt());
    getter.setBalanceAmt(0); 
   } else if (giver.getBalanceAmt() < getter.getBalanceAmt()) {
    System.out.println(giver.getName() + " has to give " + giver.getBalanceAmt() + " to " + getter.getName());
    giver.setBalanceAmt(0);
    getter.setBalanceAmt(getter.getBalanceAmt() - giver.getBalanceAmt());
   }
  });
 });
}

代码不好,循环太多。 建议一个很好的方法来解决金额,并提出输出的第二部分。

1 个答案:

答案 0 :(得分:0)

使用两个指针将你的底部逻辑从O(m 2 )减少到O(m)。

int giverPointer = 0;
int getterPointer = 0;
while(giverPointer < giversList.size() && getterPointer < getterList.size()){
    if (giversList.get(giverPointer).getBalanceAmt() == getterList.get(getterPointer).getBalanceAmt()) {
        System.out.println(giversList.get(giverPointer).getName() + " has to give " + giversList.get(giverPointer).getBalanceAmt() + " to " + getterList.get(getterPointer).getName());
        giversList.get(giverPointer).setBalanceAmt(0);
        getterList.get(getterPointer).setBalanceAmt(0);
        giverPointer++;
        getterPointer++;
    } else if (giversList.get(giverPointer).getBalanceAmt() > getterList.get(getterPointer).getBalanceAmt()) {
        System.out.println(giversList.get(giverPointer).getName() + " has to give " + getterList.get(getterPointer).getBalanceAmt() + " to " + getterList.get(getterPointer).getName());
        giversList.get(giverPointer).setBalanceAmt(giversList.get(giverPointer).getBalanceAmt() - getterList.get(getterPointer).getBalanceAmt());
        getterList.get(getterPointer).setBalanceAmt(0); 
        getterPointer++;
    } else {
        System.out.println(giversList.get(giverPointer).getName() + " has to give " + giversList.get(giverPointer).getBalanceAmt() + " to " + getterList.get(getterPointer).getName());
        giversList.get(giverPointer).setBalanceAmt(0);
        getterList.get(getterPointer).setBalanceAmt(getterList.get(getterPointer).getBalanceAmt() - giversList.get(giverPointer).getBalanceAmt());
        giverPointer++;
    }
}