Programowanie w języku C/C++ » Artykuły

Konwersja liczb rzymskich na arabskie

Prosta metoda na konwersję liczb rzymskich na arabskie.
#include <iostream>
#include <stdlib.h>
 
/******************************************************************************/
using namespace std;
char rzymska[24];
void RzymToArab(char *);
/******************************************************************************/
int main(int argc, char *argv[])
{
  cout << "LiczbChanger\n";
  cout << "Podaj liczbe rzymska, ktora chcesz zamienic na arabska: ";
  cin >> rzymska;
  RzymToArab(rzymska);
  system("PAUSE");        
  return 0;
}
/******************************************************************************/
void RzymToArab(char* zawartosc)
{
  int wynik = 0;
  for(int i = 0; i <= 24; i++)
  {
    if(zawartosc[i] == 'I' && zawartosc[i+1] == 'V')
    {
        wynik+=4;
        i++;
    }
    else if(zawartosc[i] == 'I' && zawartosc[i+1] == 'X')
    {
        wynik+=9;
        i++;
    }
    else if(zawartosc[i] == 'X' && zawartosc[i+1] == 'L')
    {
        wynik+=40;
        i++;
    }
    else if(zawartosc[i] == 'X' && zawartosc[i+1] == 'C')
    {
        wynik+=90;
        i++;
    }    
    else if(zawartosc[i] == 'C' && zawartosc[i+1] == 'D')
    {
        wynik+=400;
        i++;
    }
    else if(zawartosc[i] == 'C' && zawartosc[i+1] == 'M')
    {
        wynik+=900;
        i++;
    }        
    else if(zawartosc[i] == 'I')
    {
        wynik++;
    }
    else if(zawartosc[i] == 'V')
    {
        wynik+=5;
    }
    else if(zawartosc[i] == 'X')
    {
        wynik+=10;
    }
    else if(zawartosc[i] == 'L')
    {
        wynik+=50;
    }
    else if(zawartosc[i] == 'C')
    {
        wynik+=100;
    }
    else if(zawartosc[i] == 'D')
    {
        wynik+=500;
    }    
    else if(zawartosc[i] == 'M')
    {
        wynik+=1000;
    }
    else if(!(zawartosc[i]))
    {
        break;
    }
  }
  cout << zawartosc << " to " << wynik << endl;
}
/******************************************************************************/

10 komentarzy

Ślepiec 2007-06-17 13:16

to dodam swój, sorry że nie jako funkcja :
int main(int argc, char* argv[])
{
        int k=0,b=0,i,l1=0,t=0,l[] = {5,1} ,l10[] = {1000,100,10,1};
        char r[] = {'5','M','D','C','L','X','V','I'};
        char c;
        c = getchar();
        do {
        for (i=0;i<8;i++)
                if (c == r[i]) {
                      t = l10[i/2]* l[i-i/2*2];
                      break;
                }
        if ( t > l1 && b) l1 = t -  l10[i/2+i-i/2*2];
        else {k += l1;
              l1 = t; }
        c = getchar();
        if (!b) b++;
        } while(c != '\n');
        k += l1;
        printf("%d\n",k);
        system("PAUSE");
        return 0;
}

azja 2006-04-24 23:20

A może w taki sposób?

/*zapisuje odczytywane symbole do tablicy i odczytujc od tylu
  sumuje wartosc poszczeglnych symboli, w przypadku gdy poprzedni symbol
  ma wartosc wiksza od aktualnie sprawdzanego (dla liczb 4, 9, 40 itd) odejmuje od ogolnej sumy  wartosc elementu aktualnie sprawdzanego
program nie sprawdza poprawnosci liczby rzymskiej*/

  1. include <stdio.h>
  2. include <conio.h>

int konwersja(char symbol);

main()
{
 const int max = 20;      /*maxymalna ilosc cyfr rzymskich*/
 char rzymska[max];       /*tablica do przechowywania cyfr rzymskich*/
 char znak;               /*wczytywana litera reprezentujca cyfre rzymska*/
 int arab ,               /*wartosc liczby arabskiej*/
     biezaca ,            /*wartosc aktualnie sprawdzanej cyfry*/
     poprzednia,          /*warto poprzedniej cyfry*/
     i,                   /*zmienna kontrolna petli*/
     delta = 32,          /*roznica midzy malymi i duzymi literami*/
     wlk_tab;             /*rzeczywista ilosc wczytanych elementow*/

 do {
 clrscr();
 arab = 0; biezaca = 0; poprzednia = 0; wlk_tab = 0;
 printf("Program zamienia liczby rzymskie na arabskie\n\n");
 printf("Podaj liczb w postaci cyfr rzymskich ");
 printf("..... : ");
 i = 0;
/*wczytywanie symboli, zamiana na duze litery, i zapis do tablicy jezeli podane znaki naleza do cyfr rzymskich*/
 do {
 znak = getch();
 if ((znak >= 97)&&(znak <= 122))
    znak -= delta;
 if ((znak == 'I')||(znak =='V')||(znak =='X')||(znak =='L')||(znak =='C')||(znak =='D')||(znak =='M')) {
       putchar(znak);
       rzymska[i] = znak;
       i += 1;
       wlk_tab = i;
      }
 } while ((znak != 13)&&(i < max));
 i = 0;
printf("\n\n w kolejnosci ");
 while (i < wlk_tab) {
   printf("%5d", konwersja(rzymska[i]));
   i++;
   }
i = wlk_tab;
 while (i) {
       biezaca = konwersja(rzymska[i-1]);
       if (poprzednia > biezaca)
          arab -= biezaca;
          else
            arab += biezaca;
       poprzednia = biezaca;
       i--;
       };
  printf("\n\n   Warto dziesitna wprowadzonej liczby to %d \n\n\n\n\n", arab);
  printf("Czy chcesz zakonczy program t/n ");
  znak = getch();
  } while ((znak !='t')&&(znak !='T'));

 return 0;
}

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

