首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

ZOJ 2476 Total Amount:貨幣字符串解析與格式化輸出

     編輯:關於C++

ZOJ 2476 Total Amount 詳解

題目:輸入 n 條記錄,每條形如 $123.45。求總和,輸出格式化貨幣字符串:$ + 整數部分每三位加逗號 + . + 兩位小數。n=0 結束。總和不超過 2³¹-1。

核心難點

  1. 解析:去除 $、,,提取整數與小數部分,轉為長整型(分為單位避免浮點誤差)。
  2. 格式化輸出:整數部分從右向左每三位插入逗號,處理「不足三位不加逗號」「小數補零」等邊界。
  3. 精度:絕對不能用 double/float,浮點誤差會導致 WA。全程用 64 位整數存儲「分」。

解析策略

讀入字符串 s,去掉首字符 $,移除所有 ,,按 . 分割:

  • 無小數點 → 整數部分 s,小數 "00"。
  • 有小數點 → 整數部分 s1,小數 s2(補齊/截斷至 2 位)。
  • 總分 = stoll(s1) * 100 + stoll(s2)。

格式化輸出算法

將總分轉為字符串 total_str(不含小數點)。

  1. 若長度 ≤ 2:整數部分為 "0",小數部分左補零至 2 位。
  2. 否則:整數部分 = total_str.substr(0, len-2),小數 = 後 2 位。
  3. 整數部分從右向左每 3 位插入 ',':倒序遍歷,計數器 cnt,每 3 字符插入逗號(最前不加)。

參考代碼 (C++)

#include <bits/stdc++.h>
using namespace std;

long long parseMoney(const string& s) {
    // s 格式:$1,234.56 或 $123 或 $0.5 等
    string t = s.substr(1); // 去掉 $
    t.erase(remove(t.begin(), t.end(), ','), t.end()); // 去掉逗號
    size_t pos = t.find('.');
    long long dollars = 0, cents = 0;
    if (pos == string::npos) {
        dollars = stoll(t);
    } else {
        dollars = stoll(t.substr(0, pos));
        string c = t.substr(pos + 1);
        if (c.size() == 1) c += '0';
        else if (c.size() > 2) c = c.substr(0, 2);
        cents = stoll(c);
    }
    return dollars * 100 + cents;
}

string formatMoney(long long totalCents) {
    long long dollars = totalCents / 100;
    int cents = totalCents % 100;
    string d = to_string(dollars);
    // 整數部分加逗號
    string withComma;
    for (int i = d.size() - 1, cnt = 0; i >= 0; --i, ++cnt) {
        if (cnt && cnt % 3 == 0) withComma.push_back(',');
        withComma.push_back(d[i]);
    }
    reverse(withComma.begin(), withComma.end());
    // 小數部分
    string c = (cents < 10 ? "0" : "") + to_string(cents);
    return "$" + withComma + "." + c;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    while (cin >> n && n) {
        long long total = 0;
        for (int i = 0; i < n; ++i) {
            string s; cin >> s;
            total += parseMoney(s);
        }
        cout << formatMoney(total) << '\n';
    }
    return 0;
}

關鍵測試用例

輸入總分(分)輸出說明
1
$0.01
1$0.01最小金額
1
$1,000.00
100000$1,000.00千分位逗號
2
$999.99
$0.01
100000$1,000.00進位導致逗號位置變化
1
$123456789.99
12345678999$123,456,789.99多逗號
1
$0.5
50$0.50小數補零

常見錯誤與避坑指南

  • ❌ 用 double 累加 → 浮點誤差(如 0.1+0.2≠0.3)。
  • ❌ printf("%.2f") 直接輸出 → 無逗號、四捨五入錯誤。
  • ❌ 整數部分逗號邏輯錯:如 1234 輸出 1,234 而非 12,34。
  • ❌ 小數位不足 2 位不補零:$1.5 應為 $1.50。
  • ❌ 輸入可能包含 $ 和 , 但無小數點,需兼容。

總結

ZOJ 2476 是「字符串解析 + 整數精度運算 + 格式化輸出」的綜合訓練題。核心教訓:貨幣計算永遠用整數(分/厘),格式化輸出要仔細處理邊界(零、進位、逗號位置)。此類題目在金融、賬單系統開發中極具實戰價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved