0 Replies - 1594 Views - Last Post: 30 May 2011 - 12:38 PM Rate Topic: -----

#1 anonymous26   User is offline

  • D.I.C Lover

Reputation: 2
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Decimal to Roman Numeral Converter

Posted 30 May 2011 - 12:38 PM

Description: Code to convert a decimal into its equivalent Roman numeral string.
#include <stdio.h>
#include <string.h>

#define MAX_ROMAN_NUMERALS	100

struct ROMAN_NUMERALS
{
    char letter;
    int value;
};

const struct ROMAN_NUMERALS rns[] = {{'M', 1000}, {'D', 500}, {'C', 100}, {'L', 50}, {'X', 10}, {'V', 5}, {'I', 1}};

int HowManyOfNumeral(int numeral, int *num);
const char* PostProcessRNs(unsigned char* rnString);
void ModifyRNs3(char* subStr, const char* numerals, const unsigned int count);
void ModifyRNs4(char* subStr, const char* numerals, const unsigned int count);
void ModifyRNs5(char* subStr, const char* numerals, const unsigned int count);

char romanNumerals[MAX_ROMAN_NUMERALS] = {0};	// Roman numeral string.

int main()
{
	int numFromArg = 0;	// Number to convert.
	int idx;
	int rnidx;

	int stringIndex = 0;        // Keep track of string position in romanNumerals.
	int howManyNumerals = 0;    // How many times each numeral appears in the final string.
	int sizeOfRomanNumerals = sizeof(rns) / sizeof(rns[0]);

	printf("Enter a number - ");
	scanf("%d", &numFromArg);

	if(numFromArg > (1000 * MAX_ROMAN_NUMERALS))
	{
		printf("Numbers only up to %d supported.n", 1000 * MAX_ROMAN_NUMERALS);
		return 0;
	}
	else
	if(numFromArg < 0)
	{
		puts("Negative numbers not supported.");
		return 0;
	}

	if(numFromArg != 0)
	{
		for(idx = 0; idx < sizeOfRomanNumerals; idx++)
		{
			howManyNumerals = HowManyOfNumeral(rns[idx].value, &numFromArg);

			// Fill the string.
			rnidx = stringIndex;

			for(; rnidx < (stringIndex + howManyNumerals); rnidx++)
			{
				romanNumerals[rnidx] = rns[idx].letter;
			}

			stringIndex = rnidx;
		}

		printf("Roman numeral string (after postprocess) is %sn", PostProcessRNs(romanNumerals));
	}
	else
	{
		romanNumerals[0] = 'N';
		printf("Roman numeral string (nulla) is %sn", romanNumerals);
	}
        
	return 0;
}

int HowManyOfNumeral(int numeral, int *num)
{
	int ratio;

 	if(*num < numeral)
 	    return 0;

	// How many times does the numeral go into num?
	ratio = *num / numeral;

  	// Reduce num by the ratio and continue calculation.
    *num -= numeral * ratio;

    return ratio;
}

const char* PostProcessRNs(unsigned char* rnString)
{
	const char* RN_REPEATERS[] = {"CCCC", "XXXX", "IIII", "LXXXX", "DCCCC", "VIV"};

	char* ptrToSubStr;
	const unsigned int memoryUpperLimit = (unsigned int)rnString + (MAX_ROMAN_NUMERALS - 1);

	// **** Repeating numerals 5x
	// Look for 'LXXXX' and convert to 'XC'.
	if(ptrToSubStr = strstr(rnString, RN_REPEATERS[3]))
	{
		ModifyRNs5(ptrToSubStr, "XC", memoryUpperLimit - (unsigned int)(ptrToSubStr + 5));
	}

	// Look for 'DCCCC' and convert to 'CM'.
	if(ptrToSubStr = strstr(rnString, RN_REPEATERS[4]))
	{
		ModifyRNs5(ptrToSubStr, "CM", memoryUpperLimit - (unsigned int)(ptrToSubStr + 5));
	}

	// **** Repeating numerals 4x
	// Look for 'CCCC' and convert to 'CD'.
	if(ptrToSubStr = strstr(rnString, RN_REPEATERS[0]))
	{
		ModifyRNs4(ptrToSubStr, "CD", memoryUpperLimit - (unsigned int)(ptrToSubStr + 4));
	}

	// Look for 'XXXX' and convert to 'XL'.
	if(ptrToSubStr = strstr(rnString, RN_REPEATERS[1]))
	{
		ModifyRNs4(ptrToSubStr, "XL", memoryUpperLimit - (unsigned int)(ptrToSubStr + 4));
	}

	// Look for 'IIII' and convert to 'IV'.
	if(ptrToSubStr = strstr(rnString, RN_REPEATERS[2]))
	{
		ModifyRNs4(ptrToSubStr, "IV", memoryUpperLimit - (unsigned int)(ptrToSubStr + 4));
	}

	// Look for 'VIV' and replace with 'IX'.
	if(ptrToSubStr = strstr(rnString, RN_REPEATERS[5]))
	{
		ModifyRNs3(ptrToSubStr, "IX", memoryUpperLimit - (unsigned int)(ptrToSubStr + 3));
	}

	return rnString;
}

void ModifyRNs3(char* subStr, const char* numerals, const unsigned int count)
{
	*subStr = *numerals;
	*(subStr + 1) = *(numerals + 1);
	memmove(subStr + 2, subStr + 3, count);
}

void ModifyRNs4(char* subStr, const char* numerals, const unsigned int count)
{
	*subStr = *numerals;
	*(subStr + 1) = *(numerals + 1);
	memmove(subStr + 2, subStr + 4, count);
}

void ModifyRNs5(char* subStr, const char* numerals, const unsigned int count)
{
	*subStr = *numerals;
	*(subStr + 1) = *(numerals + 1);
	memmove(subStr + 2, subStr + 5, count);
}



Is This A Good Question/Topic? 0
  • +

Page 1 of 1