3

The input will be a string of Roman numerals that have to be sorted by their value. Also this task has to be completed using classes in c++

So far I've created my class

#include<iostream>
#include<string>
using namespace std;

class RomanNumbers
{
public:
    RomanNumbers(string = "");

    void setRoman(string);

    int convertToDecimal();

    void printDecimal();

    void printRoman();


private:

    string roman;

    int decimal;

};

And the functions to convert a number from Roman numeral to integer form but my question is : How shall I sort them because I can't create a new string that will contain the converted Roman numerals and sort the string. Any help will be appreciated.

#include<iostream>
#include<string>
#include "RomanNumbers.h"
using namespace std;

RomanNumbers::RomanNumbers(string myRoman)
{
    roman = myRoman;
    decimal = 0;
}

void RomanNumbers::setRoman(string myRoman)
{
    roman = myRoman;
    decimal = 0;
}

int RomanNumbers::convertToDecimal()
{
    enum romans { I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000 };

    for (int i = 0; i < roman.size(); i++)
    {
        switch (roman[i])
        {

         case 'M': decimal += M; break;
         case 'D': decimal += D; break;
         case 'C': decimal += C; break;
         case 'L': decimal += L; break;
         case 'X': decimal += X; break;
         case 'V': decimal += V; break;

         case 'I':
             if (roman[i + 1] != 'I' && i + 1 != roman.size())
             {
                 decimal -= 1;
             }
             else
             {
                 decimal += 1;
             }
               break;

        }
    }

    return decimal;
}

void RomanNumbers::printRoman()
{
    cout << "Number in Roman form : " << roman;
    cout << endl;
}

void RomanNumbers::printDecimal()
{
    cout << "Number converted in integer form : " << decimal;

    cout << endl;
}
Ziezi
  • 6,375
  • 3
  • 39
  • 49
Triple3XH
  • 113
  • 3
  • 11
  • 1
    You can create a new array/vector of your values stored as `std::pair` and sort that, or you can make a custom sorting predicate passed to `std::sort` that uses your conversion function to compare values. – paddy Mar 27 '17 at 22:25
  • Also notice that your conversion will not work for numbers like XC (90) – DannyPhantom Mar 27 '17 at 22:27
  • 1
    Can you give me a piece code to understand better ? @paddy – Triple3XH Mar 27 '17 at 22:37
  • I'm not sure what you mean by “sort the string”. Don't you want to sort by the *number*? Unless you're doing an alphabetical sort (C, CC, CCC, CCCI, CCCII, CCCIII, CCCIV, CCCIX, CCCL, CCCLI, etc.). – dan04 Mar 27 '17 at 22:37
  • @dan04 By sort the string i mean to sort the values of the Roman Numerals but the output will be a string of Roman Numerals sorted by their value – Triple3XH Mar 27 '17 at 22:48
  • @Triple3XH: There's only a minor benefit to `std::pair`. The chief problem is that you need an `operator<` such that `RomanNumbers("M") < RomanNumbers("MX")`. That's not hard, once you fix the problem that `decimal` is not set. You must call `convertToDecimal` whenever you get a new string. – MSalters Mar 27 '17 at 23:28
  • @MSalters i don't know how to make an operator < to solve my problem – Triple3XH Mar 27 '17 at 23:31
  • 1
    @Triple3XH: Plenty of existing questions on that here on StackOverflow. Check for "operator overloading". – MSalters Mar 27 '17 at 23:33
  • @MSalters how shall i fix the problem that decimal is not set ? – Triple3XH Mar 28 '17 at 00:02

1 Answers1

6

One way to tackle your problem is through a definition of a meaningful comparison operator< / comparison lambda expression / comparison class, which then be used along with the sort algorithm:

template <class RandomAccessIterator, class Compare>
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

for example a comparison class would be:

struct RomanComp 
{
    bool operator() const (const RomanNumbers& lhs, const RomanNumbers& rhs)
    { 
        return lhs.decimal < rhs.decimal;
    }
} RomanComparator; // <--- note object instantiation

and then to sort a vector of roman number for example, you do:

std::vector<RomanNumbers> nums;

std::sort(nums.begin(), nums.end(), RomanComparator);

assuming:

#include <algorithm>    // std::sort
#include <vector>       // std::vector
Ziezi
  • 6,375
  • 3
  • 39
  • 49
  • Or just define that operator as 'operator<'. Slightly simpler, and maybe makes the class easier to use for other purposes as well. – Cris Luengo Mar 28 '17 at 01:47
  • @CrisLuengo I've tried to overload the operator << like that : `friend ostream& operator <<(ostream &os, const RomanNumbers &r) { return (os << r.printRoman); }` but again it won't work so if you have ever a better solution with code please tell me – Triple3XH Mar 28 '17 at 01:51