Регистрация Войти
Войти через VK Войти через FB Войти через Google Войти через Яндекс
Войти через VK Войти через FB Войти через Google Войти через Яндекс
Поиск по сайту
Конвертирование арабских цифр в римские
Класс позволяющий конвертировать арабский цифры в римские.
/*************************************************************
* Arabic/Roman Numeral Convertor *
* *
* For converting between integers and Roman Numerals as well *
* as checking the validity of Roman Numerals. *
* *
* 1 I *
* 5 V 5,000 V *
* 10 X 10,000 X *
* 50 L 50,000 L *
* 100 C 100,000 C *
* 500 D 500,000 D *
* 1000 M 1,000,000 M *
* *
* Copyright (C) Dmitry Zarezenko, 2005 *
* E-mail : DIKGenius_php@rambler.ru *
*************************************************************/
class ArRoConvertor{
// Constructor
function __construct (){
}
/***********************************
* These first arrays are used by *
* the functions which convert *
* roman numerals into arabic. *
***********************************/
var $counter= Array();
var $romans = Array("I" => 1, "V" => 5, "X" => 10, "L" => 50, "C" => 100, "D" => 500, "M" => 1000, "" => 0);
var $subs = Array("I" => true, "X" => true, "C" => true, "M" => true);
/***********************************
* This first function is a pretty *
* simple and generic function used *
* to define and throw errors *
***********************************/
function createError($ErrorName, $ErrorMessage) {
$theError = new Error();
$theError->name = $ErrorName;
$theError->message = $ErrorMessage;
$theError->throw();
}
/***********************************
* These next four functions are *
* used to test for errors in the *
* input and convert roman numerals *
* into arabic integers. *
***********************************/
function checkRom($Rcur, $Rnext, $lSub, $n, $l) {
if (!isSet($this->romans[$Rcur]) || (!isSet($this->romans[$Rnext]) && (($n+1) < $l))) {
$this->createError("InputError", "Not a Roman Numeral");
}
else if ($this->romans[$Rcur] >= $lSub) {
$this->createError("InputError", "Not a Properly Formed Numeral");
}
}
function testSub($cR, $nR, $pR) {
if (isSet ($this->romans[$cR]) && isSet ($this->romans[$nR]) && isSet ($this->romans[$pR])){
if ($this->romans[$cR] < $this->romans[$nR]) {
if (($this->romans[$pR] == $this->romans[$nR]) && ($this->subs[$nR] != true)) {
$this->createError("InputError", "Not a Properly Formed Numeral");
}
else if (($this->subs[$cR] == true) && (10*$this->romans[$cR] >= $this->romans[$nR])) {
return true;
}
else {
$this->createError("InputError", "Not a Properly Formed Numeral");
return false;
}
}
}
return false;
}
function testRom($rome) {
if (!isSet ($this->counter[$rome])) return false;
if ($this->counter[$rome] < 3) {
return true;
}
else {
$this->createError("InputError", "Not a Properly Formed Numeral");
}
return false;
}
function RomanToArabic ($rNumb) {
$this->counter["I"] = 0;
$this->counter["V"] = 2;
$this->counter["X"] = 0;
$this->counter["L"] = 2;
$this->counter["C"] = 0;
$this->counter["D"] = 2;
$this->counter["M"] = -1000000000; // Negative infinity
$intNumb = 0;
$lastNumb = 1000000000; // Positive infinity
$thisNumb = 0;
$lastSub = 1000000000; // Positive infinity
$rNumb= strtoupper ($rNumb);
/*$tmpNumb= preg_replace ( "/[^IVXLCDM]/m", '', $rNumb);
if ($tmpNumb!= $rNumb) $this->createError("Warning", "$rNumb is not a Roman numeral, was changed on $tmpNumb");
$rNumb= $tmpNumb;*/
$len= strlen ($rNumb);
for ($i= 0; $i< $len; $i++){
$currentR = $rNumb[$i];
@$nextR = $rNumb[$i+1];
@$prevR = $rNumb[$i-1];
$this->checkRom ($currentR, $nextR, $lastSub, $i, $len);
if ($this->testSub ($currentR, $nextR, $prevR)) {
$thisNumb = $this->romans[$nextR] - $this->romans[$currentR];
$i ++;
$lastSub = $this->romans[$currentR];
}
else if ($this->testRom($currentR)){
$thisNumb = $this->romans[$currentR];
$this->counter[$currentR] ++;
}
if ($thisNumb > $lastNumb) {
$this->createError("InputError", "Not a Properly Formed Numeral");
}
else {
$intNumb += $thisNumb;
$lastNumb = $thisNumb;
}
}
return $intNumb;
}
/***********************************
* The next two functions are used *
* for converting an arabic integer *
* into a roman Numeral. *
***********************************/
function Cut($num, $n){
return ($num - ($num % $n ) ) / $n;
}
function ArabicToRoman ($aNumb) {
if (!is_int ($aNumb)){
$this->createError("InputError", "$aNumb is not a Arabic Integer");
return "";
}
$rNumb= "";
while ($aNumb> 5999) { $rNumb.= "M"; $aNumb-= 1000;}
if(($aNumb > 0)) {
$mill = Array("", "M", "MM", "MMM", "MMMM", "MMMMM");
$cent = Array("", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM");
$tens = Array("", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC");
$ones = Array("", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX");
$m = $this->Cut($aNumb, 1000); $aNumb%= 1000;
$c = $this->Cut($aNumb, 100); $aNumb%= 100;
$t = $this->Cut($aNumb, 10); $aNumb%= 10;
return $rNumb . $mill[$m] . $cent[$c] . $tens[$t] . $ones[$aNumb];
}
else {
$this->createError("InputError", "Numbers from 1 to 5999 only please.");
return "";
}
}
}
class Error{
var $name= "", $message= "";
function Error(){
}
function throw(){
print "<b>" . $this->name ." :</b> " . $this->message . "<br>\n";
}
}
$s = new ArRoConvertor();
print 'RomanToArabic: '.$str." = <b>" . $s->RomanToArabic($str) ."</b><br>\n";
print 'ArabicToRoman: '.$str." = <b>" . $s->ArabicToRoman( intval ($str)) ."</b><br>\n";
.
Прокомментировать/Отблагодарить