今、気づきました。
アラビア数字から、ローマ数字へ変換できるだけでは、間が、抜けているということを、です。
その逆が出来なければ、あほ。
従って、その逆を行うために、ローマ数字からアラビア数字へ変換してやる方法を、考えなくてはなりません。
で、東北本線(高崎線かも)の電車の中で考えました。
基本的には、次のようになると思います。
ただ、例外があります。
こんなところでしょうか。
上記の要求にしたがって記述したら、このようになりました。
見れば分かりますが、言語はCです。
かなり汚いソースですし、洗練されていないロジックなので恥ずかしいのですが、あくまでもサンプルですので。
で、 Java に移植したソースが、こちらにあります。
Java 版は、 main関数もつけといたので、コンパイルすればそのまま実行できます。
Java なので、当然ながら、javaが必要です。
Sun からダウンロードするなりして、適当に入手して下さいませ。
で、これを、この前作ったアラビア数字→ローマ数字自動変換モジュールとくみあわせてやれば、自動判別機能付きの相互変換も出来る事になります。
ちなみに、これのGUIの実行モジュールは、めんどくさいので端折りました。
相互変換モジュールのほうは作るつもりなので、そちらを見て下さいませ。
<↑>
------ここから-----
#include <stdio.h> #include <ctype.h> #include <string.h> #define null NULL /* (c)1999 A.Matsuda arabic.c */ struct{ int c; int v; }tbl[] = { { 'm', 1000 }, { 'd', 500 }, { 'c', 100 }, { 'l', 50 }, { 'x', 10 }, { 'v', 5 }, { 'i', 1 }, { -1 , -1 }, }; int chkv( int c ) { int i; for( i = 0 ; ; i++ ){ if( tbl[i].c == -1 ){ break; } if( toupper(tbl[i].c) == toupper(c) ){ return 1; } } return 0; } int getv( int c ) { int i; for( i = 0 ; ; i++ ){ if( tbl[i].c == -1 ){ break; } if( toupper(c) == toupper(tbl[i].c) ){ return tbl[i].v; } } return -1; } int arabic( char* buf , int* val ) { int prev = 0; int current = 0; int i; int cnt = 0; if( buf == null || val == null ){ return 1; } *val = 0; for( i = 0 ; i < strlen( buf ) ; i ++ ){ if( chkv(buf[i]) ){ current = getv( buf[i] ); if( prev == current){ cnt++; } else{ if( prev < current && cnt >= 1 ){ /* 2回以上引かれる数より小さな数が続いた後に減算を行う事はない */ return -2; } cnt = 0; } if( current > prev && prev != 0 ){ if( prev*5 != current && prev*10 != current ){ return -2; } if( prev == 5 || prev == 50 || prev == 500 ){ return -2; } *val -= prev*2; *val += current; prev = current - prev; } else{ /* 一度減算をおこなったら、currentよりも小さな値であるべき */ if( prev != 0 && (( (prev%9) == 0 ) && (prev/9) <= current) ) { return -2; } if( prev != 0 && ( prev == 4 || prev == 40 || prev == 400 ) && ( ( prev / 4 ) <= current ) ){ return -2; } if( ( prev == 5 || prev == 50 || prev == 500 ) && (cnt >= 1 ) ){ return -2; } *val += current; prev = current; } } else{ return -3; } } return 0; }
------ここまで-----
ソースプログラムのダウンロードはこちらをクリックして下さい。
<↑>
つかいかた
つかいかたのごせつめい。
関数のつかいかたのごせつめい。
書式
引数
戻値 int
<↑>
ご注意
<↑>
------ここから-----
/* arabic.java (c)1999 A.Matsuda */ import java.awt.*; import java.awt.event.*; import java.awt.Toolkit.*; import java.applet.*; import java.util.*; import java.lang.*; import java.text.*; import java.lang.System.*; public class arabic { static final char delimiter = (char)-1; class elem{ char c; int v; public elem(char c, int v){ this.c = c; this.v = v; } public char getChar() { return c; } public int getVal() { return v; } }; elem tbl[]={ new arabic.elem( 'm', 1000 ), new elem( 'd', 500 ), new elem( 'c', 100 ), new elem( 'l', 50 ), new elem( 'x', 10 ), new elem( 'v', 5 ), new elem( 'i', 1 ), new elem( delimiter , -1 ), }; boolean chkv( char c ) { int i; for( i = 0 ; ; i++ ){ if( tbl[i].getChar() == delimiter ){ break; } if( tbl[i].getChar() == c ){ return true; } } return false; } int getv( char c ) { int i; for( i = 0 ; ; i++ ){ if( tbl[i].getChar() == (char)-1 ){ break; } if( c == tbl[i].getChar() ){ return tbl[i].getVal(); } } return -1; } int arabic( String buf ) throws Exception { int prev = 0; int current = 0; int i; int val = 0; int cnt = 0; buf.trim(); buf = buf.toLowerCase(); for( i = 0 ; i < buf.length() ; i ++ ){ if( chkv( buf.charAt( i ) ) == true ){ current = getv( buf.charAt( i ) ); if( prev == current){ cnt++; } else{ if( prev < current && cnt >= 1 ){ //2回以上引かれる数より小さな数が続いた後に減算を行う事はない throw new Exception("書式が不正です"); } cnt = 0; } if( current > prev && prev != 0 ){ if( prev * 5 != current && prev * 10 != current ){ throw new Exception("書式が不正です"); } if( prev == 5 || prev == 50 || prev == 500 ){ throw new Exception("書式が不正です"); } val -= prev * 2; val += current; prev = current - prev; } else{ //一度減算をおこなったら、currentよりも小さな値であるべき if( prev != 0 && ( ( ( prev % 9 ) == 0 ) && ( ( prev / 9 ) <= current) ) ) { throw new Exception("書式が不正です"); } if( prev != 0 && ( prev == 4 || prev == 40 || prev == 400 ) && ( (prev / 4) <= current ) ){ //減算が行われた直後に同じ桁の数は並ばない。 throw new Exception("書式が不正です"); } if( ( prev == 5 || prev == 50 || prev == 500 ) && (cnt >= 1 ) ){ throw new Exception("書式が不正です"); } val += current; prev = current; } } else{ throw new Exception("不正な文字が含まれています"); } } return val; } public static void main( String arg[] ) { int i; int val; arabic arabic = new arabic(); for( i = 0 ; i < arg.length ; i++ ){ try{ val = arabic.arabic( arg[ i ] ); } catch( Exception e ){ System.out.println( e.getMessage() ); continue; } System.out.println( arg[i] + "-->" + new Integer(val).toString() ); } }; };
------ここまで-----
ソースプログラムのダウンロードはこちらをクリックして下さい。
<↑>
つかいかた
つかいかたのごせつめい。
引数のあたえかた
クラスの使い方のご説明。
class arabic:
int arabic( String buf ) throws Exception
引数
戻値 int
付記
<↑>
ご注意
<↑>
<ホームページへ> <ローマ数字変換へ> <ローマ数字→アラビア数字自動変換へ> <アラビア数字←→ローマ数字相互自動変換へ>
Copyright © MCMXCIX Ayumi Matsuda All rights reserved.