Форум программистов, компьютерный форум CyberForum.ru

Записать число словами - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 66, средняя оценка - 4.82
Хитрый_КОТ
 Аватар для Хитрый_КОТ
3 / 3 / 1
Регистрация: 21.11.2010
Сообщений: 30
13.05.2011, 19:23     Записать число словами #1
У меня такой вопрос:
Как целое число до 10 000 записать словами???
например вводим с клавиатуры 123 а она выводит "сто двадцать три"
Лично все написал по следущему алгоритму:
1) сперва разбил число на элементы (тысячи сотни десятки еденицы)
2) уложил их в массив (из 4х элементов)
3) а потом на операторе if для каждого элемента (всего вышло 4х9 + 9для десятков)

В общем получился огромный код на 6 стр А4
А хочется уменьшить его в 2-3 раза до 2-3стр

в общем хочу сделать чтобы работало анологично как для обычного числового массива через for


C++
1
2
3
4
5
6
7
for (int k=0; k<10; k++)
{
if(mass[q]==k)
{
cout<<slovo[k]<<endl; // char slovo[] зависящая от k или под номером или индефикатором k
}
}
1) как можно строкам ( char[] ) номера присвоить, в зависимости от k выводится то или иное слово
2) можно ли забить массив строками, наприм каждый элемент содержит по слову (или два и более слов)
slovo[1]= "один"
slovo[2]= "два"
....
slovo[k]="некое число"
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
skaa
Хочу в Исландию
 Аватар для skaa
1024 / 823 / 75
Регистрация: 10.11.2010
Сообщений: 1,626
13.05.2011, 19:40     Записать число словами #2
У меня есть эта программа по-английски, если надо могу напечатать.
Хитрый_КОТ
 Аватар для Хитрый_КОТ
3 / 3 / 1
Регистрация: 21.11.2010
Сообщений: 30
13.05.2011, 19:46  [ТС]     Записать число словами #3
давай, посмотрю
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
13.05.2011, 19:50     Записать число словами #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Смотри:

Числа — прописью
Напишем программу, которая чрезвычайно востребована в реальной жизни: вывод числа прописью. Мы не будем писать совсем уж универсальный вариант, так как наша цель — просто поучиться использовать тип string в реальной программе. Ограничим наши числа положительными целыми в диапазоне от 1 до 999 999 999 — такие числа целиком помещаются в целую переменную типа int.

Замечание
Если требуются большие числа, то в системе Visual C++ 6 мы можем использовать нестандартный целый тип __int64. Стандартное решение — использовать структуру с двумя полями типа long.

Мы не зря написали число 999 999 999 с пробелами между тройками чисел — числительные от 1 до 999 пишутся одинаково, независимо от местоположения. Вся разница — в слове после очередной тройки: старшая — это миллионы, средняя — это тысячи, а младшая — непосредственно рубли. Поэтому естественно написать функцию, которая получает число от 1 до 999, и выдает результат типа string. В этом случае мы сможем инкапсулировать все массивы числительных в этой процедуре. Однако миллионы и рубли у нас мужского рода, а тысячи — женского. Поэтому вместо «один» и «два» надо писать «одна» и «две». В остальном числительные полностью совпадают. Поэтому мы должны прописать второй параметр типа bool, который всегда будет false, а для тысяч — true (листинг 5.6).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Листинг 5.6. Функция toNumeral — трехзначное число прописью
 //--обрабатывает только 3-хзначное число
