// <copyright file="RomanNumeralExtensions.cs" company="Always Elucidated Solution Pioneers, LLC">
// Copyright (c) 2008 Always Elucidated Solution Pioneers, LLC. All Rights Reserved.
// </copyright>
// <author>Jesse C. Slicer</author>
// <email>[email protected]</email>
// <date>2008-10-01</date>
// <summary>Translates Roman numeral strings to integers and vice-versa.</summary>
namespace Aesop.Extensions
{
// System namespaces
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
/// <summary>
/// Holds the IsValidRomanNumeral(), ParseRomanNumeral() and ToRomanNumeralString() extension methods.
/// </summary>
public static class RomanNumeralExtensions
{
/// <summary>
/// The number of mappings in the dictionary.
/// </summary>
private const int NumberOfRomanNumeralMaps = 13;
/// <summary>
/// The matching of Roman numeral placeholders to their integer equivalents.
/// </summary>
private static readonly Dictionary<string, int> romanNumerals =
new Dictionary<string, int>(NumberOfRomanNumeralMaps)
{
{ "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 }
};
/// <summary>
/// The regular expression to test the string against.
/// </summary>
private static readonly Regex validRomanNumeral = new Regex(
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
/// <summary>
/// Determines whether the specified string is a valid Roman numeral.
/// </summary>
/// <param name="value">
/// The Roman numeral string to validate.
/// </param>
/// <returns>
/// <c>true</c> if the specified string is a valid Roman numeral; otherwise, <c>false</c>.
/// </returns>
public static bool IsValidRomanNumeral(this string value)
{
return validRomanNumeral.IsMatch(value);
}
/// <summary>
/// Parses the Roman numeral into its integer equivalent.
/// </summary>
/// <param name="value">
/// The Roman numeral string.
/// </param>
/// <returns>
/// The integer representation of the Roman numeral.
/// </returns>
public static int ParseRomanNumeral(this string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
value = value.ToUpperInvariant().Trim();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral())
{
throw new ArgumentException("Empty or invalid Roman numeral string.", "value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = romanNumerals[value[--i].ToString()];
if (i > 0)
{
var previousDigit = romanNumerals[value[i - 1].ToString()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
/// <summary>
/// Converts the number to its equivalent Roman numeral string.
/// </summary>
/// <param name="value">
/// The integer to convert.
/// </param>
/// <returns>
/// The Roman numeral representation of the integer.
/// </returns>
public static string ToRomanNumeralString(this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder(MaxRomanNumeralLength);
foreach (var pair in romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append(pair.Key);
value -= pair.Value;
}
}
return sb.ToString();
}
}
}
// <copyright file="RomanNumeralExtensions.cs" company="Always Elucidated Solution Pioneers, LLC">
// Copyright (c) 2008 Always Elucidated Solution Pioneers, LLC. All Rights Reserved.
// </copyright>
// <author>Jesse C. Slicer</author>
// <email>[email protected]</email>
// <date>2008-10-01</date>
// <summary>Translates Roman numeral strings to integers and vice-versa.</summary>
namespace Aesop.Extensions
{
// System namespaces
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
/// <summary>
/// Holds the IsValidRomanNumeral(), ParseRomanNumeral() and ToRomanNumeralString() extension methods.
/// </summary>
public static class RomanNumeralExtensions
{
/// <summary>
/// The number of mappings in the dictionary.
/// </summary>
private const int NumberOfRomanNumeralMaps = 13;
/// <summary>
/// The matching of Roman numeral placeholders to their integer equivalents.
/// </summary>
private static readonly Dictionary<string, int> romanNumerals =
new Dictionary<string, int>(NumberOfRomanNumeralMaps)
{
{ "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 }
};
/// <summary>
/// The regular expression to test the string against.
/// </summary>
private static readonly Regex validRomanNumeral = new Regex(
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
/// <summary>
/// Determines whether the specified string is a valid Roman numeral.
/// </summary>
/// <param name="value">
/// The Roman numeral string to validate.
/// </param>
/// <returns>
/// <c>true</c> if the specified string is a valid Roman numeral; otherwise, <c>false</c>.
/// </returns>
public static bool IsValidRomanNumeral(this string value)
{
return validRomanNumeral.IsMatch(value);
}
/// <summary>
/// Parses the Roman numeral into its integer equivalent.
/// </summary>
/// <param name="value">
/// The Roman numeral string.
/// </param>
/// <returns>
/// The integer representation of the Roman numeral.
/// </returns>
public static int ParseRomanNumeral(this string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
value = value.ToUpperInvariant().Trim();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral())
{
throw new ArgumentException("Empty or invalid Roman numeral string.", "value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = romanNumerals[value[--i].ToString()];
if (i > 0)
{
var previousDigit = romanNumerals[value[i - 1].ToString()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
/// <summary>
/// Converts the number to its equivalent Roman numeral string.
/// </summary>
/// <param name="value">
/// The integer to convert.
/// </param>
/// <returns>
/// The Roman numeral representation of the integer.
/// </returns>
public static string ToRomanNumeralString(this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder(MaxRomanNumeralLength);
foreach (var pair in romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append(pair.Key);
value -= pair.Value;
}
}
return sb.ToString();
}
}
}
public static class RomanNumeralExtensions
{
private const int NumberOfRomanNumeralMaps = 13;
private static readonly Dictionary<string, int> romanNumerals =
new Dictionary<string, int>(NumberOfRomanNumeralMaps)
{
{ "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 }
};
private static readonly Regex validRomanNumeral = new Regex(
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
public static bool IsValidRomanNumeral(this string value)
{
return validRomanNumeral.IsMatch(value);
}
public static int ParseRomanNumeral(this string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
value = value.ToUpperInvariant().Trim();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral())
{
throw new ArgumentException("Empty or invalid Roman numeral string.", "value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = romanNumerals[value[--i].ToString()];
if (i > 0)
{
var previousDigit = romanNumerals[value[i - 1].ToString()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
public static string ToRomanNumeralString(this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder(MaxRomanNumeralLength);
foreach (var pair in romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append(pair.Key);
value -= pair.Value;
}
}
return sb.ToString();
}
}
Here's a to-and-from for Roman Numeralsnumerals. Not often used, but could be handy. Usage:
if ("IV".IsValidRomanNumeral ())
{
// Do useful stuff with the number 4.
}
Console.WriteLine ("MMMDCCCLXXXVIII".ParseRomanNumeral ());
Console.WriteLine (3888.ToRomanNumeralString ());
// <copyright file="RomanNumeralExtensions.cs" company="Always Elucidated Solution Pioneers, LLC">
// Copyright (c) 2008 Always Elucidated Solution Pioneers, LLC. All Rights Reserved.
// </copyright>
// <author>Jesse C. Slicer</author>
// <email>[email protected]</email>
// <date>2008-10-01</date>
// <summary>Translates Roman Numeralnumeral strings to integers and vice-versa.</summary>
namespace Aesop.Extensions
{
#region Using Directives
// System namespaces
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
#endregion
#region Static Class Definition : RomanNumeralExtensions
/// <summary>
/// Holds the IsValidRomanNumeral (), ParseRomanNumeral () and
/// ToRomanNumeralString () extension methods.
/// </summary>
public static class RomanNumeralExtensions
{
#region Public Static Extension Methods /// <summary>
/// The number of mappings in the dictionary.
/// </summary>
private const int NumberOfRomanNumeralMaps = 13;
/// <summary>
/// DeterminesThe whethermatching theof specifiedRoman stringnumeral isplaceholders ato validtheir Romaninteger numeralequivalents.
/// </summary>
/// <param name="value"> private static readonly Dictionary<string, int> romanNumerals =
/// The Roman numeral string to validate. new Dictionary<string, int>(NumberOfRomanNumeralMaps)
/// </param> {
/// <returns> { "M", 1000 },
/// <c>true</c> if the specified string is a valid Roman numeral; { "CM", 900 },
/// otherwise { "D", <c>false</c>.500 },
/// </returns> { "CD", 400 },
public static bool { "C", 100 },
IsValidRomanNumeral (this string value) { "XC", 90 },
{ "L", 50 },
return m_validRomanNumeral.IsMatch (value); { "XL", 40 },
{ "X", 10 },
{ "IX", 9 },
{ "V", 5 },
{ "IV", 4 },
{ "I", 1 }
};
/// <summary>
/// Parses the Roman<summary>
numeral into its integer equivalent.
/// </summary>
The regular ///expression <paramto name="value">
test the string ///against.
The Roman numeral string.
/// </param>summary>
/// <returns>
/// private Thestatic integerreadonly representationRegex ofvalidRomanNumeral the= Romannew numeral.Regex(
/// </returns>
public static int
ParseRomanNumeral "^(this string value?i:(?=[MDCLXVI])
((M{0,3})((C[DM])|(D?C{0,3}))"
if (value == null)
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
throw new ArgumentNullException ("value"RegexOptions.Compiled);
}
value = value/// <summary>
/// Determines whether the specified string is a valid Roman numeral.ToUpperInvariant
/// </summary>
/// <param name="value">
/// The Roman numeral string to validate.
/// </param>
/// <returns>
/// <c>true</c> if the specified string is a valid Roman numeral; otherwise, <c>false</c>.
/// </returns>
public static bool IsValidRomanNumeral(this string value).Trim
{
return validRomanNumeral.IsMatch(value);
}
var length/// =<summary>
value /// Parses the Roman numeral into its integer equivalent.Length;
/// </summary>
if ((length ==/// 0)<param ||name="value">
!value /// The Roman numeral string.IsValidRomanNumeral
/// </param>
/// <returns>
/// The integer representation of the Roman numeral.
/// </returns>
public static int ParseRomanNumeral()this string value)
{
throw new ArgumentException if (value == null)
"Empty{
or invalid Roman numeral string.",
throw new ArgumentNullException("value");
}
var total = 0;
var ivalue = length;
while value.ToUpperInvariant(i > 0)
{
var digit = m_romanNumerals [value [--i].ToString Trim()];;
if (i > 0)
{
var previousDigitlength = m_romanNumerals [value [i - 1]value.ToString ()];Length;
if (previousDigit(length <== digit0) || !value.IsValidRomanNumeral())
{
digit -= previousDigit;
throw new ArgumentException("Empty or invalid Roman numeral string.", i--"value");
}
}
total += digit;
}
return total;
}
/// <summary>
/// Converts the number to its equivalent Roman numeral string.
/// </summary>
/// <param name="value">
/// The integer to convert.
/// </param>
/// <returns>
/// The Roman numeral representation of the integer.
/// </returns>
public static string
ToRomanNumeralStringvar (thistotal int= value)0;
{
const int MinValue = 1;
const int var MaxValuei = 3999;length;
if ((value < MinValue) || while (valuei > MaxValue)0)
{
throw new ArgumentOutOfRangeException (
"value",{
value,
"Argument out ofvar Romandigit numeral= rangeromanNumerals[value[--i]."ToString();
}];
const int MaxRomanNumeralLength = 15; if (i > 0)
var sb {
var previousDigit = newromanNumerals[value[i StringBuilder- 1].ToString(MaxRomanNumeralLength);];
foreach (var pair in m_romanNumerals if (previousDigit < digit)
{
while (value / pair.Value > 0)
{ digit -= previousDigit;
sb.Append (pair.Key) i--;
value -= pair.Value; }
}
}
return sb.ToString (); total += digit;
}
#endregion return total;
}
#region Private Static Member Data /// <summary>
/// Converts the number to its equivalent Roman numeral string.
/// </summary>
/// <param name="value">
/// The integer to convert.
/// </param>
/// <returns>
/// The Roman numeral representation of the integer.
/// </returns>
public static string ToRomanNumeralString(this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
/// <summary>
/// The number ofif mappings((value in< theMinValue) dictionary.|| (value > MaxValue))
/// </summary>
private const int {
throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
NumberOfRomanNumeralMaps = 13; }
/// <summary>
/// The regular expression to test the string against.
const int MaxRomanNumeralLength ///= </summary>15;
private static readonly Regex var m_validRomanNumeralsb =
new Regex (
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?StringBuilder(II{0,2}))|V)?))$",
RegexOptions.CompiledMaxRomanNumeralLength);
/// <summary>
/// The matching of Roman numeral placeholders to their integer
foreach ///(var pair in equivalents.romanNumerals)
/// </summary>
private static readonly Dictionary<string, int> m_romanNumerals ={
new Dictionary<string, int> (NumberOfRomanNumeralMaps)
{
while (value {/ "M",pair.Value 1000> },0)
{ "CM", 900 },
{ "D", 500 },
{ "CD", 400 },
{ "C", 100 },
{ "XC", 90 },
{ "L", 50 },sb.Append(pair.Key);
{ "XL", 40 },
{ "X", 10 },
{ "IX",value 9-= },pair.Value;
{ "V", 5 },
{ "IV", 4 },
{ "I", 1 }
};
#endregion return sb.ToString();
}
#endregion }
}
Here's a to-and-from for Roman Numerals. Not often used, but could be handy. Usage:
if ("IV".IsValidRomanNumeral ())
{
// Do useful stuff with the number 4.
}
Console.WriteLine ("MMMDCCCLXXXVIII".ParseRomanNumeral ());
Console.WriteLine (3888.ToRomanNumeralString ());
// <copyright file="RomanNumeralExtensions.cs" company="Always Elucidated Solution Pioneers, LLC">
// Copyright (c) 2008 Always Elucidated Solution Pioneers, LLC. All Rights Reserved.
// </copyright>
// <author>Jesse C. Slicer</author>
// <email>[email protected]</email>
// <date>2008-10-01</date>
// <summary>Translates Roman Numeral strings to integers and vice-versa.</summary>
namespace Aesop.Extensions
{
#region Using Directives
// System namespaces
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
#endregion
#region Static Class Definition : RomanNumeralExtensions
/// <summary>
/// Holds the IsValidRomanNumeral (), ParseRomanNumeral () and
/// ToRomanNumeralString () extension methods.
/// </summary>
public static class RomanNumeralExtensions
{
#region Public Static Extension Methods
/// <summary>
/// Determines whether the specified string is a valid Roman numeral.
/// </summary>
/// <param name="value">
/// The Roman numeral string to validate.
/// </param>
/// <returns>
/// <c>true</c> if the specified string is a valid Roman numeral;
/// otherwise, <c>false</c>.
/// </returns>
public static bool
IsValidRomanNumeral (this string value)
{
return m_validRomanNumeral.IsMatch (value);
}
/// <summary>
/// Parses the Roman numeral into its integer equivalent.
/// </summary>
/// <param name="value">
/// The Roman numeral string.
/// </param>
/// <returns>
/// The integer representation of the Roman numeral.
/// </returns>
public static int
ParseRomanNumeral (this string value)
{
if (value == null)
{
throw new ArgumentNullException ("value");
}
value = value.ToUpperInvariant ().Trim ();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral ())
{
throw new ArgumentException (
"Empty or invalid Roman numeral string.",
"value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = m_romanNumerals [value [--i].ToString ()];
if (i > 0)
{
var previousDigit = m_romanNumerals [value [i - 1].ToString ()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
/// <summary>
/// Converts the number to its equivalent Roman numeral string.
/// </summary>
/// <param name="value">
/// The integer to convert.
/// </param>
/// <returns>
/// The Roman numeral representation of the integer.
/// </returns>
public static string
ToRomanNumeralString (this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException (
"value",
value,
"Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder (MaxRomanNumeralLength);
foreach (var pair in m_romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append (pair.Key);
value -= pair.Value;
}
}
return sb.ToString ();
}
#endregion
#region Private Static Member Data
/// <summary>
/// The number of mappings in the dictionary.
/// </summary>
private const int NumberOfRomanNumeralMaps = 13;
/// <summary>
/// The regular expression to test the string against.
/// </summary>
private static readonly Regex m_validRomanNumeral =
new Regex (
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
/// <summary>
/// The matching of Roman numeral placeholders to their integer
/// equivalents.
/// </summary>
private static readonly Dictionary<string, int> m_romanNumerals =
new Dictionary<string, int> (NumberOfRomanNumeralMaps)
{
{ "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 }
};
#endregion
}
#endregion
}
Here's a to-and-from for Roman numerals. Not often used, but could be handy. Usage:
if ("IV".IsValidRomanNumeral())
{
// Do useful stuff with the number 4.
}
Console.WriteLine("MMMDCCCLXXXVIII".ParseRomanNumeral());
Console.WriteLine(3888.ToRomanNumeralString());
// <copyright file="RomanNumeralExtensions.cs" company="Always Elucidated Solution Pioneers, LLC">
// Copyright (c) 2008 Always Elucidated Solution Pioneers, LLC. All Rights Reserved.
// </copyright>
// <author>Jesse C. Slicer</author>
// <email>[email protected]</email>
// <date>2008-10-01</date>
// <summary>Translates Roman numeral strings to integers and vice-versa.</summary>
namespace Aesop.Extensions
{
// System namespaces
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
/// <summary>
/// Holds the IsValidRomanNumeral(), ParseRomanNumeral() and ToRomanNumeralString() extension methods.
/// </summary>
public static class RomanNumeralExtensions
{
/// <summary>
/// The number of mappings in the dictionary.
/// </summary>
private const int NumberOfRomanNumeralMaps = 13;
/// <summary>
/// The matching of Roman numeral placeholders to their integer equivalents.
/// </summary>
private static readonly Dictionary<string, int> romanNumerals =
new Dictionary<string, int>(NumberOfRomanNumeralMaps)
{
{ "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 }
};
/// <summary>
/// The regular expression to test the string against.
/// </summary>
private static readonly Regex validRomanNumeral = new Regex(
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
/// <summary>
/// Determines whether the specified string is a valid Roman numeral.
/// </summary>
/// <param name="value">
/// The Roman numeral string to validate.
/// </param>
/// <returns>
/// <c>true</c> if the specified string is a valid Roman numeral; otherwise, <c>false</c>.
/// </returns>
public static bool IsValidRomanNumeral(this string value)
{
return validRomanNumeral.IsMatch(value);
}
/// <summary>
/// Parses the Roman numeral into its integer equivalent.
/// </summary>
/// <param name="value">
/// The Roman numeral string.
/// </param>
/// <returns>
/// The integer representation of the Roman numeral.
/// </returns>
public static int ParseRomanNumeral(this string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
value = value.ToUpperInvariant().Trim();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral())
{
throw new ArgumentException("Empty or invalid Roman numeral string.", "value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = romanNumerals[value[--i].ToString()];
if (i > 0)
{
var previousDigit = romanNumerals[value[i - 1].ToString()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
/// <summary>
/// Converts the number to its equivalent Roman numeral string.
/// </summary>
/// <param name="value">
/// The integer to convert.
/// </param>
/// <returns>
/// The Roman numeral representation of the integer.
/// </returns>
public static string ToRomanNumeralString(this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder(MaxRomanNumeralLength);
foreach (var pair in romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append(pair.Key);
value -= pair.Value;
}
}
return sb.ToString();
}
}
}
Here's a to-and-from for Roman Numerals. Not often used, but could be handy. Usage:
if ("IV".IsValidRomanNumeral ())
{
// Do useful stuff with the number 4.
}
Console.WriteLine ("MMMDCCCLXXXVIII".ParseRomanNumeral ());
Console.WriteLine (3888.ToRomanNumeralString ());
The source:
// <copyright file="RomanNumeralExtensions.cs" company="Always Elucidated Solution Pioneers, LLC">
// Copyright (c) 2008 Always Elucidated Solution Pioneers, LLC. All Rights Reserved.
// </copyright>
// <author>Jesse C. Slicer</author>
// <email>[email protected]</email>
// <date>2008-10-01</date>
// <summary>Translates Roman Numeral strings to integers and vice-versa.</summary>
namespace Aesop.Extensions
{
#region Using Directives
// System namespaces
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
#endregion
#region Static Class Definition : RomanNumeralExtensions
/// <summary>
/// Holds the IsValidRomanNumeral (), ParseRomanNumeral () and
/// ToRomanNumeralString () extension methods.
/// </summary>
public static class RomanNumeralExtensions
{
#region Public Static Extension Methods
/// <summary>
/// Determines whether the specified string is a valid Roman numeral.
/// </summary>
/// <param name="value">
/// The Roman numeral string to validate.
/// </param>
/// <returns>
/// <c>true</c> if the specified string is a valid Roman numeral;
/// otherwise, <c>false</c>.
/// </returns>
public static bool
IsValidRomanNumeral (this string value)
{
return m_validRomanNumeral.IsMatch (value);
}
/// <summary>
/// Parses the Roman numeral into its integer equivalent.
/// </summary>
/// <param name="value">
/// The Roman numeral string.
/// </param>
/// <returns>
/// The integer representation of the Roman numeral.
/// </returns>
public static int
ParseRomanNumeral (this string value)
{
if (value == null)
{
throw new ArgumentNullException ("value");
}
value = value.ToUpperInvariant ().Trim ();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral ())
{
throw new ArgumentException (
"Empty or invalid Roman numeral string.",
"value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = m_romanNumerals [value [--i].ToString ()];
if (i > 0)
{
var previousDigit = m_romanNumerals [value [i - 1].ToString ()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
/// <summary>
/// Converts the number to its equivalent Roman numeral string.
/// </summary>
/// <param name="value">
/// The integer to convert.
/// </param>
/// <returns>
/// The Roman numeral representation of the integer.
/// </returns>
public static string
ToRomanNumeralString (this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException (
"value",
value,
"Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder (MaxRomanNumeralLength);
foreach (var pair in m_romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append (pair.Key);
value -= pair.Value;
}
}
return sb.ToString ();
}
#endregion
#region Private Static Member Data
/// <summary>
/// The number of mappings in the dictionary.
/// </summary>
private const int NumberOfRomanNumeralMaps = 13;
/// <summary>
/// The regular expression to test the string against.
/// </summary>
private static readonly Regex m_validRomanNumeral =
new Regex (
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
/// <summary>
/// The matching of Roman numeral placeholders to their integer
/// equivalents.
/// </summary>
private static readonly Dictionary<string, int> m_romanNumerals =
new Dictionary<string, int> (NumberOfRomanNumeralMaps)
{
{ "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 }
};
#endregion
}
#endregion
}
lang-cs