Премини към съдържанието
theking44

Помощ за програма за превръщане на арабските цифри в римски

    Препоръчан отговор

    theking44    3

    Извинявам се но знам че тази тема не е за този форум но ми трябва бърза услуга по информатика трябва да направя проект в който арабските числа да се превръщат в римски и обратно ПОМОЩ !!!!

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове

    Написах програма на С++ с джампове вместо с функции. По лесно и четливо ми се стори.

     

    Имам и аз един въпрос. Защо във втората функция, тази за превръщане на римско число в арабско ми се налага да напиша 2 пъти функцията getline(); за да се изпълни само веднъж. WINDOWS 7, компилатор на Майкрософт.

     

    Аз ли съм бъгав или компилатора ?

     

    #include <iostream>
    #include <string>
    #include <new>
    using namespace std;
    
    void romantonumber();
    void numbertoroman();
    
    int main()
    {
    	int n;
    	cout << "choose from the menu\n\n";
    	cout << "1 - Roman to Number\n";
    	cout << "2 - Number to Roman\n";
    	cin >> n;
    	if (n == 1) romantonumber();
    	else if (n == 2)numbertoroman();
    	return 0;
    }
    
    void numbertoroman()
    {
    	int i;
    	unsigned number;
    	unsigned thousands;
    	string roman;
    	roman = "";
    	cout << "\nInput a number to transfer into Roman number\n";
    	cin >> number;
    location1to10:	
    	if (number < 5)
    	{
    		if (number == 0)
    		{
    			cout << "There is not a number zero in the Roman number system";
    			return;
    		}
    		else if (number == 4)
    		{
    			roman = roman + "IV";
    			cout << roman;
    			return;
    		}
    		else
    		{
    location123:			
    			for (i = 1; i <= 3; i++)
    			{
    				roman = roman + "I";
    				if (i == number)
    				{
    					cout << roman;
    					return;
    				}
    			}
    		}
    	}
    	else if (number < 10)
    	{
    		if (number == 9)
    		{
    			roman = roman + "IX";
    			cout << roman;
    			return;
    		}
    		else if (number == 5)
    		{
    			roman = roman + "V";
    			cout << roman;
    			return;
    		}
    		else
    		{
    			roman = roman + "V";
    			number = number - 5;
    			goto location123;
    		}
    	}
    	else if (number < 20)
    	{
    		roman = roman + "X";
    location10to20:		
    		if (number == 10)
    		{
    			cout << roman;
    			return;
    		}
    		else 
    		{
    			number = number - 10;
    			goto location1to10;
    		}
    	}
    	else if (number < 30)
    	{
    		roman = roman + "XX";
    		number = number - 10;
    		goto location10to20;
    	}
    	else if (number < 40)
    	{
    		roman = roman + "XXX";
    		number = number - 20;
    		goto location10to20;
    	}
    	else if (number < 50)
    	{
    		roman = roman + "XL";
    		number = number - 30;
    		goto location10to20;
    	}
    	else if (number < 90)
    	{
    		roman = roman + "L";
    		if (number == 50)
    		{
    			cout << roman;
    			return;
    		}
    		else
    		{
    			number = number - 50;
    			goto location1to10;
    		}
    	}
    	else if (number < 100)
    	{
    		roman = roman + "XC";
    		if (number == 90)
    		{
    			cout << roman;
    			return;
    		}
    		number = number - 90;
    		goto location1to10;
    	}
    	else if (number < 200)
    	{
    		roman = roman + "C";
    location100to200:		
    		if (number == 100)
    		{
    			cout << roman;
    			return;
    		}
    		number = number - 100;
    		goto location1to10;
    	}
    	else if (number < 300)
    	{
    		roman = roman + "CC";
    		number = number - 100;
    		goto location100to200;
    	}
    	else if (number < 400)
    	{
    		roman = roman + "CCC";
    		number = number - 200;
    		goto location100to200;
    	}
    	else if (number < 500)
    	{
    		roman = roman + "CD";
    		number = number - 300;
    		goto location100to200;
    	}
    	else if (number < 900)
    	{
    		roman = roman + "D";
    		if (number == 500)
    		{
    			cout << roman;
    			return;
    		}
    		number = number - 500;
    		goto location1to10;
    	}
    	else if (number < 1000)
    	{
    		roman = roman + "CM";
    		if (number == 900)
    		{
    			cout << roman;
    			return;
    		}
    		number = number - 900;
    		goto location1to10;
    	}
    	else if (number < 65536)
    	{
    		thousands = number/1000;
    		for (i = 1; i <= thousands; i++) roman = roman + "M";
    		if (number % 1000 == 0)
    		{
    			cout << roman;
    			return;
    		}
    		number = number - thousands*1000;
    		goto location1to10;
    	}
    	else cout << "Too big number !!!";
    }
    
    void romantonumber()
    {
    	int number = 0;
    	int i;
    	int a;
    	string roman;
    	string c;
    	cout << "\nInput the Roman number to convert to number\n";
    	getline(cin, roman); //Защо трябва да го напиша 2 пъти за да се изпълни веднъж ???
    	getline(cin, roman);
    	a = roman.length();
    	int* aroman = new int[a];
    	for (i = 0; i < a; i++)
    	{
    		c = roman.substr(i,1);
    		if (c == "I") aroman[i] = 1;
    		else if (c == "V") aroman[i] = 5;
    		else if (c == "X") aroman[i] = 10;
    		else if (c == "L") aroman[i] = 50;
    		else if (c == "C") aroman[i] = 100;
    		else if (c == "D") aroman[i] = 500;
    		else if (c == "M") aroman[i] = 1000;
    		else
    		{
    			cout << "This is not a valid Roman number";
                            delete[] aroman;
    			return;
    		}
    	}
    	for (i = 0; i < a - 1; i++)
    	{
    		if (aroman[i] < aroman[i+1]) number = number - aroman[i];
    		else number = number + aroman[i];
    		if (number > 65535) 
    		{
    			cout << "Too big number";
                            delete[] aroman;
    			return;
    		}
    	}
    	number = number + aroman[a-1];
    	if (number > 65535) 
    	{
                    delete[] aroman;
    		cout << "Too big number";
    		return;
    	}
            delete[] aroman;
    	cout << number;
    }
    
    

    Редактирано от Реджеп Иведик (преглед на промените)
    • Харесва ми 1

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    ined    3561

    Защото не изчистваш буфера преди getline()

         cout << "\nInput the Roman number to convert to number\n";
         cin.ignore();
         getline(cin, roman);
    	
    
    Редактирано от ined (преглед на промените)

    • Харесва ми 1

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    flare    10428

    Написах програма на С++ с джампове вместо с функции. По лесно и четливо ми се стори.

    Тази реплика изпълни със радост моето съществуване тази сутрин. Благодаря!

    • Харесва ми 2

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    ined    3561

    Тази реплика изпълни със радост моето съществуване тази сутрин. Благодаря!

    Какво по-добро за закуска от една спагети прогама в BASIC стил :)

     

    Иначе преобразуването арабски към римски цифри не дава добре оптимизирани числа

    примерно: 1999 го докарва само до MCMXCIX вместо до MIM

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    flare    10428

    примерно: 1999 го докарва само до MCMXCIX вместо до MIM

    Срещу правилата не се рита. Първото е вярно.

    • Харесва ми 2

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    ined    3561

    Прав си, сега видях че имало и правило

    • Символ, представляващ стойност 10x, не може да се поставя пред символ, по-голям от 10x+1. Така например M може да бъде предшестван от D и C, но не и от I, V, X или L.
    Редактирано от ined (преглед на промените)

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    flare    10428

    Прав си, сега видях че имало и правило

    ...

    Така например M може да бъде предшестван от D и C

    Ми даже е и по-строго:

    Пред M и D се слага само C. Пред C и L само X. пред X - само I

    То е очевидно де - няма никакъв смисъл да слагаш половинка отпред...

     

    Но продължавам да се впечатлявам от тая програма горе. Опитвам се да измисля как да я направя по-нечетлива. Баси дори lookup таблица с всички възможни стойности ще е по-прегледна.

    Редактирано от flare (преглед на промените)
    • Харесва ми 1

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    ined    3561

    Ако действително правилата са толкова строги на практика се опростява много записа с таблица:

    const unsigned numt[]={1,  4,   5,  9,  10,  40,  50, 90, 100, 400,500,900,1000};
    const string nums[]={ "I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
    
    void numbertoroman()
    {
        int x=12;
        unsigned number;
        string roman;
        roman = "";
        cout << "\nInput a number to transfer into Roman number\n";
        cin >> number;
        if (number>100000)
        {
            cout<<"Too big number\n";
            return;
        }
        while (number) 
        {
            if (number >= numt[x]) 
            {
                 roman += nums[x];
                 number -= numt[x];
            }
            else x--;
        }
        cout<<roman<<endl;
    }
    
    Редактирано от ined (преглед на промените)
    • Харесва ми 2

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    flare    10428

     

    ...

    Точно така е. Даже има и още - максимум 3 повторения на знак на база 10 и едно на знак на база 5

    Редактирано от flare (преглед на промените)

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове

    Не се сетих. 


    Точно така е. Даже има и още - максимум 3 повторения на знак.

     

     

    С изключение на хилядите.

     

    Но правилото за три повторения не е строго правило.

    Редактирано от Реджеп Иведик (преглед на промените)

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    flare    10428

    Не се сетих. 

     

    С изключение на хилядите.

     

    Но правилото за три повторения не е строго правило.

    Няма изключения. Тия сега сме си ги измислили. За по-големи числа римляните слагали чертички отгоре. Почвайте да правите графично приложение. Хем ще сложите и дванайсетичните дроби.

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове

    Няма изключения. Тия сега сме си ги измислили. За по-големи числа римляните слагали чертички отгоре. Почвайте да правите графично приложение. Хем ще сложите и дванайсетичните дроби.

     

    В уикипедия пише, че има. Не само за големите, но и за малките числа. 

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове
    ined    3561
    const unsigned numt[]={1,  4,   5,  9,  10,  40,  50, 90, 100, 400,500,900,1000};
    const string nums[]={ "I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
    
    string num2rom(unsigned n)
    {
        int x=12;
        string r="";
        while (n)
           if (n >= numt[x])
           {
               r += nums[x];
               n -= numt[x];
           }
           else x--;
        return r;
    }
    
    void numbertoroman()
    {
        unsigned number, t;
        string roman="";
        cout << "\nInput a number to transfer into Roman number\n";
        cin >> number;
        if (number>=4000000) 
        {
            cout<<"Too BIG number\n";
            return;
        }
        if (number>3999)
        {
            t=number/1000%5;
            if (t==4) t=0;
            roman=num2rom(number/1000-t);
            for (int i=0; i<roman.length(); i++) cout<<'_';
            cout<<endl;
            number %= 1000 + t*1000;
        }
        roman += num2rom(number);
        cout<<roman<<endl;
    }
    
    Редактирано от ined (преглед на промените)

    Сподели този отговор


    Линк към този отговор
    Сподели в други сайтове

    Регистрирайте се или влезете в профила си за да коментирате

    Трябва да имате регистрация за да може да коментирате това

    Регистрирайте се

    Създайте нова регистрация в нашия форум. Лесно е!

    Нова регистрация

    Вход

    Имате регистрация? Влезте от тук.

    Вход


    ×

    Информация

    Този сайт използва бисквитки (cookies), за най-доброто потребителско изживяване. С използването му, вие приемате нашите Условия за ползване.