首页 > 专题系列 > Java解POJ > POJ 1312 Numerically Speaking [解题报告] Java
2013
11-09

POJ 1312 Numerically Speaking [解题报告] Java

Numerically Speaking

问题描述 :

A developer of crossword puzzles (and other similar word games) has decided to develop a mapping between every possible word with from one to twenty characters and unique integers. The mapping is very simple, with the ordering being done first by the length of the word, and then alphabetically. Part of the list is shown below.

a 1
b 2
...
z 26
aa 27
ab 28
...
snowfall 157,118,051,752
...

Your job in this problem is to develop a program which can translate, bidirectionally, between the unique word numbers and the corresponding words.

输入:

Input to the program is a list of words and numbers, one per line starting in column one, followed by a line containing a single asterisk in column one. A number will consist only of decimal digits (0 through 9) followed immediately by the end of line (that is, there will be no commas in input numbers). A word will consist of between one and twenty lowercase alphabetic characters (a through z).

输出:

The output is to contain a single line for each word or number in the input data. This line is to contain the word starting in column one, followed by an appropriate number of blanks, and the corresponding word number starting in column 23. Word numbers that have more than three digits must be separated by commas at thousands, millions, and so forth.

样例输入:

29697684282993
transcendental
28011622636823854456520
computationally
zzzzzzzzzzzzzzzzzzzz
*

样例输出:

elementary            29,697,684,282,993
transcendental        51,346,529,199,396,181,750
prestidigitation      28,011,622,636,823,854,456,520
computationally       232,049,592,627,851,629,097
zzzzzzzzzzzzzzzzzzzz  20,725,274,851,017,785,518,433,805,270

解题代码:

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 
 * Accepted. BigInteger is used here.
 * 
 * 
 */
public class Main {

    /**
     * Check if the given string is in numberic format.
     * 
     * @param a
     * @return
     */
    private static boolean isNumber(String a) {
        for (int i = 0; i < a.length(); i++) {
            if (a.charAt(i) >= '0' && a.charAt(i) <= '9') {
                // ignore
            } else {
                return false;
            }
        }

        return true;
    }

    /**
     * Format the given number.  such as 1234 to 1,234
     * 
     * @param a
     * @return
     */
    private static String format(String a) {
        StringBuffer sb = new StringBuffer();
        for (int j = a.length() - 1; j >= 0; j--) {
            if ((j != a.length() - 1) && ((a.length() - 1 - j) % 3 == 0)) {
                sb.append(",");
            }

            sb.append(a.charAt(j));
        }

        return sb.reverse().toString();
    }

    /**
     * Translate the words to number.
     * 
     * @param a
     * @return
     */
    private static String transalteToNumber(String a) {
        BigInteger m = new BigInteger("26");
        BigInteger ret = BigInteger.ZERO;

        BigInteger b = BigInteger.ONE;

        for (int i = a.length() - 1; i >= 0; i--) {
            BigInteger temp = new BigInteger("" + (a.charAt(i) - 'a' + 1));
            temp = temp.multiply(b);
            b = b.multiply(m);
            ret = ret.add(temp);
        }

        return ret.toString();
    }

    /**
     * Translate number to words.
     * 
     * @param a
     * @return
     */
    private static String translateString(String a) {
        BigInteger b = new BigInteger(a);
        BigInteger m = new BigInteger("26");
        StringBuffer sb = new StringBuffer();
        while (b.compareTo(BigInteger.ZERO) > 0) {

            BigInteger k = b.mod(m);
           if (k.intValue() <= 0) {
                sb.append("z");
                b = b.subtract(m);
            } else {
                sb.append((char) (k.intValue() - 1 + 'a'));

                b = b.subtract(k);
            }
            b = b.divide(m);
        }

        return sb.reverse().toString();
    }

    /**
     * Delete the leading zero.
     * 
     * @param a
     * @return
     */
    private static String deleteLeadingZero(String a) {
        int i = 0;
        while (a.charAt(i) == '0') {
            i++;
        }

        StringBuilder sb = new StringBuilder();
        while (i < a.length()) {
            sb.append(a.charAt(i));
            i++;
        }

        return sb.toString();
    }

    /**
     * Format and print the result string.
     * 
     * @param s
     */
    private static void print(String s) {
        int max = 22;
        String[] temp = s.split("[ ]+");

        System.out.print(temp[0]);

        for (int j = temp[0].length(); j < max; j++) {
            System.out.print(" ");
        }

        System.out.println(temp[1]);
    }

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Scanner cin = new Scanner(System.in);
        while (true) {
            String line = cin.nextLine();
            line = deleteLeadingZero(line.trim());
            if (line.equals("*")) {
                break;
            }

            String word = "";
            String number = "";
            if (isNumber(line)) {
                word = translateString(line);
                number = format(line);
                print(word + " " + number);
            } else {
                word = line;
                number = format(transalteToNumber(line));
                print(word + " " + number);
            }
        }
    }

}