输入每个人花钱信息,直接计算出每个人应该付多少钱。
示例:
张三:32 # 买肉
李四:12 # 买土豆
张三:35 # 买番茄
王五:
这六:
展开/折叠结果
每人应交或返回的金额
王五: 19.75元(应交)
这六: 19.75元(应交)
李四: 7.75元(应交)
张三: 47.25元(应退)
支付分配情况
王五 应交 19.75元 给 张三
这六 应交 19.75元 给 张三
李四 应交 7.75元 给 张三
源代码:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AA制计算器</title>
<style>
body {
text-align: center;
font-family: Arial, sans-serif;
margin: 20px;
}
textarea {
width: 100%;
height: 150px;
}
button {
margin-top: 10px;
}
.result {
margin-top: 20px;
border: 1px solid #ccc;
padding: 10px;
}
</style>
</head>
<body>
<h1>AA制计算器</h1>
<textarea id="input" placeholder="请输入信息,格式为:张三: 32 # 买肉"></textarea>
<button onclick="calculate()">计算</button>
<div class="result" id="result"></div>
<script>
function calculate() {
let input = document.getElementById('input').value.trim();
// 替换中文冒号为英文冒号
input = input.replace(/:/g, ':');
const lines = input.split('\n');
const expenses = {};
const contributions = {};
const allNames = new Set(); // 用于存储所有姓名
lines.forEach(line => {
const [info, note] = line.split('#').map(part => part.trim());
const [name, value] = info.split(':').map(part => part.trim());
// 添加姓名到集合中
allNames.add(name);
// 处理收入和支出
if (value.startsWith('+')) {
const amount = parseFloat(value.slice(1));
contributions[name] = (contributions[name] || 0) + amount; // 记录预收款
} else {
const amount = parseFloat(value);
if (!isNaN(amount)) {
expenses[name] = (expenses[name] || 0) + amount; // 记录支出
}
}
});
// 计算总支出
const totalExpense = Object.values(expenses).reduce((sum, val) => sum + val, 0);
const totalPeople = allNames.size; // 参与人数
const averageExpense = totalExpense / totalPeople; // 每人应负担的金额
// 计算每个人的应交或应退金额
const result = {};
allNames.forEach(name => {
const paid = contributions[name] || 0; // 个人预收款
const owed = expenses[name] || 0; // 个人支出
// 应交或应退金额 = 每人应负担的金额 - (支出 + 预收款)
result[name] = averageExpense - (owed + paid);
});
// 计算应交和应退的人
const payers = [];
const receivers = [];
allNames.forEach(name => {
if (result[name] > 0) {
payers.push({ name, amount: result[name] }); // 应交的人
} else if (result[name] < 0) {
receivers.push({ name, amount: -result[name] }); // 应退的人
}
});
// 按应退金额从高到低排序
receivers.sort((a, b) => b.amount - a.amount);
// 按应交金额从高到低排序
payers.sort((a, b) => b.amount - a.amount);
// 分配应交金额
let output = '<h3>每人应交或返回的金额</h3><ul>';
payers.forEach(payer => {
output += `<li>${payer.name}: ${payer.amount.toFixed(2)}元(应交)</li>`;
});
receivers.forEach(receiver => {
output += `<li>${receiver.name}: ${-result[receiver.name].toFixed(2)}元(应退)</li>`;
});
// 创建一个新的输出列表
let paymentOutput = '<h3>支付分配情况</h3><ul>';
// 分配应交金额给应退金额最多的人
payers.forEach(payer => {
let remaining = payer.amount;
for (let receiver of receivers) {
if (remaining <= 0) break; // 如果没有剩余金额,退出
if (receiver.amount > 0) {
const payment = Math.min(remaining, receiver.amount);
paymentOutput += `<li>${payer.name} 应交 ${payment.toFixed(2)}元 给 ${receiver.name}</li>`;
remaining -= payment;
receiver.amount -= payment; // 减少接收者的应退金额
}
}
});
// 将支付分配情况添加到结果中
output += paymentOutput + '</ul>';
// output += '</ul>';
document.getElementById('result').innerHTML = output;
}
</script>
</body>
</html>
发表回复