Сортировка строки римских цифр

Входными данными будет строка римских цифр, которые необходимо отсортировать по их значению. Также эта задача должна быть выполнена с использованием классов в c++

Пока я создал свой класс

#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;

};

И функции для преобразования числа из римской цифры в целочисленную форму, но мой вопрос: как мне их отсортировать, потому что я не могу создать новую строку, которая будет содержать преобразованные римские цифры и отсортировать строку. Любая помощь будет оценена.

#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;
}

person Triple3XH    schedule 27.03.2017    source источник
comment
Вы можете создать новый массив/вектор ваших значений, хранящихся как std::pair<int,std::string>, и отсортировать его, или вы можете сделать собственный предикат сортировки, переданный в std::sort, который использует вашу функцию преобразования для сравнения значений.   -  person paddy    schedule 28.03.2017
comment
Также обратите внимание, что ваше преобразование не будет работать для таких чисел, как XC (90)   -  person DannyPhantom    schedule 28.03.2017
comment
Можете ли вы дать мне кусок кода, чтобы понять лучше? @Пэдди   -  person Triple3XH    schedule 28.03.2017
comment
Я не уверен, что вы подразумеваете под «сортировать строку». Разве вы не хотите сортировать по числу? Если вы не выполняете сортировку по алфавиту (C, CC, CCC, CCCI, CCCII, CCCIII, CCCIV, CCCIX, CCCL, CCCLI и т. д.).   -  person dan04    schedule 28.03.2017
comment
@ dan04 Под сортировкой строки я подразумеваю сортировку значений римских цифр, но на выходе будет строка римских цифр, отсортированных по их значению.   -  person Triple3XH    schedule 28.03.2017
comment
@Triple3XH: std::pair дает лишь незначительное преимущество. Основная проблема заключается в том, что вам нужен operator< такой, что RomanNumbers("M") < RomanNumbers("MX"). Это не сложно, как только вы решите проблему, что decimal не установлен. Вы должны вызывать convertToDecimal всякий раз, когда получаете новую строку.   -  person MSalters    schedule 28.03.2017
comment
@MSalters, я не знаю, как сделать оператор ‹, чтобы решить мою проблему   -  person Triple3XH    schedule 28.03.2017
comment
@Triple3XH: На StackOverflow существует множество вопросов по этому поводу. Проверьте, не перегружен ли оператор.   -  person MSalters    schedule 28.03.2017
comment
@MSalters, как мне решить проблему с неустановленным десятичным числом?   -  person Triple3XH    schedule 28.03.2017


Ответы (1)


Одним из способов решения вашей проблемы является определение осмысленного сравнения operator</сравнительного лямбда-выражения/класса сравнения, которые затем будут использоваться вместе с алгоритмом sort:

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

например, класс сравнения будет:

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

а затем, чтобы отсортировать вектор римского числа, например, вы делаете:

std::vector<RomanNumbers> nums;

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

предполагая:

#include <algorithm>    // std::sort
#include <vector>       // std::vector
person Ziezi    schedule 27.03.2017
comment
Или просто определите этот оператор как «оператор‹». Немного проще и, возможно, упрощает использование класса для других целей. - person Cris Luengo; 28.03.2017
comment
@CrisLuengo Я пытался перегрузить оператор ‹‹ вот так: friend ostream& operator <<(ostream &os, const RomanNumbers &r) { return (os << r.printRoman); }, но опять же это не сработает, поэтому, если у вас есть лучшее решение с кодом, сообщите мне - person Triple3XH; 28.03.2017