Delphi 将整数转换为罗马数字


本文整理自网络,侵删。

 
//数字转换罗马
function ToRoman(const iArabic: Integer): String;
const // S5 は 5 * 10^n を表すシンボル, S1 は 1 * 10^n を表すシンボル
  ROMAN_SYMBOLS: array [-1.. 3] of record S5, S1: Char end = (
    (S5: ' '; S1: ' '), // ??欹隶Д氓?を横着するためのダミ?`
    (S5: ' '; S1: 'M'),
    (S5: 'D'; S1: 'C'),
    (S5: 'L'; S1: 'X'),
    (S5: 'V'; S1: 'I')
  );
begin
  if (iArabic > 3999) or (iArabic < 1) then
    Exit('');

  var V := Int32(iArabic).ToString;
  V := (StringOfChar('0', 4) + V).SubString(V.Length, 4); // 必ず4文字の文字列にする

  var SB := TStringBuilder.Create;
  try
    for var i := 0 to 3 do //
    begin
      var C := ROMAN_SYMBOLS[i];
      var P := ROMAN_SYMBOLS[i - 1]; // 

      var N := StrToIntDef(V.Chars[i], 0);
      var F := N > 4;
      var R := N mod 5;

      if (R = 4) then // ??余が 4 か?
      begin
        SB.Append(C.S1);
        SB.Append(IfThen(F, P.S1, C.S5))
      end
      else
      begin
        if F then
          SB.Append(C.S5);
        SB.Append(C.S1, R);
      end;
    end;

    Result := SB.ToString;
  finally
    SB.DisposeOf;
  end;
end;

?Y果
   0:
  12: XII
  24: XXIV
  42: XLII
  49: XLIX
  89: LXXXIX
 299: CCXCIX
 493: CDXCIII
1960: MCMLX
3999: MMMCMXCIX






//罗马转换数字
function ToAlabic(const iRomanNum: String): Integer;
const
  ROMANS: array [-1.. 6] of record Number: Integer; Symbol: Char; end = (
    (Number:    0; Symbol: ' '),
    (Number: 1000; Symbol: 'M'),
    (Number:  500; Symbol: 'D'),
    (Number:  100; Symbol: 'C'),
    (Number:   50; Symbol: 'L'),
    (Number:   10; Symbol: 'X'),
    (Number:    5; Symbol: 'V'),
    (Number:    1; Symbol: 'I')
  );
begin
  Result := 0;

  var i := 0;
  var j := 0;
  var Len := iRomanNum.Length;
  while i < Len do
  begin
    var C := iRomanNum.Chars[i];
    var N := iRomanNum.Chars[i + 1];

    var CR := ROMANS[j];
    var NR := ROMANS[j - 1];

    if N = NR.Symbol then
    begin
      var D := 1;
      while D < NR.Number do
        D := D * 10;

      Inc(Result, NR.Number - D div 10);
      Inc(i, 2);
    end
    else
    begin
      if C = CR.Symbol then
      begin
        Inc(Result, CR.Number);
        Inc(i);
      end
      else
        Inc(j);
    end
  end;
end;

?Y果
         :    0
      XII:   12
     XXIV:   24
     XLII:   42
     XLIX:   49
   LXXXIX:   89
   CCXCIX:  299
  CDXCIII:  493
    MCMLX: 1960
MMMCMXCIX: 3999


program RomanNum;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uRomanNumHelper in 'uRomanNumHelper.pas'; //将上面2个函数放到这个单元里

const
  NUMS: array[0.. 9] of Integer = (
    0, 12, 24, 42, 49, 89, 299, 493, 1960, 3999
  );
begin
  //阿拉伯数字→罗马数字
  Writeln('Alabic to Roman');
  for var N in NUMS do
    Writeln(N:4, ': ', ToRoman(N));

  Writeln;

//罗马数字→阿拉伯数字
  Writeln('Roman to Alabic');
  for var N in NUMS do
  begin
    var R := ToRoman(N);
    Writeln(R:9, ': ', ToAlabic(R):4);
  end;

  Readln;
end.

相关阅读 >>

Delphi 获取本机 hostname ip address

Delphi 对zlib单元进行再封装

Delphi firedac 下的 sqlite [4] - 创建数据库

Delphi 将 4 个 byte 合成 1 个 integer 的五种方法 - 回复 "三足乌" 的问题

Delphi webbrowser1 缩放网页

Delphi 隐藏文件夹

Delphi 如何快速从列表框tlistbox中删除重复项

Delphi 删除只读文件

Delphi ttabcontrol在tabitem添加关闭按钮

Delphi 拦截tab按键消息

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...