發新話題

[教學]羅馬數字與阿拉伯數字的轉換

[教學]羅馬數字與阿拉伯數字的轉換

複製內容到剪貼板
代碼:
#include <stdio.h>
#include <stdlib.h>

int ValidNum(char);                //Check the word of Input.
int TransNum(char*);        //Transfer the Numbers.

int main(void)
{
        int No1=0, No2=0, No3, i, j, k;
        char IOput[1024], Num1[512], Num2[512], op;

        printf("Enter Your Operation: ");
        gets(IOput);

        /*  Remove Space ' '.  */
        for(i=0; IOput[i]; ++i)
        {
                if(IOput[i] == ' ')
                {        
                        for(j=i; IOput[j]; ++j)        IOput[j] = IOput[j+1];
                        IOput[j] = IOput[j+1];
                        --i;
                }
        }

        /*  Pick the 1st Number.  */
        for(i=0; ValidNum(IOput[i]); ++i)        Num1[i] = IOput[i];
        Num1[i] = '\0';

        /*  Pick Operation.  */
        op = IOput[i];
        ++i;
        
        /*  Pick the 2nd Number.  */
        for(j=0; ValidNum(IOput[i]); ++i, ++j)        Num2[j] = IOput[i];
        Num2[j] = '\0';
        
        /*  Transfer the Numbers.  */
        No1 = TransNum(Num1);
        No2 = TransNum(Num2);

        /*  Do the Operation.  */
        switch(op)
        {
                case '+':
                        No3 = No1 + No2;
                        break;

                case '-':
                        No3 = No1 - No2;
                        break;

                case '*':
                        No3 = No1 * No2;
                        break;

                case '/':
                        No3 = No1 / No2;
                        break;
               
                default:
                        if(Num1[0] == '\0')        printf("O(0)\n");
                        else        printf("%s(%d)\n", Num1, No1);

                        system("PAUSE");
                        return 0;
        }

        /*  Process Output String.  */
        if(No3 == 0)
        {
                IOput[0] = 'O';
                IOput[1] = '\0';
        }
        else
        {
                i = 0;
                k = No3;

                if((j = k / 1000) > 0)
                {
                        for(; j>0; --j, ++i)        IOput[i] = 'M';
                        k %= 1000;
                }
                if((j = k / 500) > 0)
                {
                        for(; j>0; --j, ++i)        IOput[i] = 'D';
                        k %= 500;
                }
                if((j = k / 100) > 0)
                {
                        for(; j>0; --j, ++i)        IOput[i] = 'C';
                        k %= 100;
                }
                if((j = k / 50) > 0)
                {
                        for(; j>0; --j, ++i)        IOput[i] = 'L';
                        k %= 50;
                }
                if((j = k / 10) > 0)
                {
                        for(; j>0; --j, ++i)        IOput[i] = 'X';
                        k %= 10;
                }
                if((j = k / 5) > 0)
                {
                        for(; j>0; --j, ++i)        IOput[i] = 'V';
                        k %= 5;
                }
                for(; k>0; --k, ++i)        IOput[i] = 'I';

                IOput[i] = '\0';
        }

        printf("%s(%d) %c %s(%d) = %s(%d)\n", Num1, No1, op, Num2, No2, IOput, No3);
               
        system("PAUSE");
        return 0;
}
//------------------------------------------------------------------------------

int ValidNum(char word)
{
        switch(word)
        {
                case 'O':
                case 'I':
                case 'V':
                case 'X':
                case 'L':
                case 'C':
                case 'D':
                case 'M':
                        return 1;
        }

        return 0;
}
//------------------------------------------------------------------------------

int TransNum(char *Num)
{
        int No=0, i;

        for(i=0; Num[i]; ++i)
        {
                switch(Num[i])
                {
                        case 'O':
                                No += 0;
                                break;

                        case 'I':
                                No += 1;
                                break;

                        case 'V':
                                No += 5;
                                break;

                        case 'X':
                                No += 10;
                                break;

                        case 'L':
                                No += 50;
                                break;

                        case 'C':
                                No += 100;
                                break;

                        case 'D':
                                No += 500;
                                break;

                        case 'M':
                                No += 1000;
                                break;
                }
        }

        return No;
}
//------------------------------------------------------------------------------
C++怎麼做....
複製內容到剪貼板
代碼:
#include <stdlib.h>
#include <iostream>

using namespace std;
//---------------------------------------------------------------------------

class Roma
{
        private:
                int Number;
                string Str;

        public:
                Roma(int Input=0) : Number(Input)         {        Str = NumToStr(Input);        }
                Roma(char *Input) : Str(Input)                  {        Number = StrToNum(Str);        }
                Roma(string Input) : Str(Input)                  {        Number = StrToNum(Str);        }
                Roma(const Roma &Input) : Number(Input.Number), Str(Input.Str)        {}
                virtual ~Roma()        {}

