Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > перевод чисел из десятичной системы счисления


Автор: simка 27.11.2004, 22:52
Написать прогу перевода чисел из десятичной системы счисления в Римскую. Исходное число считывается из одного файла, а результат записывается в другой файл.
I-1;V-5;X-10;L-50:C-100;D-500;M-1000

Автор: Intro 28.11.2004, 19:21
Такая прога на олимпиаде была, там не решил, но дома разобрался... короче считывай char[] потом переводи в число, дальше разбирай с лево на право --- естественно перед элементом может стоять I поэтому обязательно это учитывай...

Автор: chipset 28.11.2004, 20:00
Модератор: Название темы должно отражать ее суть!

Автор: sergejzr 28.11.2004, 21:32
Вот написал в обе стороны smile
Комментировать не стал, так как вроде и так всё ясно smile
Кстати, я конечно не всё сам выдумывал уже готового в инете полно smile
Код

#include"iostream.h"
#define MAX_RNUM 512 //Максимальная длинна строки

int main()
{

int choice=0;
char in_stroka[MAX_RNUM];
char*begunok;
int in=0,out=0;

cout<<"Pervod chisel. Vybirajte 1(R-A) 2(A-R)? (1/2)"<<endl;

//Пользователь обязан задать 1 или 2 и ничего другого :)
while(!(choice==1||choice==2))cin>>choice;

switch(choice)
{
   case 1:
   {
       cout<<"Zadajte rimskuju cifru i nazhmite ENTER. Maximal'no: "<<MAX_RNUM<<" znakov"<<endl;
       cin>>in_stroka;

               //Ну вот, смотрим на символ и прибавляем к ответу его значение
       for(begunok=in_stroka;*begunok;begunok++)
       {
           switch(*begunok)
           {
               case 'M': out+=1000; break;
               case 'D': out+=500; break;
               case 'C': out+=100; break;
               case 'L': out+=50; break;
               case 'X': out+=10; break;
               case 'V': out+=5; break;
               case 'I': out+=1; break;
               default:{ cout<<"Neizvestnyj znak!"<<*begunok<<" vyhod!"; return -1; }
           }
           
       }
                //Готово
       cout<<in_stroka<<"(R) = "<<out<<"(A)";
   }
   break;
   case 2:
       {
                                                             
           cout<<"Zadajte Arabskuju cifru i nazhmite ENTER"<<endl;
           cin>>in;
               out=in;        
                               //А здесь "делим" вычитанием. Всё равно каждую букву прорисовывать                                        
               while (out >= 1000)
               {
                   cout<<"M"; out = out-1000;
               }
               if (out >= 500)                                                          
               {
                   cout<<"D"; out = out- 500;
               }
               while (out >=  100)                                                        
               {
                   cout<<"C"; out = out- 100;
               }                                        
               if (out >= 50)                                                            
               {
                   cout<<"L"; out = out-  50;
               }                                        
               while (out >=   10)                                                        
               {
                   cout<<"X"; out = out-  10;
               }                                        
               if (out >=  5)                                                            
               {
                   cout<<"V"; out = out-   5;
               }                                        
               while (out >=    1)                                                        
               {
                   cout<<"I"; out = out-   1;
               }                                      
       }
}
return 0;
}

Автор: Alexandr87 29.11.2004, 14:25
Короче код написанный для перевода рим->дес., работает в некоторых случаях не корректно, не предусмотрен случай когда идет вычитание при стоящем справа меньшем числе:
Так XIX - не 21, а 19.

Алгоритм следующий: (писать код не буду, т.к. некогда, да и опыта мало, чтоб сделать это быстро и понятно)

1.Рассматриваем введеную строку с права налево.
2.Пишем функцию проверки(но можно включить и main()), которая будет принимать два char'a(можно указатели), и выдавать 1, если первый в римской сс, больше второго. Затем, можно воспользоваться тем, что предложил sergej.z , но только ставить условие, мол если следующий за текущем символом больше текущего, то не прибавлять десятичный эквивалент данного char'a, а отнимать его.

Автор: Alexandr87 29.11.2004, 15:24
Вощем вроде вот, контроль вводимых значений делай сам


Код

#include <iostream>
using namespace std;

int comp(char arg1)
{
int argg1=0;
switch (arg1)
{
case 'I':
 argg1=1;break;
case 'V':
 argg1=5;break;
case 'X':
 argg1=10;break;
case 'L':
 argg1=50;break;
case 'C':
 argg1=100;break;
case 'D':
 argg1=500;break;
case 'M':
 argg1=1000;
}
return argg1;
}


void main()
{
int out=0;
char my[50];
cout<<"Vvedite chislo v rimskoi zapisi\n>>";
cin>>my;
for (int x=strlen(my)-1; x>=0; x--)
{
 if (comp(my[x])>=comp(my[x+1]))
  out+=comp(my[x]);
 if (comp(my[x])<comp(my[x+1]))
  out-=comp(my[x]);
}
cout<<out;
cin.get();
cin.get();
}


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)