---
# System prepended metadata

title: a013.羅馬數字
tags: [程式題目]

---

# a013.羅馬數字題解
![螢幕擷取畫面 2024-08-21 133754](https://hackmd.io/_uploads/ByhSVMEsA.png)
> [name=資訊甲_24陳奕寬]
---

# 解題思路
題目目標是做出羅馬數字的加減，主要會分成2個部分
#### 1. 羅馬數字轉阿拉伯數字-
使用2個陣列做對照表
將輸入的羅馬數字陣列轉成阿拉伯數字
在依照羅馬數字的規則計算出答案
```csvpreview=
    char a[7]={'I','V','X','L','C','D','M'}
    int b[7]={1,5,10,50,100,500,1000};
```
#### 2. 阿拉伯數字轉羅馬數字-
我的作法是先把數字分成各個不同的位數
例如:1998->1000、900、90、8
接著判斷數字的位數確定好輸出的羅馬數字
在依照不同的規則輸出
像是1〜3、6〜8、4、5、9有自己的特性
![螢幕擷取畫面 2024-08-22 103253](https://hackmd.io/_uploads/HyZGNQNj0.png)
# 程式碼
```clike=
#include<iostream>
#include<string>
#include<string.h>
using namespace std;
int rom_num(string c){
    char a[7]={'I','V','X','L','C','D','M'};
    int b[7]={1,5,10,50,100,500,1000};
    int num;
        int x[50];
        int n=c.length()-1;//陣列大小
        //得阿拉伯數字
        for(int i=0;i<c.length();i++){
            for(int j=0;j<7;j++){
                if (c[i]==a[j]){x[i]=b[j];}//羅馬數字數值存到陣列
            }
        }
        //羅馬數字規則加減
        for(int i=c.length()-1;i>=0;i--){//後
            int j=i-1;//前
            if(x[i]>x[j]){
                x[i]=x[i]-x[j];
                x[j]=0;
                i-=1;
                j-=1;
            }j-=1;
        }
        num=x[0];
        for(int i=1;i<c.length();i++){
            num+=x[i];
        }
        return num;
}
string ara_num(int n){
    char a[7]={'I','V','X','L','C','D','M'};
    string rome;//羅馬數字
    int fre=0;
    int num;//阿拉伯數字
    num=n;
    while(n != 0){        
            n/=10;
            fre++;  
    }
    for(int i=fre-1;i>=0;i--){
        int div=1;//位數
        int dig;//數字
        int f;//羅馬數字陣列位置1-3
        int j;//羅馬數字陣列位置6-8
        int k;//rome位置
        int l;//9
        for(int j=i;j>0;j--){
                div*=10;
        }
        dig=(num/div)*div;
        num-=(num/div)*div;
        switch(i){
                case 3:
                    f=6;break;
                case 2:
                    f=4;j=5;l=6;break;
                case 1:
                    f=2;j=3;l=4;break;
                case 0:
                    f=0;j=1;l=2;break;
        }  
        switch(dig/div){
                case 1:case 2:case 3:
                    for(int i=0;i<dig/div;i++){
                        rome+=a[f];
                    }
                    break;
                case 4:
                    rome=rome+a[f]+a[j];
                    break;
                case 5:
                    rome+=a[j];
                    break;
                case 6:case 7:case 8:
                    rome+=a[j];
                    for(int i=0;i<dig/div-5;i++){                       
                        rome+=a[f];
                    }
                    break;
                case 9:
                    rome=rome+a[f]+a[l];     
        }
    }
    return rome;
}
int main(){
    while(1){
        string n,m;
        cin>>n;
        if(n=="#"){break;}
        cin>>m;
        int ans=abs(rom_num(n)-rom_num(m));
        if(ans==0){
            cout<<"ZERO"<<endl;
        }
        else{
            cout<<ara_num(ans)<<endl;
        }
    }
    return 0;
}
```
# 特殊用法
### 1. 字串加減
```clike=
#include<iostream>
#include<string>
using namespace std;
int main(){
    string rome;
    int i=1;
    while(1){
        char a;
        cin>>a;
        rome+=a;
        cout<<i<<"."<<rome<<endl;
        i++;
    }
    return 0;
}
```
![螢幕擷取畫面 2024-08-22 110333](https://hackmd.io/_uploads/r1h597EoC.png)


### 2. 絕對值
<font color="#f00">**測資的時候一直WA，找了很多問題，最後發現就是沒有加上絕對值**</font>
絕對值_abs()
```clike=
int main(){
    while(1){
        string n,m;
        cin>>n;
        if(n=="#"){break;}
        cin>>m;
        int ans=abs(rom_num(n)-rom_num(m));
        if(ans==0){
            cout<<"ZERO"<<endl;
        }
        else{
            cout<<ara_num(ans)<<endl;
        }
    }
    return 0;
}
```