                Roma operator +(const Roma &Operand)        {        return Roma(Number + Operand.Number);        }
                Roma operator -(const Roma &Operand)        {        return Roma(Number - Operand.Number);        }
                Roma operator *(const Roma &Operand)        {        return Roma(Number * Operand.Number);        }
                Roma operator /(const Roma &Operand)        {        return Roma(Number / Operand.Number);        }
                Roma& operator =(const Roma &Operand);

                int StrToNum(void)                {        return Number;        }
                int StrToNum(string&);
                string NumToStr(void)        {        return Str;                }
                string NumToStr(int);

                friend istream& operator >>(istream &in_data, Roma &roma);
                friend ostream& operator <<(ostream &out_data, const Roma &roma)
                {        return out_data << roma.Str << '(' << roma.Number << ')';        }
};
//---------------------------------------------------------------------------

int main(void)
{
        char op, buffer[1024];
        int pos, i, j;
        string Input;
        Roma Num1, Num2;

        cout << "Enter Your Operation:" << ends;
        cin >> ws;
        cin.getline(buffer, 1024);

        /*  Remove Space ' '.  */
        for(i=0; buffer[i]; ++i)
        {
                if(buffer[i] == ' ')
                {
                        for(j=i; buffer[j]; ++j)        buffer[j] = buffer[j+1];
                        buffer[j] = buffer[j+1];
                        --i;
                }
        }
        Input = buffer;

        /*  Devide 2 Numbers.  */
        pos = Input.find_first_of("+-*/", 0);
        if(pos == -1)
        {
                Num1 = Input;
                cout << Num1 << endl;
                system("PAUSE");
                return 0;
        }

        /*  Pick the Operation.  */
        op = Input.at(pos);

        /*  Pick the 2 Numbers.  */
        Num1 = Input.substr(0, pos);
        Num2 = Input.substr(pos+1);

        /*  Do the Operation.  */
        switch(op)
        {
                case '+':
                        cout<<Num1<<' '<<op<<' '<<Num2<<" = "<<Num1+Num2<<endl;
                        break;

                case '-':
                        cout<<Num1<<' '<<op<<' '<<Num2<<" = "<<Num1-Num2<<endl;
                        break;

                case '*':
                        cout<<Num1<<' '<<op<<' '<<Num2<<" = "<<Num1*Num2<<endl;
                        break;

                case '/':
                        cout<<Num1<<' '<<op<<' '<<Num2<<" = "<<Num1/Num2<<endl;
                        break;
        }

        system("PAUSE");
        return 0;
}
//---------------------------------------------------------------------------

Roma& Roma::operator =(const Roma &Operand)
{
        Number = Operand.Number;
        Str = Operand.Str;
        return *this;
}
//---------------------------------------------------------------------------

int Roma::StrToNum(string &str)
{
        int No=0, i;

        for(i=0; (unsigned)i<str.length(); ++i)
        {
                switch(str[i])
                {
                        case 'O':
                                No += 0;
                                break;

                        case 'I':
                                No += 1;
                                break;

                        case 'V':
                                No += 5;
                                break;

                        case 'X':
                                No += 10;
                                break;

                        case 'L':
                                No += 50;
                                break;

                        case 'C':
                                No += 100;
                                break;

                        case 'D':
                                No += 500;
                                break;

                        case 'M':
                                No += 1000;
                                break;

                        default:
                                str = str.substr(0, i);
                }
        }

        if(str == "")        str = "O";
        return No;
}
//---------------------------------------------------------------------------

string Roma::NumToStr(int No)
{
        if(No == 0)        return string("O");
        else
        {
                int i=0, j, k=No;
                string str = "";

                if((j = k / 1000) > 0)
                {
                        for(; j>0; --j, ++i)        str += 'M';
                        k %= 1000;
                }
                if((j = k / 500) > 0)
                {
                        for(; j>0; --j, ++i)        str += 'D';
                        k %= 500;
                }
                if((j = k / 100) > 0)
                {
                        for(; j>0; --j, ++i)        str += 'C';
                        k %= 100;
                }
                if((j = k / 50) > 0)
                {
                        for(; j>0; --j, ++i)        str += 'L';
                        k %= 50;
                }
                if((j = k / 10) > 0)
                {
                        for(; j>0; --j, ++i)        str += 'X';
                        k %= 10;
                }
                if((j = k / 5) > 0)
                {
                        for(; j>0; --j, ++i)        str += 'V';
                        k %= 5;
                }
                for(; k>0; --k, ++i)        str += 'I';

                return str;
        }
}
//---------------------------------------------------------------------------

