Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // C++98
- #include <iostream>
- #include <fstream>
- using namespace std;
- /**
- * Files
- */
- #define FILE_IN "num.txt"
- #define FILE_OUT "spell.txt"
- /**
- * Constants
- */
- #define CHAR_ZERO CHAR_NUM[0]
- #define LEN_NUM 10
- #define LEN_SI 3
- #define LEN_BI 4
- const int MAX_LEN = 20;
- const int INTERVAL = 4;
- // chinese numerals
- const string CHAR_NUM[] = {"零", "ㄧ", "二", "三", "四", "五", "六", "七",
- "八", "九"};
- // small interval
- const string CHAR_SI[] = {"十", "百", "千"};
- // big interval
- const string CHAR_BI[] = {"萬", "億", "兆", "京"};
- /**
- * Prototypes
- */
- typedef string (*FUNC)(string );
- string num2spell(string );
- string spell2num(string );
- bool validate(FUNC , bool verbose = false);
- int main() {
- // 驗證正確性
- //validate(num2spell, true);
- // 數字 -> 中文數字
- while (1) {
- string num;
- cout << "輸入整數: ";
- cin >> num;
- try {
- cout << num2spell(num) << endl;
- } catch (const string &str) {
- cout << "Error: " << str << endl;
- }
- }
- // 中文數字 -> 數字
- // while (1) {
- // string num;
- //
- // cout << "輸入中文數字: ";
- // cin >> num;
- //
- // cout << spell2num(num) << endl;
- // }
- return 0;
- }
- /** \brief Convert a number to Chinsese numerals
- * \param string num A non-negative integer
- * \return string Chinese numerals
- */
- string num2spell(string num) {
- size_t sz = num.size(), revi, si, bi;
- bool lastZero = false,
- lastNonZero = false;
- int val;
- string ret;
- // limit the size
- if (sz > MAX_LEN) {
- throw string("Exceeded max length");
- }
- // special numbers
- if ("0" == num) {
- return CHAR_ZERO;
- }
- for (size_t i = 0; i != sz; ++i) {
- revi = (sz - 1) - i;
- bi = revi / INTERVAL;
- si = revi % INTERVAL;
- val = num[i] - '0';
- if (0 != val) {
- if (lastZero) {
- // append a zero
- ret += CHAR_ZERO;
- }
- // append a numeral
- if (1 == val && 1 == si) {
- // ten
- if (0 != i) {
- ret += CHAR_NUM[1];
- }
- } else {
- ret += CHAR_NUM[val];
- }
- if (0 != si) {
- // append a small interval char
- ret += CHAR_SI[si - 1];
- }
- lastNonZero = true;
- lastZero = false;
- } else {
- lastZero = true;
- }
- if (0 == si && 0 != bi) {
- if (lastNonZero) {
- // append a big interval char
- ret += CHAR_BI[bi - 1];
- // uncomment this to hide zero at rear of the big interval
- // followed up by another one
- //lastZero = false;
- }
- lastNonZero = false;
- }
- }
- return ret;
- }
- /** \brief Convert a Chinese numerals to number
- * \param string spell A Chinese numerals
- * \return string Number as string
- */
- string spell2num(string spell) {
- int val = -1, siNum[INTERVAL] = {0}, biPower = 0, lastBiPower = 0;
- bool isNum, isSi, isBi, valProc, firstNonZero = false;
- string ch;
- string ret;
- if (CHAR_ZERO == spell) {
- return "0";
- }
- for (size_t i = 0; i != spell.size(); i += 2) {
- ch = spell.substr(i, 2);
- // numeral
- isNum = false;
- for (int j = 0; j != LEN_NUM; ++j) {
- if (ch == CHAR_NUM[j]) {
- val = j;
- valProc = false;
- isNum = true;
- }
- }
- // small interval
- isSi = false;
- if ( !isNum) {
- for (int si = 0; si != LEN_SI; ++si) {
- if (ch == CHAR_SI[si]) {
- // ten
- if (-1 == val) {
- val = 1;
- }
- siNum[si + 1] = val;
- valProc = true;
- isSi = true;
- }
- }
- }
- // big interval
- isBi = false;
- if ( !isSi) {
- for (int bi = 0; bi != LEN_BI; ++bi) {
- if (ch == CHAR_BI[bi]) {
- lastBiPower = biPower;
- biPower = (bi + 1) * INTERVAL;
- lastBiPower -= INTERVAL + biPower;
- while (lastBiPower > 0) {
- ret += '0';
- --lastBiPower;
- }
- if ( !valProc) {
- siNum[0] = val;
- }
- // append small interval digits
- for (int si = INTERVAL - 1; -1 != si; --si) {
- if (0 != siNum[si]) {
- firstNonZero = true;
- }
- if (firstNonZero) {
- ret += (siNum[si] + '0');
- }
- siNum[si] = 0;
- }
- isBi = true;
- }
- }
- }
- }
- if (isBi) {
- while (0 != biPower) {
- ret += '0';
- --biPower;
- }
- } else {
- lastBiPower = biPower - INTERVAL;
- while (lastBiPower > 0) {
- ret += '0';
- --lastBiPower;
- }
- if ( !valProc) {
- siNum[0] = val;
- }
- for (int si = INTERVAL - 1; -1 != si; --si) {
- if (0 != siNum[si]) {
- firstNonZero = true;
- }
- if (firstNonZero) {
- ret += (siNum[si] + '0');
- }
- }
- }
- return ret;
- }
- bool validate(FUNC func, bool verbose) {
- fstream fsIn(FILE_IN, fstream::in),
- fsOut(FILE_OUT, fstream::in);
- string computed, lineIn, lineOut;
- bool ret = true;
- int lineNum = 1;
- while (getline(fsIn, lineIn) &&
- getline(fsOut, lineOut)) {
- computed = func(lineIn);
- if (computed != lineOut) {
- if (verbose) {
- cout << "Conflicting Result at line " << lineNum << endl <<
- "in : " << lineIn << endl <<
- "expected: " << lineOut << endl <<
- "result : " << computed << endl;
- }
- ret = false;
- break;
- }
- ++lineNum;
- }
- return ret;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement