User Tools

Site Tools


php:kompost:romannumbers

[PHP] RomanNumbers

Umwandeln von Dezimalzahlen in römische und umgekehrt

RomanNumbers
<?php 
/**
* mpl           by ERB software
* @author       stefan.erb(at)erb-software.com
* @since        PHP 5.2
*/
 
/**
 * @example
 * echo $r = RomanNumbers::getRomanNumber(1945);
 * echo "<br />";
 * echo RomanNumbers::getDecimalNumber($r);
 */
class RomanNumbers{
	/**
	 * Pro level (10er-Potenz) die einzelnen Zeichen
	 */
	protected static $romanDigits = array(
		0 => array(1=> 'I', 5=> 'V', 10 => 'X'),
		1 => array(1=> 'X', 5=> 'L', 10 => 'C'),
		2 => array(1=> 'C', 5=> 'D', 10 => 'M'),
		3 => array(1=> 'M', 5=> 'I&#x186;', 10 => '&#x3F9;I&#x3FD;'),
		4 => array(1=> '&#x3F9;I&#x3FD;', 5=> 'I&#x3FD;&#x3FD;', 10 => '&#x3F9;&#x3F9;I&#x3FD;&#x3FD;')
	);
	/**
	 * Pro Zahl (0-9) die zusammenstellung, welche Zeichen alles verwednet werden 
	 */    
	protected static $formula = array(
		0 => array(),
		1 => array(1),
		2 => array(1,1),
		3 => array(1,1,1),
		4 => array(1,5),
		5 => array(5),
		6 => array(5,1),
		7 => array(5,1,1),
		8 => array(5,1,1,1),
		9 => array(1,10)
	);
 
	/**
	 * Wandelt römische Zahl in eine eine Ganzzahl um
	 * Ist eine einfache, aber nicht umbedingt die schnellste Variante
	 * @param  $romanNumber String      römische Zahl
	 * @param  $error       String      Fehlermeldung
	 * @return              Integer     arabische Zahl
	 */
	public static function getDecimalNumber($romanNumber, &$error = false){
		//Für alle Zahlen zwieschen 0 und 99'999 die römische Zahl ermitteln
		//und mit der Eingabe vergleichen. Bei Übereinstimmung die Zahl zurückgeben
		for($i = 0; $i < 100000; $i++){
			if($romanNumber == self::getRomanNumber($i)){
				return $i;
			}
		}
		$error = "keine Nummer für {$romanNumber} gefunden";
		return -1;
	}
 
	/**
	 * Wandelt eine Ganzzahl in eine römische Zahl um
	 * @param $number   Integer     arabische Zahl
	 * @return          String      römische Zahl
	 */
	public static function getRomanNumber($number){
		//Nummer in seine Einzelteile zerlegen und umgekehrt indexieren
		//So ist der Index analog dem Level (10er-Potenz) der Ziffer 
		$numbers = array_reverse(str_split($number));
		foreach($numbers as $level => $digit){
			//Für jede Ziffer die römische Nummer ermitteln. Dazu werden die
			//romanDigits anhand der Auflistung zur Ziffer und dem Level aus
			//den 2 statischen Arrays zusammengesetzt.
			$romanDigit='';
			foreach(self::$formula[$digit] as $num){
				$romanDigit .=self::$romanDigits[$level][$num];
			}
			$romanNumber = $romanDigit.$romanNumber;      
		}
		return $romanNumber;    
	}
}
?>
php/kompost/romannumbers.txt · Last modified: 11.12.2013 11:54:10 (external edit)