Share Code đọc số thành chữ, - số lớn bao nhiêu cũng cân tất

c-sharp
python
c++

(Tiến Nguyễn) #1

Chia sẻ anh em code c# đọc số. :smiley:
#Những giờ rảnh rỗi trên công ty

  public string ToText(string str)
            {
                string[] word = { "", " một", " hai", " ba", " bốn", " năm", " sáu", " bẩy", " tám", " chín" };
                string[] million = { "", " mươi", " trăm", "" };
                string[] billion = { "", "", "", " nghìn", "", "", " triệu", "", "" };
                string result = "{0}";
                int count = 0;
                for (int i = str.Length - 1; i >= 0; i--)
                {
                    if (count > 0 && count % 9 == 0)
                        result = string.Format(result, "{0} tỷ");
                    if(!(count < str.Length - 3&&count>2 && str[i].Equals('0')&& str[i - 1].Equals('0')&& str[i - 2].Equals('0')))
                    result = string.Format(result, "{0}"+ billion[count%9]);
                    if (!str[i].Equals('0'))
                        result = string.Format(result, "{0}" + million[count%3]);
                    else if(count%3 ==1 && count >1 && !str[i-1].Equals('0') && !str[i + 1].Equals('0'))
                        result = string.Format(result, "{0} lẻ");
                    var num = Convert.ToInt16(str[i].ToString());
                    result = string.Format(result, "{0}" + word[num]);
                    count++;
                }
                result = result.Replace("{0}", "");
                return result.Trim();
            }

(HK boy) #2

Tự dưng nhớ lại challenge của mình

đã từ rất lâu rồi…


(Vuio) #3

Bạn có ý tưởng hay, giống mình trước kia (thử thách của noname00)
Nhưng bài này không đơn giản thế đâu, nếu bạn không tin đọc thử giúp mình các số sau:
21
15
3005


(Tên Gì Cũng Được) #4

dù sao cũng like cho tinh thần chia sẻ :smiley:


(Tiến Nguyễn) #5

Bạn tự chạy code sẽ biết kết quả của mình thôi :smile:


(Trần Hoàn) #6

Không thấy có “lăm”, “mốt” là thấy chưa chuẩn rồi


(Huy Hoàng Phạm) #7

Thí chủ đã tự test code do chính mình viết chưa :slight_smile:

03210 crash app =))


(Tiến Nguyễn) #8

đã test chưa kĩ, với lại toàn test số lớn :smiley: sorry


(Inter Virgins) #9

Dỗi cái máy tính à bạn :smile:


(HK boy) #10

Mọi người thấy thích 24hai mươi tư hay là hai mươi bốn hơn?


(Tiến Nguyễn) #11

Bắt vậy nhiều case kinh khủng, tiếng việc, lúc thì mốt lúc thì một, :smiley:


(HK boy) #12

tiếng Việt

Thử làm <= 7 lần if xem sao =))


(Tiến Nguyễn) #13

Thanh niên làm được chưa, chia sẻ coi


(HK boy) #14

Vừa code xong cách đây vài phút…

Cứ từ từ =))


(Vô Thin) #15

