Задача: Преобразование сумм из цифрового представления в строковое
Исходник: перевод числа в числительное, язык: C++ [code #602, hits: 8386]
автор: - [добавлен: 23.12.2009]
  1. #include "to_numeral.h"
  2.  
  3. std::string aszNumeral;
  4. int iNum = -13456737;
  5. to_numeral<int, char, ru_lower_locale_tag>(iNum, aszNumeral);
  6. // aszNumeral = "минус тринадцать миллионов четыреста пятьдесят шесть тысяч семьсот тридцать семь "
  7.  
  8. std::wstring wszNumeral;
  9. __int64 i64Num = 13134563467;
  10. to_numeral<__int64, wchar_t, ru_upper_locale_tag>(i64Num, wszNumeral);
  11. // wszNumeral = "ТРИНАДЦАТЬ МИЛЛИАРДОВ СТО ТРИДЦАТЬ ЧЕТЫРЕ МИЛЛИОНА ПЯТЬСОТ ШЕСТЬДЕСЯТ ТРИ ТЫСЯЧИ ЧЕТЫРЕСТА ШЕСТЬДЕСЯТ СЕМЬ "
  12.  
  13.  
  14. //////////////////////////////////////////////////////////////////////////////////////////
  15. //
  16. // ru_lower_locale.h
  17. //
  18. //////////////////////////////////////////////////////////////////////////////////////////
  19.  
  20. #ifndef __RU_LOWER_LOCALE_H__
  21. #define __RU_LOWER_LOCALE_H__
  22.  
  23. #pragma once
  24.  
  25. //////////////////////////////////////////////////////////////////////////////////////////
  26. struct ru_lower_locale_tag { };
  27. //////////////////////////////////////////////////////////////////////////////////////////
  28.  
  29. //////////////////////////////////////////////////////////////////////////////////////////
  30. template <>
  31. const char*** ToNumeralLocale<char, ru_lower_locale_tag>(void)
  32. {
  33. typedef char char_type;
  34.  
  35. static const char_type* g_pServiceArr[] =
  36. { "ноль", "минус " };
  37. static const char_type* g_pFirstNumeralArr[] =
  38. { "один ", "одиннадцать ", "десять ", "сто ", "одна " };
  39. static const char_type* g_pSecondNumeralArr[] =
  40. { "два ", "двенадцать ", "двадцать ", "двести ", "две " };
  41. static const char_type* g_pThirdNumeralArr[] =
  42. { "три ", "тринадцать ", "тридцать ", "триста " };
  43. static const char_type* g_pFourthNumeralArr[] =
  44. { "четыре ", "четырнадцать ", "сорок ", "четыреста " };
  45. static const char_type* g_pFifthNumeralArr[] =
  46. { "пять ", "пятнадцать ", "пятьдесят ", "пятьсот " };
  47. static const char_type* g_pSixthNumeralArr[] =
  48. { "шесть ", "шестнадцать ", "шестьдесят ", "шестьсот " };
  49. static const char_type* g_pSeventhNumeralArr[] =
  50. { "семь ", "семнадцать ", "семьдесят ", "семьсот " };
  51. static const char_type* g_pEighthNumeralArr[] =
  52. { "восемь ", "восемнадцать ", "восемьдесят ","восемьсот " };
  53. static const char_type* g_pNinthNumeralArr[] =
  54. { "девять ", "девятнадцать ", "девяносто ", "девятьсот " };
  55.  
  56. static const char_type* g_pFirstTriadArr[] =
  57. { "тысяча ", "тысячи ", "тысяч " };
  58. static const char_type* g_pSecondTriadArr[] =
  59. { "миллион ", "миллиона ", "миллионов " };
  60. static const char_type* g_pThirdTriadArr[] =
  61. { "миллиард ", "миллиарда ", "миллиардов " };
  62. static const char_type* g_pFourthTriadArr[] =
  63. { "триллион ", "триллиона ", "триллионов " };
  64. static const char_type* g_pFifthTriadArr[] =
  65. { "триллиард ","триллиарда ", "триллиардов " };
  66.  
  67. static const char_type** g_NumeralLocale[] =
  68. {
  69. g_pServiceArr,
  70. g_pFirstNumeralArr, g_pSecondNumeralArr, g_pThirdNumeralArr,
  71. g_pFourthNumeralArr, g_pFifthNumeralArr, g_pSixthNumeralArr,
  72. g_pSeventhNumeralArr, g_pEighthNumeralArr, g_pNinthNumeralArr,
  73. g_pFirstTriadArr, g_pSecondTriadArr, g_pThirdTriadArr,
  74. g_pFourthTriadArr, g_pFifthTriadArr
  75. };
  76. return g_NumeralLocale;
  77. }
  78. //////////////////////////////////////////////////////////////////////////////////////////
  79.  
  80. //////////////////////////////////////////////////////////////////////////////////////////
  81. template <>
  82. const wchar_t*** ToNumeralLocale<wchar_t, ru_lower_locale_tag>(void)
  83. {
  84. typedef wchar_t char_type;
  85.  
  86. static const char_type* g_pServiceArr[] =
  87. { L"ноль", L"минус " };
  88. static const char_type* g_pFirstNumeralArr[] =
  89. { L"один ", L"одиннадцать ", L"десять ", L"сто ", L"одна " };
  90. static const char_type* g_pSecondNumeralArr[] =
  91. { L"два ", L"двенадцать ", L"двадцать ", L"двести ", L"две " };
  92. static const char_type* g_pThirdNumeralArr[] =
  93. { L"три ", L"тринадцать ", L"тридцать ", L"триста " };
  94. static const char_type* g_pFourthNumeralArr[] =
  95. { L"четыре ", L"четырнадцать ", L"сорок ", L"четыреста " };
  96. static const char_type* g_pFifthNumeralArr[] =
  97. { L"пять ", L"пятнадцать ", L"пятьдесят ", L"пятьсот " };
  98. static const char_type* g_pSixthNumeralArr[] =
  99. { L"шесть ", L"шестнадцать ", L"шестьдесят ", L"шестьсот " };
  100. static const char_type* g_pSeventhNumeralArr[] =
  101. { L"семь ", L"семнадцать ", L"семьдесят ", L"семьсот " };
  102. static const char_type* g_pEighthNumeralArr[] =
  103. { L"восемь ", L"восемнадцать ", L"восемьдесят ",L"восемьсот " };
  104. static const char_type* g_pNinthNumeralArr[] =
  105. { L"девять ", L"девятнадцать ", L"девяносто ", L"девятьсот " };
  106.  
  107. static const char_type* g_pFirstTriadArr[] =
  108. { L"тысяча ", L"тысячи ", L"тысяч " };
  109. static const char_type* g_pSecondTriadArr[] =
  110. { L"миллион ", L"миллиона ", L"миллионов " };
  111. static const char_type* g_pThirdTriadArr[] =
  112. { L"миллиард ", L"миллиарда ", L"миллиардов " };
  113. static const char_type* g_pFourthTriadArr[] =
  114. { L"триллион ", L"триллиона ", L"триллионов " };
  115. static const char_type* g_pFifthTriadArr[] =
  116. { L"триллиард ",L"триллиарда ", L"триллиардов " };
  117.  
  118. static const char_type** g_NumeralLocale[] =
  119. {
  120. g_pServiceArr,
  121. g_pFirstNumeralArr, g_pSecondNumeralArr, g_pThirdNumeralArr,
  122. g_pFourthNumeralArr, g_pFifthNumeralArr, g_pSixthNumeralArr,
  123. g_pSeventhNumeralArr, g_pEighthNumeralArr, g_pNinthNumeralArr,
  124. g_pFirstTriadArr, g_pSecondTriadArr, g_pThirdTriadArr,
  125. g_pFourthTriadArr, g_pFifthTriadArr
  126. };
  127. return g_NumeralLocale;
  128. }
  129. //////////////////////////////////////////////////////////////////////////////////////////
  130.  
  131. //////////////////////////////////////////////////////////////////////////////////////////
  132. //////////////////////////////////////////////////////////////////////////////////////////
  133.  
  134. #endif // __RU_LOWER_LOCALE_H__
  135.  
  136.  
  137. //////////////////////////////////////////////////////////////////////////////////////////
  138. //
  139. // ru_upper_locale.h
  140. //
  141. //////////////////////////////////////////////////////////////////////////////////////////
  142.  
  143. #ifndef __RU_UPPER_LOCALE_H__
  144. #define __RU_UPPER_LOCALE_H__
  145.  
  146. #pragma once
  147.  
  148. //////////////////////////////////////////////////////////////////////////////////////////
  149. struct ru_upper_locale_tag { };
  150. //////////////////////////////////////////////////////////////////////////////////////////
  151.  
  152. //////////////////////////////////////////////////////////////////////////////////////////
  153. template <>
  154. const char*** ToNumeralLocale<char, ru_upper_locale_tag>(void)
  155. {
  156. typedef char char_type;
  157.  
  158. static const char_type* g_pServiceArr[] =
  159. { "НОЛЬ", "МИНУС " };
  160. static const char_type* g_pFirstNumeralArr[] =
  161. { "ОДИН ", "ОДИННАДЦАТЬ ", "ДЕСЯТЬ ", "СТО ", "ОДНА " };
  162. static const char_type* g_pSecondNumeralArr[] =
  163. { "ДВА ", "ДВЕНАДЦАТЬ ", "ДВАДЦАТЬ ", "ДВЕСТИ ", "ДВЕ " };
  164. static const char_type* g_pThirdNumeralArr[] =
  165. { "ТРИ ", "ТРИНАДЦАТЬ ", "ТРИДЦАТЬ ", "ТРИСТА " };
  166. static const char_type* g_pFourthNumeralArr[] =
  167. { "ЧЕТЫРЕ ", "ЧЕТЫРНАДЦАТЬ ", "СОРОК ", "ЧЕТЫРЕСТА " };
  168. static const char_type* g_pFifthNumeralArr[] =
  169. { "ПЯТЬ ", "ПЯТНАДЦАТЬ ", "ПЯТЬДЕСЯТ ", "ПЯТЬСОТ " };
  170. static const char_type* g_pSixthNumeralArr[] =
  171. { "ШЕСТЬ ", "ШЕСТНАДЦАТЬ ", "ШЕСТЬДЕСЯТ ", "ШЕСТЬСОТ " };
  172. static const char_type* g_pSeventhNumeralArr[] =
  173. { "СЕМЬ ", "СЕМНАДЦАТЬ ", "СЕМЬДЕСЯТ ", "СЕМЬСОТ " };
  174. static const char_type* g_pEighthNumeralArr[] =
  175. { "ВОСЕМЬ ", "ВОСЕМНАДЦАТЬ ", "ВОСЕМЬДЕСЯТ ","ВОСЕМЬСОТ " };
  176. static const char_type* g_pNinthNumeralArr[] =
  177. { "ДЕВЯТЬ ", "ДЕВЯТНАДЦАТЬ ", "ДЕВЯНОСТО ", "ДЕВЯТЬСОТ " };
  178.  
  179. static const char_type* g_pFirstTriadArr[] =
  180. { "ТЫСЯЧА ", "ТЫСЯЧИ ", "ТЫСЯЧ " };
  181. static const char_type* g_pSecondTriadArr[] =
  182. { "МИЛЛИОН ", "МИЛЛИОНА ", "МИЛЛИОНОВ " };
  183. static const char_type* g_pThirdTriadArr[] =
  184. { "МИЛЛИАРД ", "МИЛЛИАРДА ", "МИЛЛИАРДОВ " };
  185. static const char_type* g_pFourthTriadArr[] =
  186. { "ТРИЛЛИОН ", "ТРИЛЛИОНА ", "ТРИЛЛИОНОВ " };
  187. static const char_type* g_pFifthTriadArr[] =
  188. { "ТРИЛЛИАРД ","ТРИЛЛИАРДА ", "ТРИЛЛИАРДОВ " };
  189.  
  190. static const char_type** g_NumeralLocale[] =
  191. {
  192. g_pServiceArr,
  193. g_pFirstNumeralArr, g_pSecondNumeralArr, g_pThirdNumeralArr,
  194. g_pFourthNumeralArr, g_pFifthNumeralArr, g_pSixthNumeralArr,
  195. g_pSeventhNumeralArr, g_pEighthNumeralArr, g_pNinthNumeralArr,
  196. g_pFirstTriadArr, g_pSecondTriadArr, g_pThirdTriadArr,
  197. g_pFourthTriadArr, g_pFifthTriadArr
  198. };
  199. return g_NumeralLocale;
  200. }
  201. //////////////////////////////////////////////////////////////////////////////////////////
  202.  
  203. //////////////////////////////////////////////////////////////////////////////////////////
  204. template <>
  205. const wchar_t*** ToNumeralLocale<wchar_t, ru_upper_locale_tag>(void)
  206. {
  207. typedef wchar_t char_type;
  208.  
  209. static const char_type* g_pServiceArr[] =
  210. { L"НОЛЬ", L"МИНУС " };
  211. static const char_type* g_pFirstNumeralArr[] =
  212. { L"ОДИН ", L"ОДИННАДЦАТЬ ", L"ДЕСЯТЬ ", L"СТО ", L"ОДНА " };
  213. static const char_type* g_pSecondNumeralArr[] =
  214. { L"ДВА ", L"ДВЕНАДЦАТЬ ", L"ДВАДЦАТЬ ", L"ДВЕСТИ ", L"ДВЕ " };
  215. static const char_type* g_pThirdNumeralArr[] =
  216. { L"ТРИ ", L"ТРИНАДЦАТЬ ", L"ТРИДЦАТЬ ", L"ТРИСТА " };
  217. static const char_type* g_pFourthNumeralArr[] =
  218. { L"ЧЕТЫРЕ ", L"ЧЕТЫРНАДЦАТЬ ", L"СОРОК ", L"ЧЕТЫРЕСТА " };
  219. static const char_type* g_pFifthNumeralArr[] =
  220. { L"ПЯТЬ ", L"ПЯТНАДЦАТЬ ", L"ПЯТЬДЕСЯТ ", L"ПЯТЬСОТ " };
  221. static const char_type* g_pSixthNumeralArr[] =
  222. { L"ШЕСТЬ ", L"ШЕСТНАДЦАТЬ ", L"ШЕСТЬДЕСЯТ ", L"ШЕСТЬСОТ " };
  223. static const char_type* g_pSeventhNumeralArr[] =
  224. { L"СЕМЬ ", L"СЕМНАДЦАТЬ ", L"СЕМЬДЕСЯТ ", L"СЕМЬСОТ " };
  225. static const char_type* g_pEighthNumeralArr[] =
  226. { L"ВОСЕМЬ ", L"ВОСЕМНАДЦАТЬ ", L"ВОСЕМЬДЕСЯТ ",L"ВОСЕМЬСОТ " };
  227. static const char_type* g_pNinthNumeralArr[] =
  228. { L"ДЕВЯТЬ ", L"ДЕВЯТНАДЦАТЬ ", L"ДЕВЯНОСТО ", L"ДЕВЯТЬСОТ " };
  229.  
  230. static const char_type* g_pFirstTriadArr[] =
  231. { L"ТЫСЯЧА ", L"ТЫСЯЧИ ", L"ТЫСЯЧ " };
  232. static const char_type* g_pSecondTriadArr[] =
  233. { L"МИЛЛИОН ", L"МИЛЛИОНА ", L"МИЛЛИОНОВ " };
  234. static const char_type* g_pThirdTriadArr[] =
  235. { L"МИЛЛИАРД ", L"МИЛЛИАРДА ", L"МИЛЛИАРДОВ " };
  236. static const char_type* g_pFourthTriadArr[] =
  237. { L"ТРИЛЛИОН ", L"ТРИЛЛИОНА ", L"ТРИЛЛИОНОВ " };
  238. static const char_type* g_pFifthTriadArr[] =
  239. { L"ТРИЛЛИАРД ",L"ТРИЛЛИАРДА ", L"ТРИЛЛИАРДОВ " };
  240.  
  241. static const char_type** g_NumeralLocale[] =
  242. {
  243. g_pServiceArr,
  244. g_pFirstNumeralArr, g_pSecondNumeralArr, g_pThirdNumeralArr,
  245. g_pFourthNumeralArr, g_pFifthNumeralArr, g_pSixthNumeralArr,
  246. g_pSeventhNumeralArr, g_pEighthNumeralArr, g_pNinthNumeralArr,
  247. g_pFirstTriadArr, g_pSecondTriadArr, g_pThirdTriadArr,
  248. g_pFourthTriadArr, g_pFifthTriadArr
  249. };
  250. return g_NumeralLocale;
  251. }
  252. //////////////////////////////////////////////////////////////////////////////////////////
  253.  
  254. //////////////////////////////////////////////////////////////////////////////////////////
  255. //////////////////////////////////////////////////////////////////////////////////////////
  256.  
  257. #endif // __RU_UPPER_LOCALE_H__
  258.  
  259.  
  260. //////////////////////////////////////////////////////////////////////////////////////////
  261. //
  262. // to_numeral_locale.h
  263. //
  264. //////////////////////////////////////////////////////////////////////////////////////////
  265.  
  266. #ifndef __TO_NUMERAL_LOCALE_H__
  267. #define __TO_NUMERAL_LOCALE_H__
  268.  
  269. #pragma once
  270.  
  271. //////////////////////////////////////////////////////////////////////////////////////////
  272. template <typename CharType, typename LocaleTag>
  273. const CharType*** ToNumeralLocale(void);
  274.  
  275. #include "ru_lower_locale.h"
  276. #include "ru_upper_locale.h"
  277. //////////////////////////////////////////////////////////////////////////////////////////
  278.  
  279. //////////////////////////////////////////////////////////////////////////////////////////
  280. template <typename CharType, typename LocaleTag>
  281. struct to_numeral_locale
  282. {
  283. typedef CharType char_type;
  284. typedef LocaleTag locale_tag;
  285.  
  286. //////////////////////////////////////////////////////////////////////////////////////
  287. static const char_type* Null(void)
  288. { return ToNumeralLocale<char_type, locale_tag>()[0][0]; }
  289. static const char_type* Minus(void)
  290. { return ToNumeralLocale<char_type, locale_tag>()[0][1]; }
  291.  
  292. static const char_type* Numeral(const int ciDigit, const int ciExt)
  293. { return ToNumeralLocale<char_type, locale_tag>()[ciDigit][ciExt]; }
  294.  
  295. static const char_type* TriadName(const int ciIndex, const int ciExt)
  296. { return ToNumeralLocale<char_type, locale_tag>()[9 + ciIndex][ciExt]; }
  297. //////////////////////////////////////////////////////////////////////////////////////
  298. };
  299. //////////////////////////////////////////////////////////////////////////////////////////
  300.  
  301. //////////////////////////////////////////////////////////////////////////////////////////
  302. //////////////////////////////////////////////////////////////////////////////////////////
  303.  
  304. #endif // __TO_NUMERAL_LOCALE_H__
  305.  
  306.  
  307. //////////////////////////////////////////////////////////////////////////////////////////
  308. //
  309. // to_numeral.h
  310. //
  311. //////////////////////////////////////////////////////////////////////////////////////////
  312.  
  313. #ifndef __TO_NUMERAL_H__
  314. #define __TO_NUMERAL_H__
  315.  
  316. #pragma once
  317.  
  318. #include <string>
  319. #include <vector>
  320. #include "to_numeral_locale.h"
  321.  
  322. //////////////////////////////////////////////////////////////////////////////////////////
  323. template <typename NumType, typename CharType, typename LocaleTag>
  324. class to_numeral
  325. {
  326. public:
  327. typedef NumType num_type;
  328. typedef CharType char_type;
  329. typedef LocaleTag locale_tag;
  330. typedef to_numeral_locale<char_type, locale_tag> locale_type;
  331. typedef std::basic_string<char_type> string;
  332.  
  333. //////////////////////////////////////////////////////////////////////////////////////
  334. public:
  335. to_numeral(const num_type tNum, string& szOut)
  336. { Proccess(tNum, szOut); }
  337. private:
  338. to_numeral(void);
  339. to_numeral(const to_numeral&);
  340. //////////////////////////////////////////////////////////////////////////////////////
  341.  
  342. private:
  343. //////////////////////////////////////////////////////////////////////////////////////
  344. inline void Proccess(const num_type tOrigNum, string& szOut) const
  345. {
  346. if(!tOrigNum) { szOut = locale_type::Null(); return; }
  347. else szOut.clear();
  348.  
  349. std::vector<int> vDigit;
  350. {
  351. num_type tNum =
  352. (tOrigNum > 0 ? tOrigNum : (szOut = locale_type::Minus(), -tOrigNum));
  353. do { vDigit.push_back(tNum % 10); tNum /= 10; } while(tNum);
  354. }
  355.  
  356. typedef std::vector<int>::const_iterator const_it;
  357. const_it citCursor = vDigit.end();
  358. // порядок чиса
  359. const int iExp = vDigit.size();
  360. // количество триад
  361. int iTriad = (iExp / 3) - (!(iExp % 3) ? 1 : 0);
  362. // количество цифр в старшей триаде
  363. int iCount = (iExp - (iTriad * 3));
  364. int iDigit = 0;
  365. int iTriadName = -1;
  366.  
  367. do
  368. {
  369. do
  370. {
  371. if(!(iDigit = *(--citCursor))) continue;
  372. switch(iCount)
  373. {
  374. //////////////////////////////////////////////////////////////////////////
  375. case 1: // единицы
  376. if(iTriad == 1 && iDigit < 3)
  377. szOut += locale_type::Numeral(iDigit, 4);
  378. else
  379. szOut += locale_type::Numeral(iDigit, 0);
  380. switch(iDigit)
  381. {
  382. case 1: iTriadName = 0; break;
  383. case 2:
  384. case 3:
  385. case 4: iTriadName = 1; break;
  386. default: iTriadName = 2; break;
  387. }
  388. break;
  389. //////////////////////////////////////////////////////////////////////////
  390. case 2: // десятки
  391. if(iDigit == 1) // вторая десятка
  392. {
  393. iDigit = *(--citCursor);
  394. if(!iDigit) szOut += locale_type::Numeral(1, 2);
  395. else szOut += locale_type::Numeral(iDigit, 1);
  396. --iCount;
  397. }
  398. else
  399. szOut += locale_type::Numeral(iDigit, 2);
  400. iTriadName = 2;
  401. break;
  402. //////////////////////////////////////////////////////////////////////////
  403. case 3: // сотни
  404. szOut += locale_type::Numeral(iDigit, 3);
  405. iTriadName = 2;
  406. break;
  407. //////////////////////////////////////////////////////////////////////////
  408. }
  409. }
  410. while(--iCount);
  411. if(!iTriad) return;
  412. if(iTriadName != -1) szOut += locale_type::TriadName(iTriad, iTriadName);
  413. iTriadName = -1;
  414. iCount = 3;
  415. --iTriad;
  416. }
  417. while(true);
  418. }
  419. //////////////////////////////////////////////////////////////////////////////////////
  420. };
  421. //////////////////////////////////////////////////////////////////////////////////////////
  422.  
  423. //////////////////////////////////////////////////////////////////////////////////////////
  424. //////////////////////////////////////////////////////////////////////////////////////////
  425.  
  426. #endif // __TO_NUMERAL_H__

+добавить реализацию