Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

JSUMRZYM - Dodawanie rzymskie Program źle dodaje duże liczby

Ostatnio zmodyfikowano 2020-09-08 17:12
Autor Wiadomość
Mag19
Temat założony przez niniejszego użytkownika
JSUMRZYM - Dodawanie rzymskie Program źle dodaje duże liczby
» 2020-09-07 22:45:03
Rozwiązuję zadanie ze spoja: https://pl.spoj.com/problems/JSUMRZYM/
Problem w tym, że program sumuje małe liczby jak I+II albo I+I. Przy większych jak IV+V LUB V+I nie wypisuje poprawnego wyniku.

C/C++
#include <iostream>
#include <map>
#include <cstdlib>
#include <algorithm>
#include <string>

using namespace std;
using std::transform;

const map < int, string > mapaRzymska {
    { 1000, "M" }, { 900, "CM" }, { 500, "D" }, { 400, "CD" }, { 100, "C" }, { 90, "XC" },
    { 50, "L" }, { 40, "XL" }, { 10, "X" }, { 9, "IX" }, { 5, "V" }, { 4, "IV" }, { 1, "I" }
};


int zRzymskiegoNaArabski( string liczba ) {
    int dlugoscLiczby = liczba.size();
    int suma = 0;
    int i = 0;
    auto iter = mapaRzymska.begin();
   
    while( i < dlugoscLiczby ) {
        if(( liczba[ i ] == iter->second[ 0 ] ) ) { //&& (iter -> second.size() == 1)){
            suma += iter->first;
            i++;
        }
        else if( i < dlugoscLiczby - 1 && liczba.substr( i, 2 ) ==( ++iter )->second ) {
            suma += iter->first;
            i += 2;
            --iter;
        }
        else if( iter != mapaRzymska.end() ) {
            ++iter;
        }
    }
   
    return suma;
}

string zArabskiegoNaRzymski( int liczba ) {
    string wynik = " ";
    auto iter = mapaRzymska.begin();
   
    while( liczba > 0 ) {
        if( liczba >= iter->first ) {
            liczba -= iter->first;
            wynik += iter->second;
        }
        else if( liczba >= iter->first ) {
            liczba -= iter->first;
            wynik += iter->first;
        }
        else if( iter != mapaRzymska.end() ) {
            iter++;
        }
    }
   
    return wynik;
   
}


int main()
{
    string wynik;
    string liczbaRzymska1, liczbaRzymska2;
    int dlugosc, cyfra;
   
   
   
    while( cin >> liczbaRzymska1 >> liczbaRzymska2 ) {
       
        transform( liczbaRzymska1.begin(), liczbaRzymska1.end(), liczbaRzymska1.begin(),
        []( unsigned char c )->unsigned char { return std::toupper( c ); } );
       
        transform( liczbaRzymska2.begin(), liczbaRzymska2.end(), liczbaRzymska2.begin(),
        []( unsigned char c )->unsigned char { return std::toupper( c ); } );
       
       
        wynik = zArabskiegoNaRzymski( zRzymskiegoNaArabski( liczbaRzymska1 ) + zRzymskiegoNaArabski( liczbaRzymska2 ) );
        cout << wynik;
        cout << endl;
    }
   
    cin.get(); cin.get();
   
    return 0;
}
P-177519
killjoy
» 2020-09-08 01:00:49
Nie działa ci konwersja z arabskiego na rzymski. Na pierwszy rzut oka, twoja mapa będzie posortowana rosnąco wg. klucza (liczby arabskiej). Użyj metod .rbegin() i .rend() zamiast .begin() i .end(), żeby przejść po mapie w odwrotnej kolejności w funkcji zArabskiegoNaRzymski(), wtedy konwersja powinna działać (chyba, że coś przeoczyłem, bo tylko rzuciłem okiem).

#edit
Po przyglądnięciu się, nie zadziała też konwersja zRzymskiegoNaArabski(). Najlepiej będzie, jak napisał @pekfos w poście poniżej, zastąpić std::map przez std::vector<std::pair>, bez innych zmian w kodzie.
P-177520
pekfos
» 2020-09-08 17:12:41
Użyj metod .rbegin() i .rend() zamiast .begin() i .end(), żeby przejść po mapie w odwrotnej kolejności
Tu nawet nie ma wyszukiwania na mapie. Powinien być po prostu wektor par.
C/C++
const std::vector < std::pair < int, string >> mapaRzymska {
    { 1000, "M" }, { 900, "CM" }, { 500, "D" }, { 400, "CD" }, { 100, "C" }, { 90, "XC" },
    { 50, "L" }, { 40, "XL" }, { 10, "X" }, { 9, "IX" }, { 5, "V" }, { 4, "IV" }, { 1, "I" }
};
P-177529
« 1 »
  Strona 1 z 1