Converting Roman number to Decimal using Interpreter design pattern

Interpreter design pattern is mainly used in compiler and other language processing programs. This design pattern used to identify various language mainly textual such as numbers, regular expression etc. This design pattern interprets every language syntax and assign a class accordingly, to do further processing.

Before going ahead have a look at Design pattern simplified version.

Let’s write the program for converting Roman number to decimal using interpreter design pattern

#include <iostream>
#include <string.h>

using namespace std;

class Roman_one;
class Roman_ten;
class Roman_hundred;
class Roman_thousand;

class Interpreter
{
	private:
		Roman_one* one;
		Roman_ten* ten;
		Roman_hundred* hun;
		Roman_thousand* thou;

	public:
		Interpreter ();
		Interpreter (bool ignore) 
		{} /* to avoid infinite loop */
		~Interpreter ();
		virtual char check_one () {}
		virtual char* check_four () {} /* Since in this case it have to return two chars */
		virtual char* check_nine () {} /* Since in this case it have to return two chars */
		virtual char check_five () {}
		virtual int multiplier () {}

		virtual void interpret_string (char *in, int &total)
		{
			int index = 0;
			if (!strncmp (in, check_nine(), 2))
			{
				total = total + 9 * multiplier ();
				index = index + 2;
			}
			else if (!strncmp (in, check_four(), 2))
			{
				total = total + 4 * multiplier ();
				index = index + 2;
			}
			else if (in [0] == check_five())
			{
				total = total + 5 * multiplier ();
				index++;
				for (int i = 0; i < 3; i++)
				{
					if (in [index] == check_one ())
					{
						total = total + 1 * multiplier ();
						index ++;
					}
					else
						break;
				}
			}
			else
			{
				/* check for ones */
				for (int i = 0; i < 3; i++)
				{
					if (in [index] == check_one ())
					{
						total = total + 1 * multiplier ();
						index ++;
					}
					else
						break;
				}
			}
			strcpy(in, &(in[index]));
		}

		virtual int interpret (char *in);

};

class Roman_thousand: public Interpreter
{
	public:
		Roman_thousand (): Interpreter (true)
		{}
		virtual char check_one ()
		{
			return 'M';
		}
		virtual char* check_four ()
		{
			return (char *)"";
		}
		virtual char check_five ()
		{
			return '\0';
		}
		virtual char* check_nine ()
		{
			return (char *)"";
		}
		virtual int multiplier ()
		{
			return 1000;
		}
};

class Roman_hundred: public Interpreter
{
	public:
		Roman_hundred (): Interpreter (true)
		{}
		virtual char check_one ()
		{
			return 'C';
		}
		virtual char* check_four ()
		{
			return (char *)"CD";
		}
		virtual char check_five ()
		{
			return 'D';
		}
		virtual char* check_nine ()
		{
			return (char *)"CM";
		}
		virtual int multiplier ()
		{
			return 100;
		}
};

class Roman_ten: public Interpreter
{
	public:
		Roman_ten (): Interpreter (true)
		{}
		virtual char check_one ()
		{
			return 'X';
		}
		virtual char* check_four ()
		{
			return (char *)"XL";
		}
		virtual char check_five ()
		{
			return 'L';
		}
		virtual char* check_nine ()
		{
			return (char *)"XC";
		}
		virtual int multiplier ()
		{
			return 10;
		}
};

class Roman_one: public Interpreter
{
	public:
		Roman_one (): Interpreter (true)
		{}
		virtual char check_one ()
		{
			return 'I';
		}
		virtual char* check_four ()
		{
			return (char *)"IV";
		}
		virtual char check_five ()
		{
			return 'V';
		}
		virtual char* check_nine ()
		{
			return (char *)"IX";
		}
		virtual int multiplier ()
		{
			return 1;
		}
};

Interpreter::Interpreter ()
{
	one = new Roman_one ();
	ten = new Roman_ten ();
	hun = new Roman_hundred ();
	thou = new Roman_thousand ();
}

Interpreter::~Interpreter ()
{
	delete one;
	delete ten;
	delete hun;
	delete thou;
}

int Interpreter::interpret (char *in)
{
	int total = 0;
	thou->interpret_string (in, total);
	hun->interpret_string (in, total);
	ten->interpret_string (in, total);
	one->interpret_string (in, total);
	return total;
}

int main ()
{
	char num[20] = "";

	cout << "Enter Roman Number: " << endl;
	cin >> num;

	cout << "Entered Number is: "<< num << endl;
	Interpreter inter;
	int ret = inter.interpret (num);
	cout << "Equivalent Number is: "<< ret << endl;

}

Output of above program:

Enter Roman Number: 
MDCCCLXXXVI
Entered Number is: MDCCCLXXXVI
Equivalent Number is: 1886

Enter Roman Number: 
MMDCLXVIII
Entered Number is: MMDCLXVIII
Equivalent Number is: 2668

Leave a Reply

Your email address will not be published. Required fields are marked *