istream& operator >>(istream &in_data, Roma &roma)
{
        string temp;
        in_data >> temp;
        roma = temp;
        return in_data;
}
//---------------------------------------------------------------------------
下面是羅馬數字轉int,沒有作規則檢查,不過要加也不難
輸入正確的羅馬數字,可以得到正確的數值
至於阿拉伯轉羅馬,查表比較快(大部分的情況下如果能靠查表解決,就不要硬算)
複製內容到剪貼板
代碼:
#include <cstdlib>
#include <iostream>
#include <cstring>

using namespace std;

int GetDigitValue(char d)
{
   switch (d)
   {
      case 'M': return 1000;
      case 'D': return 500;
      case 'C': return 100;
      case 'L': return 50;
      case 'X': return 10;
      case 'V': return 5;
      case 'I': return 1;
      //default: we can throw exception here...
   }
   return 0;
}

int GetRightNum(int* num, int length)
{
   if (length == 1) return *num;
   else if (length == 0) return 0;
   else if (num[1] > num[0])
      //it's easy to do rule check and throw exception here...
      //but it's too late now and i'm going to bed -.-
      return num[1]- num[0] + GetRightNum(num + 2, length - 2);
   else return num[0] + GetRightNum(num + 1, length - 1);
}

int RomanToArabic(const char* roman)
{
   int length = strlen(roman), re;
   int* num = new int[length];
   // try and catch here
   for (int i = 0; i < length; i++)
      num[i] = GetDigitValue(roman[i]);
   re = GetRightNum(num, length);
   delete[] num;
   return re;
}

int main()
{
   cout << RomanToArabic("XLIV")    << endl;
   cout << RomanToArabic("CMXLII")  << endl;
   cout << RomanToArabic("IL")      << endl;
   cout << RomanToArabic("MCM")     << endl;
   cout << RomanToArabic("MCMXCVI") << endl;
   system("PAUSE");
}
ArabicToRoman() 的部份若是採用string可以用替換的方式將4,9,40,90,400,900的字串替換掉,也是可以的
複製內容到剪貼板
代碼:
#include <iostream>

using namespace std;

char* ArabicToRoman(int ArabicNum,char* RomanString){
  int nArray[8]={1000,500,100,50,10,5,1,0};
  char chArray[7]={'M','D','C','L','X','V','I'};
  int nTemp=ArabicNum;
  char* pStr=RomanString;
  int nPtr=0;
  
  if(nTemp==0)
    *pStr++='O';   
  
  while(nTemp){
    if(nTemp<nArray[nPtr])
      ++nPtr;
    else{
      nTemp-=nArray[nPtr];
      *pStr++=chArray[nPtr];
    }        
  }
  *pStr='\0';
  
  return RomanString;
}

int RomanToArabic(char* RomanString){
  int nTemp;
  if(*RomanString=='\0')
    return 0;
  switch (*RomanString){
    case 'M':
      nTemp=1000;
      break;
    case 'D':
      nTemp=500;
      break;
    case 'C':
      nTemp=100;
      break;
    case 'L':
      nTemp=50;
      break;
    case 'X':
      nTemp=10;
      break;
    case 'V':
      nTemp=5;
      break;
    case 'I':
      nTemp=1;
      break;
    case 'O':
      nTemp=0;
      break;
   }
   return nTemp+=RomanToArabic(RomanString+1);
}

int main(void){
  char s[255];
  
  cout<<ArabicToRoman(1996,s)<<endl;
   
  cout<<RomanToArabic("MDCCCCLXXXXVI")<<endl;
  system("PAUSE");
}
下面這篇是數字轉羅馬數字
複製內容到剪貼板
代碼:
/*
分成百位,十位,個位來處理.

個位(1-9): I, II, III, IV, V, VI, VII, VIII, IX (0為空字串)
十位(1-9): X, XX, XXX, XL, L, LX, LXX, LXXX, XC (0為空字串)
百位(1-9): C, CC, CCC, CD, D, DC, DCC, DCCC, CM (0為空字串)

按各位數得到的字串組合在一起便是羅馬數字字串
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

char* sUnidigit[]={"","I","II","III","IV","V","VI","VII","VIII","IX"};
char* sTen[]={"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};
char* sCentum[]={"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};
  
char* arabia_roman(char* sDest,int nArabia){
   sDest[0]='\0';   
  (nArabia>99)&&strcat(sDest,sCentum[nArabia/100])&&(nArabia%=100);
  (nArabia>9)&&strcat(sDest,sTen[nArabia/10])&&(nArabia%=10);
  (nArabia>0)&&strcat(sDest,sUnidigit[nArabia]);  
  return sDest;   
}

int main(){
  char str[256];
  int i,j;
  for(i=1;i<=100;i++){
    if(i%5==0)
      printf("%3d=%8s\n",i,arabia_roman(str,i));
    else
      printf("%3d=%8s",i,arabia_roman(str,i));
  }   
  system("pause");
}
[ 本帖最後由 philxyz0316 於 2006-8-27 13:06 編輯 ]

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。