Không phải thích hay không, nó đều có sự lý giải theo cách nào đó và tốt hơn hết nên biết như một trò vui. Mình thấy nhiều người tranh cãi trên mạng (nhất là đợt bài toán bảy mươi bốn hay bảy mươi tư) mà không hiểu vấn đề. Và có ít nhất 2 quan điểm cho việc này:

  1. Quan điểm cho rằng tư là từ miền Bắc, còn miền Trung/ Nam thì đọc là bốn. Quan điểm này xem ra không vững vì ngôn ngữ là học hỏi lẫn nhau, thay đổi theo thời gian nên miền Bắc không bao giờ gọi là phim con lợn mà họ gọi phim con heo, còn miền nam thì có thứ bánh da lợn chứ không bánh da heo. Mình cho rằng quan điểm này mang nặng tính kỳ thị vùng miền lẫn nhau, nên dẹp bỏ.

  2. Có hai thứ song hành nhưng nhiều người không biết cho đến khi họ học tiếng Anh, đó là số thứ tựsố đếm. Tiếng Anh thì hai đám này đọc khác nhau nên không thấy ai tranh cãi, còn tiếng Việt vì đọc giống nhau phần lớn, có vài khác biệt (tư hay bốn là 1 ví dụ).
    Số đếm là sao, ta đếm 1, 2, 3, 4, … 14, (mười bốn) con heo, 24 (hai mươi bốn) con heo.
    Số thứ tự là sao: con heo thứ nhất, con heo thứ hai, con heo thứ 3, con heo thứ tư,… con heo thứ mười bốn, con heo thứ hai mươi tư.
    Lộn xộn số đếm và số thứ tự trong một câu: Nhà tui có cả thảy hai mươi bốn anh chị em, ông anh thứ tư của tui ổng còn đang tại ngũ.

  3. Mặc dù bên trên mình chỉ liệt kê “ít nhất 2 quan điểm”, nhưng lại dí vào theo cái này đó là có lúc đọc tư để nghe nó “êm tai” hơn theo luật gì đó trong ngôn ngữ học (mình không nghiên cứu ngôn ngữ học nên không biết). Chỉ biết thơ trường phái Bút Tre thì có sửa dấu:

"Tiễn anh chỉ một quả chuồi
Em về em nhớ cái buổi hôm nay" (sửa dấu đọc sao cho êm tai nhỉ)

Quan điểm của mình là nếu không biết chỗ đó là gì, thì ta hiển thị lên 4 thay vì bốn hay tư :smiley: vì gần như ai cũng biết 4 là gì khi nó lẫn trong những dòng chữ dài.


(Trần Hoàn) #16

Muốn tham gia quá mà đang bận việc :frowning:


(明玉) #17

Cứ dùng mươi tư, mươi mốt, mươi lăm, thứ nhất. Việc biến âm và dùng Hán Việt “tư” thay cho “bốn” là để cho dễ đọc.


(‏) #18

http://giaibaitaptoan.net/giai-toan-4-bai-trieu-va-lop-trieu-tiep-theo-35-1681.html

nó đọc mươi tư nè, mà tốt nhất là quẳng chữ “tư” ra thành 1 biến cho người dùng tùy chỉnh, chữ “linh” và chữ “nghìn” luôn, thậm chí chữ “lăm” hay “nhăm” cũng chơi luôn

sáu mươi lăm dòng: http://rextester.com/HUWWX37455 :joy:

#include <iostream>
#include <string>
#include <algorithm>
#include <exception>
#include <cassert>
#ifdef __unix__
#include <clocale>
#elif defined _WIN32 || defined _WIN64
#include <fcntl.h> //_O_WTEXT
#include <io.h> //_setmode()
#endif

const std::wstring CHU_SO[] = {
    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"
};
const std::wstring MUOIF = L"mười"; //muoi` co' dau'
const std::wstring MUOI = L"mươi";
const std::wstring TRAM = L"trăm";
const std::wstring NGAN_TR[] = { L"nghìn", L"triệu" };
const std::wstring TY = L"tỷ";
const std::wstring MOTS = L"mốt"; //mot' co dau sac
const std::wstring TU = L"tư"; //tu
const std::wstring LAM = L"lăm"; //lam
const std::wstring LINH = L"linh";
const wchar_t SPACE = L' ';
const std::wstring COMMA = L", ";

std::wstring toVnStr(const std::string& num);

