romanos programa para numeros naturales flujo diagrama decimales convertir arabigos algoritmo php arrays numbers roman-numerals

programa - Números para números romanos con php



diagrama de flujo para convertir numeros arabigos a romanos (6)

COMPROBADO Y VERIFICADO POR LA UNIDAD DE PHP

Cree una clase con el nombre RomanNumerials y agregue una propiedad estática protegida tal como se define:

protected static $lookup = [ 1000 => ''M'', 900 => ''CM'', 500 => ''D'', 400 => ''CD'', 100 => ''C'', 90 => ''XC'', 50 => ''L'', 40 => ''XL'', 10 => ''X'', 9 => ''IX'', 5 => ''V'', 4 => ''IV'', 1 => ''I'', ];

luego agrega un método de la siguiente manera

public function output ($number) { $solution = ''''; foreach(static::$lookup as $limit => $glyph){ while ($number >= $limit) { $solution .= $glyph; $number -= $limit; } } return $solution; }

Necesito transformar números ordinarios a números romanos con php y tengo este código:

<?php function roman2number($roman){ $conv = array( array("letter" => ''I'', "number" => 1), array("letter" => ''V'', "number" => 5), array("letter" => ''X'', "number" => 10), array("letter" => ''L'', "number" => 50), array("letter" => ''C'', "number" => 100), array("letter" => ''D'', "number" => 500), array("letter" => ''M'', "number" => 1000), array("letter" => 0, "number" => 0) ); $arabic = 0; $state = 0; $sidx = 0; $len = strlen($roman); while ($len >= 0) { $i = 0; $sidx = $len; while ($conv[$i][''number''] > 0) { if (strtoupper(@$roman[$sidx]) == $conv[$i][''letter'']) { if ($state > $conv[$i][''number'']) { $arabic -= $conv[$i][''number'']; } else { $arabic += $conv[$i][''number'']; $state = $conv[$i][''number'']; } } $i++; } $len--; } return($arabic); } function number2roman($num,$isUpper=true) { $n = intval($num); $res = ''''; /*** roman_numerals array ***/ $roman_numerals = array( ''M'' => 1000, ''CM'' => 900, ''D'' => 500, ''CD'' => 400, ''C'' => 100, ''XC'' => 90, ''L'' => 50, ''XL'' => 40, ''X'' => 10, ''IX'' => 9, ''V'' => 5, ''IV'' => 4, ''I'' => 1 ); foreach ($roman_numerals as $roman => $number) { /*** divide to get matches ***/ $matches = intval($n / $number); /*** assign the roman char * $matches ***/ $res .= str_repeat($roman, $matches); /*** substract from the number ***/ $n = $n % $number; } /*** return the res ***/ if($isUpper) return $res; else return strtolower($res); } /* TEST */ echo $s=number2roman(6,true); echo "/n and bacK:/n"; echo roman2number($s); ?>

prueba de esta manera pero no funciona:

echo $s=number2roman((.$row[''id''].),true); echo "/n and bacK:/n"; echo roman2number($s);

el problema es que necesito cambiar los números son lecturas de mi base de datos sql y no sé cómo hacerlo, desde y hasta.


Encontré este código aquí: http://php.net/manual/en/function.base-convert.php

Función optimizada y embellecida:

/** * @param int $number * @return string */ function numberToRomanRepresentation($number) { $map = array(''M'' => 1000, ''CM'' => 900, ''D'' => 500, ''CD'' => 400, ''C'' => 100, ''XC'' => 90, ''L'' => 50, ''XL'' => 40, ''X'' => 10, ''IX'' => 9, ''V'' => 5, ''IV'' => 4, ''I'' => 1); $returnValue = ''''; while ($number > 0) { foreach ($map as $roman => $int) { if($number >= $int) { $number -= $int; $returnValue .= $roman; break; } } } return $returnValue; }


Hay un problema de compensación ilegal.

Reemplazar

$o=1:$b].$s);

con

$o=1:$b >0 ? $b : 0].$s);


Mira mi solución aquí https://github.com/frostymarvelous/Whisppa-Libs/blob/master/Misc/Numeralo.php . Funciona en ambos sentidos.

<?php /** * @package Whisppa * @subpackage Misc * @license http://opensource.org/licenses/MIT MIT License * @author Stefan (frostymarvelous) Froelich <[email protected]> * @copyright Copyright (c) 2015, Stefan (frostymarvelous) Froelich */ namespace Whisppa/Misc; /** * This class allows you to convert from Roman numerals to natural numbers and vice versa. * I decided to do this as a fun challenge after reading http://thedailywtf.com/articles/Roman-Enumeration * Took me about 30 minutes to come up with, research and code the solution. * It can convert numbers up to 3,999,999 because I couldn''t find any numerals for 5,000,000 above. * Due to my inability to get the correct accented characters 5000 above, I resulted to using the pipe (|) to represent accent. */ class Numeralo { /** * @var string[] A notation map to represent the common Roman numeral values. * @static */ protected static $NOTATION = [ ''|'', //one ''['', //five '']'', //ten ]; /** * @var /ArrayObject[] A map of Roman numerals based on place value. Each item ends with the first numeral in the next place value. * @static */ protected static $NUMERALS_BY_PLACE_VALUE = [ [''I'', ''V'', ''X'',], //ones [''X'', ''L'', ''C'',], //tens [''C'', ''D'', ''M'',], // hundreds [''M'', ''V|'', ''X|'',], //thousands [''X|'', ''L|'', ''C|'',], //tens of thousands [''C|'', ''D|'', ''M|'',], //hundreds of thousands [''M|'', ''~'', ''~'',], // millions. there are no values for the last two that I could find ]; /** * @var string[] sA map of numbers and their representative Roman numerals in notation format. This map allows us to make any numeral by replacing the the notation with the place value equivalent. * @static */ protected static $NUMBER_TO_NOTATION = [ ''0'' => '''', ''1'' => ''|'', ''2'' => ''||'', ''3'' => ''|||'', ''4'' => ''|['', ''5'' => ''['', ''6'' => ''[|'', ''7'' => ''[||'', ''8'' => ''[|||'', ''9'' => ''|]'', ]; /** * @var int[] A map of the major Roman numerals and the number equivalent. * @static */ protected static $NUMERALS_TO_NUMBER = [ ''I'' => 1, ''V'' => 5, ''X'' => 10, ''L'' => 50, ''C'' => 100, ''D'' => 500, ''M'' => 1000, ''V|'' => 5000, ''X|'' => 10000, ''L|'' => 50000, ''C|'' => 100000, ''D|'' => 500000, ''M|'' => 1000000, ]; /** * Converts natural numbers to Roman numerals. * * @static * @param int|string $number a number or numeric string less than 3,999,999 * @throws /InvalidArgumentException if the provided $number argument is not numeric or greater than 3,999,999. * @return string Roman numeral equivalent */ public static function number_to_numerals($number) { if(!is_numeric($number)) throw new /InvalidArgumentException(''Only numbers allowed''); if($number > 3999999) throw new /InvalidArgumentException(''Number cannot be greater than 3,999,999''); $numerals = ''''; $number_string = strrev((string) $number); $length = strlen($number_string); for($i = 0; $i < $length; $i++) { $char = $number_string[$i]; $num_map = self::$NUMERALS_BY_PLACE_VALUE[$i]; $numerals = str_replace(self::$NOTATION, $num_map, self::$NUMBER_TO_NOTATION[$char]) . $numerals; } return $numerals; } /** * Converts Roman numerals to natural numbers. * * @static * @param string $numerals the Roman numerals to be converted * @throws /InvalidArgumentException if the provided $numerals argument contains invalid characters. * @return int the equivalent number */ public static function numerals_to_number($numerals) { $number = 0; $numeral_string = strrev((string) $numerals); $length = strlen($numeral_string); $prev_number = false; $is_accented = false; for($i = 0; $i < $length; $i++) { $char = $numeral_string[$i]; if($char == ''|'') //check if it is an accent character { $is_accented = true; continue;//skip this iteration and process it in the next one as the accent applies to the next char } else if($is_accented) { $char .= ''|''; $is_accented = false; } //TODO Make a check using maybe regex at the beginning of the method. if(!isset(self::$NUMERALS_TO_NUMBER[$char])) throw new /InvalidArgumentException("Invalid character ''{$char}'' in numeral string"); $num = self::$NUMERALS_TO_NUMBER[$char]; //this is where the magic happens //if the previous number divided by 5 or 10 is equal to the current number, then we subtract eg. 9 = IX. I = 1, X = 10, 10/10 = 1 if($prev_number) { if(($prev_number / 5) == $num || ($prev_number / 10) == $num) $number -= $num; else $number += $num; } else $number += $num; $prev_number = $num; } return $number; } }


Otra forma de hacerlo

<?php function ConverToRoman($num){ $n = intval($num); $res = ''''; //array of roman numbers $romanNumber_Array = array( ''M'' => 1000, ''CM'' => 900, ''D'' => 500, ''CD'' => 400, ''C'' => 100, ''XC'' => 90, ''L'' => 50, ''XL'' => 40, ''X'' => 10, ''IX'' => 9, ''V'' => 5, ''IV'' => 4, ''I'' => 1); foreach ($romanNumber_Array as $roman => $number){ //divide to get matches $matches = intval($n / $number); //assign the roman char * $matches $res .= str_repeat($roman, $matches); //substract from the number $n = $n % $number; } // return the result return $res; } echo ConverToRoman(23); ?>


function rome($N){ $c=''IVXLCDM''; for($a=5,$b=$s='''';$N;$b++,$a^=7) for($o=$N%$a,$N=$N/$a^0;$o--;$s=$c[$o>2?$b+$N-($N&=-2)+$o=1:$b].$s); return $s; } // from polish wiki