pootek 2006-04-04 15:56

Dziwne ze nikt tego nie zauwazyl:
piszac if(a==b==c) nie sprawdzasz czy wszystkie 3 są równe. Najpierw o ile się nie mylę wykonane zostanie porównanie b==c i zwrócona zostanie wartość true/false następnie poddana konwersji chyba na char(0/1) a więc nic z tego nie wyjdzie. Poprawny zapis to if(a==b && b==c).

jac_witkow 2005-08-23 12:30

 TamaszK, w if powinno byc (a==b==c)
A poza tym to masz absolutna racje

jac_witkow 2005-08-23 12:28

Masz zle skonstruowana petle for (powinno byc albo i<=23 albo i<23)

TamaszK 2005-08-17 12:52

A czy nikt nie uwzględnił że trzeba jeszcze sprawdzić czy przypadkiem liczba nie jest błędna?
Przecież nie może być IIII albo VVVVVVVV.

Trzeba użyć petli do tego programu. Przy każdym kolejnym obejsciu pętli sprawdzając czy rzymska[i] niejest równa rzymska[i-1] albo rzymska[i-2].

bool sprawdzacz(char a, char b, char c)
if(a == b == c)
{
return true;
}
else
{
return false;
}

}

A wyżej na końcu pętli:

sprawdzacz(rzymska[i],rzymska[i-1],rzymska[i-2])
If (sprawdzacz==true)
{
continue;
}
}

alonely 2005-05-23 17:20

jest też taki sposób. Wymyślony w nocy więc w sumie może dałoby się go jakoś przerobić.

  1. include<stdio.h>
  2. include<conio.h>
  3. include<string.h>
main()
{
   char ciag[20];
   int i,dlug,licz,k;
   licz=0;
   k=0;
   scanf("%s",&ciag);
   dlug=strlen(ciag);

      for(i=0;i<=dlug-1;i++)   {
   if(ciag[i]=='I')   {
   licz+=1;
   k=1;continue;
                      }
   if(ciag[i]=='V')   {
   if(k<=5) licz+=5-(2*k);
   else licz+=5;
   k=5;continue;
                      }
   if(ciag[i]=='X')   {
   if(k<10) licz+=10-(2*k);
   else licz+=10;
   k=10;continue;
                      }
   if(ciag[i]=='L')   {
   if(k<50) licz+=50-(2*k);
   else licz+=50;
   k=50;continue;
                      }
   if(ciag[i]=='C')   {
   if(k<100) licz+=100-(2*k);
   else licz+=100;
   k=100;continue;
                      }
   if(ciag[i]=='D')   {
   if(k<500) licz+=500-(2*k);
   else licz+=500;
   k=500;continue;
                      }
   if(ciag[i]=='M')   {
   if(k<1000) licz+=1000-(2*k);
   else licz+=1000;
   k=1000;continue;
                      }
                                 }
printf("%d",licz);
return 0;
}

Troche liczenia,ale mnie zmiennych;)
Taki sam miałem cel jak COOLTER z tym programikiem.Sposób jak sposób. Programik napisany po tygodniu znajomości C więc stąd ten haos.

pabloppp 2005-04-07 10:50

Tu trochę inna wersja (chyba troche bardziej spójna) tego samego programu, napisana w C:

  1. define N 100
  2. include <stdio.h>
  3. include <conio.h>

void rzym2arab(char[]);

const int I=1,V=5,X=10,L=50,C=100,D=500,M=1000;
int arab,tab[N];
char rzym[N];
 
int main()
{
    printf(\"Podaj liczbe rzymska\\n\");
    scanf(\"%s\",&rzym);
    rzym2arab(rzym);
    getch();
}

void rzym2arab(char rzym[])
{
    int dl=0;
    while (rzym[dl] != \'\\0\')
    {
          switch(rzym[dl])
          {
                case \'I\': {tab[dl] = I;break;}
                case \'V\': {tab[dl] = V;break;}
                case \'X\': {tab[dl] = X;break;}
                case \'L\': {tab[dl] = L;break;}
                case \'C\': {tab[dl] = C;break;}
                case \'D\': {tab[dl] = D;break;}
                case \'M\': {tab[dl] = M;break;}
                default : {printf(\"BLAD\\n\");break;}
          }    
          dl++;  
    }
    arab = tab[dl-1];
    while (dl != 1)
    {
          if (tab[dl-1] <= tab[dl-2])
             arab += tab[dl-2];
          else arab -= tab[dl-2];
          dl--;
    }
    printf(\"%d\\n\",arab);
}

yakhub 2005-03-07 12:32

A nie wygodniej byłoby użyć switch/case ?

COOLTER 2005-02-06 23:49

Program napisany na zadanie domowe dla kolegi, może komuś sięprzyda w podobnym celu.