int main()
{
    #ifdef __unix__
    setlocale(LC_ALL, "");
    #elif defined _WIN32 || defined _WIN64
    setmode(fileno(stdout), _O_WTEXT); //needed for output
    setmode(fileno(stdin), _O_WTEXT); //needed for input
    #endif

    std::string testCases[] = {
        "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
        "10", "11", "12", "20", "21", "22", "24", "90", "91", "97",
        "300", "999", "121", "215", "5121", "39500",
        "1025217", "51105500", "51000000", "999999999",
        "5120625952200", "12000000000000000000", "18446744073709551615",
        "18000000000709551615",
        "1000015", "1002015", "1000000024",
        "03215", "", "0000", "00001", "00100",
        "1844674407370955161518000000000000000000709551615",
        "0321", "000345", "15", "40430203", "3209", "3500", "3901", "21",
        "3005", "3055", "9031", "9330",
        "9000005", "9001005",
    };
    for (auto const& s : testCases)
        std::wcout << s.c_str() << " = " << toVnStr(s) << "\n";

    //http://giaibaitaptoan.net/giai-toan-4-bai-trieu-va-lop-trieu-tiep-theo-35-1681.html
    std::pair<std::string, std::wstring> testCaseWithAnswers[] = {
        {"32000000", L"ba mươi hai triệu"},
        {"32516000", L"ba mươi hai triệu năm trăm mười sáu nghìn"},
        {"32516497", L"ba mươi hai triệu năm trăm mười sáu nghìn bốn trăm chín mươi bảy"},
        {"834291712", L"tám trăm ba mươi tư triệu hai trăm chín mươi mốt nghìn bảy trăm mười hai"},
        {"308250705", L"ba trăm linh tám triệu hai trăm năm mươi nghìn bảy trăm linh năm"},
        {"500209037", L"năm trăm triệu hai trăm linh chín nghìn không trăm ba mươi bảy"},
        {"7312836", L"bảy triệu ba trăm mười hai nghìn tám trăm ba mươi sáu"},
        {"57602511", L"năm mươi bảy triệu sáu trăm linh hai nghìn năm trăm mười một"},
        {"351600307", L"ba trăm năm mươi mốt triệu sáu trăm nghìn ba trăm linh bảy"},
        {"900370200", L"chín trăm triệu ba trăm bảy mươi nghìn hai trăm"},
        {"400070192", L"bốn trăm triệu không trăm bảy mươi nghìn một trăm chín mươi hai"},
        {"10250214", L"mười triệu hai trăm năm mươi nghìn hai trăm mười bốn"},
        {"253564888", L"hai trăm năm mươi ba triệu năm trăm sáu mươi tư nghìn tám trăm tám mươi tám"},
        {"400036105", L"bốn trăm triệu không trăm ba mươi sáu nghìn một trăm linh năm"},
        {"700000231", L"bảy trăm triệu không nghìn hai trăm ba mươi mốt"},
    };
    std::wcout << "\n";
    for (auto const& p : testCaseWithAnswers)
    {
        assert(p.second == toVnStr(p.first));
        std::wcout << p.first.c_str() << "\n"
                   << p.second << "\n"
                   << toVnStr(p.first) << "\n\n";
    }
}

std::wstring toVnStrLt100(const std::string& num)
{
    if (num.size() == 1) return CHU_SO[num[0] - '0'];
    auto result = num[0] == '1' ? MUOIF : (CHU_SO[num[0] - '0'] + SPACE + MUOI);
    if (num[1] == '0') return result;
    result += SPACE;
    if (num[1] == '1' && num[0] != '1') result += MOTS;
    else if (num[1] == '4' && num[0] != '1') result += TU;
    else if (num[1] == '5') result += LAM;
    else result += CHU_SO[num[1] - '0'];
    return result;
}

std::wstring toVnStrLt1000(const std::string& num)
{
    if (num.size() < 3) return toVnStrLt100(num);
    auto result = CHU_SO[num[0] - '0'] + SPACE + TRAM;
    if (num[1] == '0' && num[2] == '0') //[0-9]00
        return num[0] == '0' ? std::wstring{} : result;
    if (num[1] == '0')  //[1-9]0[1-9]
        return result + SPACE + LINH + SPACE + CHU_SO[num[2] - '0'];
    return result + SPACE + toVnStrLt100(num.substr(1));
}

