結算是怎麼算出來的

分帳最容易吵架的地方,是「每一筆各自還」——十筆費用就要轉十次帳。 ShareMoney 的作法是先把所有費用壓成每個人的一個淨額,再用最少的轉帳次數把淨額清掉。

第一步:算出每個人的淨額

每個人有兩個數字:墊付(他實際掏錢付掉的總額)和應攤(所有費用裡分到他頭上的總額)。兩者相減就是淨額:

淨額 = 墊付總額 − 應攤總額

淨額為正代表他先幫大家出了錢,該收回來;為負代表他還沒付夠,該掏錢。 所有人的淨額加起來一定是零——錢不會憑空多出來或消失,這也是系統內部的檢查點。

外幣費用在這一步就已經按帳本匯率換算成台幣,所以一本帳裡即使混著日圓和台幣, 淨額仍然是同一個單位,不會出現兩套幣別各自結算的情況。

舉個例子

三個人出去玩,總共花了 4,500 元,三筆費用都是三人均攤,每人應攤 1,500 元:

成員墊付應攤淨額
小明3,0001,500+1,500
小華1,2001,500-300
小美3001,500-1,200

小明該收 1,500,小華該付 300,小美該付 1,200。如果照「每筆各自還」的作法, 三筆費用會產生六次轉帳;壓成淨額之後,只剩兩筆:小美轉 1,200 給小明、小華轉 300 給小明。

第二步:把轉帳次數壓到最少

把所有淨額為正的人排成一列(收款方,由大到小),淨額為負的人排成另一列(付款方,欠最多的排前面), 然後每次都讓「欠最多的人」轉給「該收最多的人」,金額取兩者的較小值。 一次轉帳至少讓其中一邊歸零,於是這個人就從列表裡移除,繼續配下一組,直到兩列都空掉。

因為每一筆轉帳至少消掉一個人,N 個人最多只需要 N−1 筆轉帳就能結清—— 五個人最多四筆,不管中間記了幾百筆費用。

補充一句實話:求「理論上絕對最少的轉帳筆數」在數學上是 NP-hard 的問題(要枚舉所有能互相抵銷的子集合)。 ShareMoney 用的是上面這個貪婪配對法,保證不超過 N−1 筆,在實際的三五人團體幾乎都等於最佳解, 但在刻意構造的特殊金額組合下,理論上可能存在再少一筆的解法。我們選擇了可預測、算得快、 而且結果穩定的作法,而不是為了極少數情況去跑指數級的搜尋。

小數與尾數怎麼處理

均攤除不盡時,餘數會固定落在分攤名單的第一個人身上,例如 100 元三人均攤是 34 / 33 / 33。 分出去的金額總和永遠等於原始金額,不會出現「每人 33.33,加起來少一毛」的黑洞。

淨額與轉帳金額都保留到小數點後兩位,並以 0.005 元為門檻判斷是否歸零, 避免浮點數誤差讓某個人身上永遠掛著 0.0000001 元的餘額,導致多出一筆沒有意義的轉帳。

記錄還款之後

實際轉完帳,在結算頁按「記錄還款」,系統會寫入一筆結算紀錄——本質上是一筆特殊的費用: 付款人是還錢的人,分攤對象是收錢的人。它同樣進入上面的淨額公式,所以兩人的餘額就此歸零, 原本的費用紀錄一筆都不用刪,帳本的歷史保持完整。

想知道怎麼開始記帳,看使用教學