Mình có thấy trên diễn đàn có share code về vụ này, nhưng không đủ đầy các trường hợp cho lắm(Tiếng Việt mình nó phong phú, phong cách quá mà ;)).
Cho nên nay mình post full code đọc full các trường hợp luôn, cho các mem mới tham khảo chơi. Với lại bác nào có cách tối ưu cho code thì xin góp ý mình với.
Đề tài này không phải mới nhưng mà…mình đã viết code này từ hơn năm trước nhưng bỏ lâu quá không đụng đến lập trình nữa, rồi cái code cũng mất, nên giờ quay lại thì gần như quên cái code được viết như thế nào. Phải mất cả ngày mình mới viết cái code mà chính mình đã nghĩ ra. Bó tay!
Các bác tự khai báo file .h nhé. Code viết cho form.
#include "readnumber.h"
ReadNumber::ReadNumber()
{
word_num = new UnicodeString[10];
UnicodeString word_arr[] = {L"không",L"một",L"hai",L"ba",L"bốn",L"năm",L"sáu",L"bảy",L"tám",L"chín"};
unit = new UnicodeString[4];
UnicodeString _unit[] = {L"",L"nghìn",L"triệu",L"tỉ"};
for(int i = 0; i<10; i++)
{
word_num[i] = word_arr[i];
if(i < 4)
unit[i] = _unit[i];
}
}
ReadNumber::~ReadNumber()
{
delete [] word_num;
delete []unit;
}
UnicodeString ReadNumber::return_word(int digit)
{
return word_num[digit];
}
void ReadNumber::two_digits(char ch1, char ch2)
{
int d1 = ch1 - '0', d2 = ch2 - '0';
switch(d1)
{
case 0:
if(d2 != 0)
{
stck_word.push(return_word(d2));
stck_word.push(L"lẻ");
}
break;
case 1:
if(d2 == 0) //10
stck_word.push(L"mười");
else if(d2 != 0)
{
if(d2 == 5) //15
stck_word.push(L"mười lăm");
else
{
stck_word.push(return_word(d2));
stck_word.push(L"mười");
}
}
break;
default:
if(d2 == 5) //#5 - 95
{
stck_word.push(L"mươi lăm");
stck_word.push(return_word(d1));
}
else if(d2 == 0) //#0
{
stck_word.push(L"mươi");
stck_word.push(return_word(d1));
}
else if(d2 == 1)
{
stck_word.push(L"mươi mốt");
stck_word.push(return_word(d1));
}
else
{ //## - 98
stck_word.push(return_word(d2));
stck_word.push(L"mươi");
stck_word.push(return_word(d1));
}
break;
}
}
bool ReadNumber::three_digits(std::string digits) //Ham tra ve false neu 3 so
{ //deu la 000
UnicodeString str_tmp = "";
str_tmp = return_word(digits[0] - '0') + L" trăm";
if(digits[0] != '0')
{
two_digits(digits[1],digits[2]);
}
if(digits[0] == '0')
{
if(digits[1] != '0' || digits[2] != '0')
two_digits(digits[1],digits[2]);
else
str_tmp = "";
}
///010 //002 0
if(str_tmp != "")
stck_word.push(str_tmp);
return (str_tmp == "");
}
UnicodeString ReadNumber::read_number(std::string number)
{
std::string str_tmp = "";
int index_unit = 0, count_digits = 0;
bool is_zero;
if(number.length() >= 3)
{
std::string::reverse_iterator rit = number.rbegin();
while(rit != number.rend())
{
str_tmp = *rit + str_tmp;
count_digits++;
if(count_digits == 3) //3 chu so
{
stck_word.push(unit[index_unit++]);
is_zero = three_digits(str_tmp); //1 trong 3 so <> 0
if(is_zero && index_unit != 4)
stck_word.push("#");
if(index_unit == 4)
index_unit = 1;
count_digits = 0;
str_tmp = "";
}
++rit;
}
}
else
{
str_tmp = number;
count_digits = number.length();
}
//it == rend
if(count_digits != 0)
stck_word.push(unit[index_unit]);
if(count_digits == 2) //2 chu so dau
{
two_digits(str_tmp[0], str_tmp[1]);
}
if(count_digits == 1)
stck_word.push(return_word(str_tmp[0] - '0'));
///////////////xuat du lieu tu stack vao chuoi////////
UnicodeString str_res = L"";
while(!stck_word.empty())
{
if(stck_word.top() == "#")
{
stck_word.pop();
stck_word.pop();
}
else
{
str_res += stck_word.top() + " ";
stck_word.pop();
}
}
return str_res;
}
std::string ReadNumber::format_number(std::string number)
{
std::string _num = number;
int len = _num.length();
if(len >= 4)
do
{
len -= 3;
_num.insert(len, 1, '.');
}while(len > 3);
return _num;
}