std::wstring toVnStrLt1e9(const std::string& num)
{
    if (num.size() < 4) return toVnStrLt1000(num);
    int splitIndex = num.size() % 3;
    if (!splitIndex) splitIndex = 3;
    auto left = toVnStrLt1e9(num.substr(0, splitIndex));
    auto right = toVnStrLt1e9(num.substr(splitIndex));
    if (left.empty() && right.empty()) return std::wstring{};
    auto const& hang = NGAN_TR[(num.size() - splitIndex) / 3 - 1];
    if (left.empty()) return CHU_SO[0] + SPACE + hang + SPACE + right;
    if (right.empty()) return left + SPACE + hang;
    return left + SPACE + hang + SPACE + right;
}

std::wstring toVnStrAbitrary(const std::string& num)
{
    if (num.size() < 10) return toVnStrLt1e9(num);
    int splitIndex = num.size() % 9;
    if (!splitIndex) splitIndex = 9;
    auto left = toVnStrLt1e9(num.substr(0, splitIndex));
    auto right = toVnStrAbitrary(num.substr(splitIndex));
    if (left.empty()) return right;
    auto hang = TY;
    for (auto i = (num.size() - splitIndex) / 9; i-->1; hang += SPACE + TY);
    if (right.empty()) return left + SPACE + hang;
    return left + SPACE + hang + COMMA + right;
}

std::string stripZeros(const std::string& s, size_t z=0)
{
    while (z < s.size() && s[z] == '0') ++z;
    return s[z-1] == '0' ? s.substr(z) : s;
}

std::wstring toVnStr(const std::string& num)
{
    if (std::any_of(begin(num), end(num), [](auto c) { return !isdigit(c); }))
        throw std::invalid_argument("Input string must consist of digits (0-9) only.");
    auto s = stripZeros(num);
    return toVnStrAbitrary(s.empty() ? "0" : s);
}

bực cái chỗ windows nó chơi wstring bê đê dễ sợ

output

0 = không
1 = một
2 = hai
3 = ba
4 = bốn
5 = năm
6 = sáu
7 = bảy
8 = tám
9 = chín
10 = mười
11 = mười một
12 = mười hai
20 = hai mươi
21 = hai mươi mốt
22 = hai mươi hai
24 = hai mươi tư
90 = chín mươi
91 = chín mươi mốt
97 = chín mươi bảy
300 = ba trăm
999 = chín trăm chín mươi chín
121 = một trăm hai mươi mốt
215 = hai trăm mười lăm
5121 = năm nghìn một trăm hai mươi mốt
39500 = ba mươi chín nghìn năm trăm
1025217 = một triệu không trăm hai mươi lăm nghìn hai trăm mười bảy
51105500 = năm mươi mốt triệu một trăm linh năm nghìn năm trăm
51000000 = năm mươi mốt triệu
999999999 = chín trăm chín mươi chín triệu chín trăm chín mươi chín nghìn chín trăm chín mươi chín
5120625952200 = năm nghìn một trăm hai mươi tỷ, sáu trăm hai mươi lăm triệu chín trăm năm mươi hai nghìn hai trăm
12000000000000000000 = mười hai tỷ tỷ
18446744073709551615 = mười tám tỷ tỷ, bốn trăm bốn mươi sáu triệu bảy trăm bốn mươi tư nghìn không trăm bảy mươi ba tỷ, bảy trăm linh chín triệu năm trăm năm mươi mốt nghìn sáu trăm mười lăm
18000000000709551615 = mười tám tỷ tỷ, bảy trăm linh chín triệu năm trăm năm mươi mốt nghìn sáu trăm mười lăm
1000015 = một triệu không nghìn không trăm mười lăm
1002015 = một triệu không trăm linh hai nghìn không trăm mười lăm
1000000024 = một tỷ, không triệu không nghìn không trăm hai mươi tư
03215 = ba nghìn hai trăm mười lăm
 = không
0000 = không
00001 = một
00100 = một trăm
1844674407370955161518000000000000000000709551615 = một nghìn tám trăm bốn mươi tư tỷ tỷ tỷ tỷ tỷ, sáu trăm bảy mươi tư triệu bốn trăm linh bảy nghìn ba trăm bảy mươi tỷ tỷ tỷ tỷ, chín trăm năm mươi lăm triệu một trăm sáu mươi mốt nghìn năm trăm mười tám tỷ tỷ tỷ, bảy trăm linh chín triệu năm trăm năm mươi mốt nghìn sáu trăm mười lăm
0321 = ba trăm hai mươi mốt
000345 = ba trăm bốn mươi lăm
15 = mười lăm
40430203 = bốn mươi triệu bốn trăm ba mươi nghìn hai trăm linh ba
3209 = ba nghìn hai trăm linh chín
3500 = ba nghìn năm trăm
3901 = ba nghìn chín trăm linh một
21 = hai mươi mốt
3005 = ba nghìn không trăm linh năm
3055 = ba nghìn không trăm năm mươi lăm
9031 = chín nghìn không trăm ba mươi mốt
9330 = chín nghìn ba trăm ba mươi
9000005 = chín triệu không nghìn không trăm linh năm
9001005 = chín triệu không trăm linh một nghìn không trăm linh năm

32000000
ba mươi hai triệu
ba mươi hai triệu

32516000
ba mươi hai triệu năm trăm mười sáu nghìn
ba mươi hai triệu năm trăm mười sáu nghìn

32516497
ba mươi hai triệu năm trăm mười sáu nghìn bốn trăm chín mươi bảy
ba mươi hai triệu năm trăm mười sáu nghìn bốn trăm chín mươi bảy

834291712
tám trăm ba mươi tư triệu hai trăm chín mươi mốt nghìn bảy trăm mười hai
tám trăm ba mươi tư triệu hai trăm chín mươi mốt nghìn bảy trăm mười hai

308250705
ba trăm linh tám triệu hai trăm năm mươi nghìn bảy trăm linh năm
ba trăm linh tám triệu hai trăm năm mươi nghìn bảy trăm linh năm

500209037
năm trăm triệu hai trăm linh chín nghìn không trăm ba mươi bảy
năm trăm triệu hai trăm linh chín nghìn không trăm ba mươi bảy

7312836
bảy triệu ba trăm mười hai nghìn tám trăm ba mươi sáu
bảy triệu ba trăm mười hai nghìn tám trăm ba mươi sáu

57602511
năm mươi bảy triệu sáu trăm linh hai nghìn năm trăm mười một
năm mươi bảy triệu sáu trăm linh hai nghìn năm trăm mười một

351600307
ba trăm năm mươi mốt triệu sáu trăm nghìn ba trăm linh bảy
ba trăm năm mươi mốt triệu sáu trăm nghìn ba trăm linh bảy

900370200
chín trăm triệu ba trăm bảy mươi nghìn hai trăm
chín trăm triệu ba trăm bảy mươi nghìn hai trăm

400070192
bốn trăm triệu không trăm bảy mươi nghìn một trăm chín mươi hai
bốn trăm triệu không trăm bảy mươi nghìn một trăm chín mươi hai

10250214
mười triệu hai trăm năm mươi nghìn hai trăm mười bốn
mười triệu hai trăm năm mươi nghìn hai trăm mười bốn

253564888
hai trăm năm mươi ba triệu năm trăm sáu mươi tư nghìn tám trăm tám mươi tám
hai trăm năm mươi ba triệu năm trăm sáu mươi tư nghìn tám trăm tám mươi tám

400036105
bốn trăm triệu không trăm ba mươi sáu nghìn một trăm linh năm
bốn trăm triệu không trăm ba mươi sáu nghìn một trăm linh năm

700000231
bảy trăm triệu không nghìn hai trăm ba mươi mốt
bảy trăm triệu không nghìn hai trăm ba mươi mốt

(Tiến Nguyễn) #19

Làm chi kinh khủng vậy?? simple thôi :))


(‏) #20

simple thì nó đọc thua các em tiểu học đọc @_@


83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?