string toNumeral(unsigned long Number, bool Thousands)
{ string units    [] = 
  {"один","два","три","четыре","пять","шесть", "семь","восемь","девять"}; 
  string tens     [] = 
  {"десять","двадцать","тридцать","сорок","пятьдесят","шестьдесят",
   "семьдесят", "восемьдесят","девяносто"}; 
  string hundreds [] =
  {"сто","двести","триста","четыреста","пятьсот","шестьсот","семьсот",
   "восемьсот","девятьсот"}; 
  string secondten[] = 
  {"одиннадцать","двенадцать","тринадцать","четырнадцать","пятнадцать",
   "шестнадцать","семнадцать","восемнадцать","девятнадцать"}; 
  string Women    [2]= {"одна","две"};    
  string result("");        // пустая строка-результат
  typedef unsigned char byte;   
  byte digits[3] = {0};         // - цифры числа
  unsigned long n = Number;
  digits[0] = n % 10;               //--младшая цифра
  digits[1] = (n / 10) % 10;            //--средняя цифра
  digits[2] = n / 100;          //--старшая цифра
  if (digits[2]>0) result +=(hundreds[digits[2]-1]+" "); 
  if (digits[1]>0)
  { if ((digits[1]==1)&&(digits[0]!=0)) 
    { result +=(secondten[digits[0]-1]+" "); return result; }
    else result +=(tens[digits[1]-1]+" ");
  }
  if (digits[0]>0) 
  { if (((digits[0]>2)&&(digits[1]!=1))||(!Thousands)) 
      result +=(units[digits[0]-1]+" ");
    else result +=(Women[digits[0]-1]+" ");
  }
  return result;
}
Вначале объявляются и инициализируются массивы числительных: в каждом массиве ровно 9 элементов. Затем объявляется и заполняется массив для трех цифр числа: младшая цифра — по меньшему индексу. Наконец, начинаются проверки цифр и получение строки-результата. Первоначально строка-результат пустая. Если очередная цифра не равна нулю, то к строке-результату прицепляется очередное числительное. Особый случай составляет вторая цифра: если она равна 1, то мы тут же проверяем третью. Если она не равна нулю, то мы прицепляем числительное из массива secondten и выходим. При определении единиц для 1 или 2 используется массив Women для числительного женского рода.
Обратите также внимание на то, как вычисляется индекс числительного — это довольно распространенный прием. Протестируем нашу функцию (листинг 5.7).
C++
1
2
3
4
5
6
7
8
9
10
Листинг 5.7. Тестовая программа для функции toNumeral
int main()
{ unsigned long Number[] = 
  {1,2,9,10,11,19,20,21,22,45,100,101,102,109,110,118,150,870,912,999};
  int k = sizeof(Number)/sizeof(unsigned long);
  char s[200]={0}; 
  for (int i = 0; i < k; ++i)
  { CharToOem(toNumeral(Number[i],true).c_str(),s); cout<<s<<endl;  }
  return 0;
}
В этой программе мы объявили тестовый массив Number, и вычислили его длину. Затем в цикле выполняется непосредственное обращение к функции перекодировки. Мы не стали использовать написанные нами ранее функции Rus (см. листинги 4.9 и 5.4). Первый операнд написан несколько необычно. Поскольку мы не записали результата в переменную, система создает анонимный временный объект. Наша функция toNumeral возвращает string, поэтому у результата (временного объекта) есть метод c_str(). Использование временных объектов — полезный прием, которым мы еще не раз будем применять.
Теперь напишем функцию, которая будет формировать наше число прописью. Очевидно, эта функция должна трижды вызвать функцию toNumeral, прицепляя после каждого вызова соответствующее слово (листинг 5.8).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Листинг 5.8. Сумма — прописью  
string Numeral(unsigned int Number)
{   string what_[3][3] = {{"миллион", "миллиона", "миллионов" },
                {"тысяча",  "тысячи",   "тысяч"     },
                {"рубль","рубля","рублей"}};
    unsigned int t = Number;
    unsigned int treads[3];     //--вычисление троек числа
    treads[0]=t%1000; treads[1]=t/1000%1000; treads[2]=t/1000000;
    string result = "";
    if (treads[2] > 0) { result +=toNumeral(treads[2], false);
    if (treads[2]/10 % 10==1) result += what_[0][2];    //-1-
    else 
switch (treads[2] % 10)
    { case 0: case 5: case 6: case 7: case 8: case 9: 
     result += what_[0][2]; break;
      case 2: case 3: case 4: result += what_[0][1]; break;
      case 1:            result += what_[0][0]; break;
    }
    result+=' ';
    }
    if (treads[1] > 0) {result +=toNumeral(treads[1], true);
    if (treads[1]/10 % 10==1) result += what_[1][2];    //-2-
    else switch (treads[1] % 10)
    { case 0: case 5: case 6: 
         case 7: case 8: case 9: result += what_[1][2]; break;
      case 2: case 3: case 4: result += what_[1][1];break;
      case 1:            result += what_[1][0];break;
    }
    result+=' ';
    }
       result +=toNumeral(treads[0], false);
    if (treads[0]/10 % 10==1) result += what_[2][2];    //-3-
    else switch (treads[0] % 10)
    { case 0: case 5: case 6: 
         case 7: case 8: case 9: result += what_[2][2];break;
      case 2: case 3: case 4: result += what_[2][1];break;
      case 1:            result += what_[2][0];break;
    }
    result+=' ';
    return result;
}
Как видите, получилась довольно простая программа. Единственное, на что надо обратить внимание — это помеченные цифрам строки: если у нас вторая цифра в тройке равна 1, то можно сразу прицеплять нужное слово. В стальных случаях мы должны анализировать последнюю цифру. Можно еще больше упростить функцию, если выделить в отдельную функцию совершенно однотипные действия в операторе switch, но оставим это на упражнения.
Yandex
Объявления
13.05.2011, 19:50     Записать число словами
Ответ Создать тему
Опции темы

Текущее время: 23:53. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru