Currency Number Formatting

medium Number Problems

Problem

Read a non-negative amount with at most two decimals. Print it with commas in two styles, always with exactly two decimals. Indian style: the last three digits form a group and the other digits are grouped in twos (12,34,567.50). International style: every group has three digits (1,234,567.50).

Constraints

  • Amount has at most 15 digits before the decimal point

Examples

Input

1234567.5

Output

Indian format: 12,34,567.50
International format: 1,234,567.50

Solutions

Best approachTime O(d)Space O(d)

We handle the amount as text, so there are no decimal rounding errors. We go from the right and put a comma after every 3 digits (international) or after 3 and then every 2 digits (Indian).

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Format an amount with commas in two styles.
 * Input   : One non-negative amount with at most 2 decimals.
 * Output  : Two lines: Indian format and International format.
 * Approach: Group the digits of the integer part from the right.
 * Time    : O(d)
 * Space   : O(d)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method receives the digits of the integer part and a flag. It returns the digits with commas.
    static String group(String digits, boolean indian) {
        StringBuilder result = new StringBuilder();

        // Step 1: Go through the digits from the right to the left. "placed" counts the digits that are already written.
        int placed = 0;
        for (int index = digits.length() - 1; index >= 0; index--) {
            // Step 2: Decide if a comma is needed before this digit.
            // International: after every 3 digits. Indian: after 3 digits, then after every 2 digits.
            boolean comma = indian ? (placed == 3 || (placed > 3 && (placed - 3) % 2 == 0)) : (placed > 0 && placed % 3 == 0);
            if (comma) {
                result.append(",");
            }

            // Step 3: Add the digit. We build the text from the right, so we reverse it at the end.
            result.append(digits.charAt(index));
            placed++;
        }
        return result.reverse().toString();
    }

    public static void main(String[] args) {
        String amount = new Scanner(System.in).next();

        // Step 4: Split the amount at the decimal point. Example: "1234567.5" -> "1234567" and "5".
        int dot = amount.indexOf('.');
        String integerPart = dot == -1 ? amount : amount.substring(0, dot);
        String fraction = dot == -1 ? "" : amount.substring(dot + 1);

        // Step 5: Make sure the fraction has exactly two digits. Example: "5" -> "50", "" -> "00".
        while (fraction.length() < 2) {
            fraction = fraction + "0";
        }

        // Step 6: Print both styles.
        System.out.println("Indian format: " + group(integerPart, true) + "." + fraction);
        System.out.println("International format: " + group(integerPart, false) + "." + fraction);
    }
}
Hints (2)
  1. Do not use decimal numbers for money. Use text or whole numbers.
  2. Count the digits from the right side.