• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zamienianie liczb rzymskich na arabskie

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
0 głosów
4,469 wizyt
pytanie zadane 19 września 2016 w Java przez littlerunaway Obywatel (1,790 p.)

	for (int j = 0; j < romertall.length() - 1; j++) {

			if (a.length > 1) {

				if (a[j] >= a[j + 1]) {
					d = a[j + 1] + a[j];
					System.out.println("Verdien i desimaltall: " + d);
				}

				else {
					d = a[j + 1] - a[j];
					System.out.println("Verdien i desimaltall: " + d);
				}

			}
		}

 

Reszta kodu: http://pastebin.com/PmX8rJH4

Chciałabym napisać program przemieniający liczby rzymskie na liczby arabskie. Gdy teraz przykładowo w swoim programie podam liczbę MCMLIV zostaje ona analizowana po kolei: MC CM ML LI IV i otrzymuję na koniec tego przypadku pięć liczb. Nie mam pojęcia jak je połączyć w spójny prawidłowy wynik. Poproszę o pomoc lub najchętniej jakieś wskazówki jak sobie z tym poradzić. 

3 odpowiedzi

+1 głos
odpowiedź 20 września 2016 przez Trucik Obywatel (1,130 p.)
wybrane 20 września 2016 przez littlerunaway
 
Najlepsza
        // Scanner in = new Scanner( System.in );
        String romertall = "MCMLIV";

        System.out.println( "Oppgi romertall: " );

        // romertall = in.next();

        int bufor = 0;                                          //inicjalizacja bufora
        int desimaltallBefore = 0;                              //rezerwacja na poprzednią wartoś
        for( int i = 0; i < romertall.length(); i++ )
        {
            char result = romertall.charAt( i );                //Twoja metoda
            int desimaltall = romertallTegnVerdi( result );     //Twoja metoda
            bufor += desimaltall;                               //Zawsze dodajes do bufora aktualną cyfrę rzymską
            if( desimaltallBefore < desimaltall )               //Jeśli poprzednia jest mniejsza niż aktualna
            {
                bufor -= 2 * desimaltallBefore;                 //Odejmujesz 2razy od bufora
            }
            desimaltallBefore = desimaltall;                    //przepisujesz z aktualną wartoś do poprzedniej i jedziesz kolejną pętlę
            System.out.println( bufor );
        }
    }

Zakomentowałem linię wpisywania daty. Algorytm może nie najszczęśliwszy, ale działa. Pamiętaj, że to jak Ty rozumiesz zagadnienie nie oznacza, że komputer musi robić to DOKŁADNIE tak samo :).

 

Jeśli chodzi o tworzenie takich prostych algorytmów polecam wziąć kartkę i długopis, WYŁĄCZYĆ KOMPUTER i rysować tak długo aż znajdziesz odpowiedź. Rozpisujesz sobie co po kolei ma się stać się z Twoim buforem, a później tłumaczysz całą taką sekwencje na instrukcje if/for/while.

komentarz 20 września 2016 przez littlerunaway Obywatel (1,790 p.)
Dziękuję bardzo :) Przeanalizuję to sobie i na następny raz na pewno będę będę wiedzieć jak z tego typu problemem sobie poradzić :)
+1 głos
odpowiedź 19 września 2016 przez Benek Szeryf (93,150 p.)
komentarz 19 września 2016 przez littlerunaway Obywatel (1,790 p.)
Już oglądałam, niezbyt pomogło.
W moim programie dodałam metodę która zwiera dwie tablice, jedną przechowującą liczby rzymskie, druga przechowująca liczby arabskie, obydwie posortowane rosnąco. Każdej liczbie rzymskiej przypisałam adekwatną liczbę arabską. Gdy w konsoli wpisze się liczbę rzymską dla każdego znaku zostanie zwrócona jego wartość, np V dostanie wartość 5, I wartość 1. Gdy wpisze się coś innego niż liczbę rzymską program się zakończy. W main'ie zrobiła pętlę for która w kolejnej tablicy zapisuje po kolei wartości każdego znaku, np. MCML {1000, 100, 1000, 50}. I właśnie w dalszej części mam problem, jak połączyć te wartości w jedną całość która daje odpowiedni wynik zależnie od tego czy poprzedzająca liczba jest większa czy mniejsza lub równa.
komentarz 19 września 2016 przez Benek Szeryf (93,150 p.)

Popełniasz zasadniczy błąd, tzn. przyjmujesz że w sekwencji liter tworzących liczbę rzymską, tylko pojedyncza litera odpowiada konkretnej wartości, a tak nie jest. Przykładowo sekwencja dwóch znaków CM odpowiada 900. Na szczęście podstawowych liczb rzymskich jest skończona ilość (kończą się na symbolu M = 1000), dzięki temu można rozpisać każdy przypadek, bo jest niewiele kombinacji.

Kluczem do zrozumienia konwersji jest to, że liczby rzymskie tworzy się od wartości największej (od lewej) do wartości najmniejszej (do prawej), a później sumuje się wartości poszczególnych elementów sekwencji. Rozważmy teraz liczbę, którą podałaś w przykładzie wyżej MCML. Zaczynamy od wartości, która leży po lewej stronie. Mamy więc następujący podział:

M -> CM -> L
1000 + 900 + 50 = 1950
1000 >= 900 >= 50 -> OK!

Natomiast Ty popełniałaś błąd, ponieważ Twój podział wyglądał następująco:

M -> C -> M -> L
1000 + 100 + 1000 + 50 = 2150
1000 >= 100 < 1000 + ... -> ERROR!

Jest on niezgodny z regułą, którą wyróżniłem wyżej innym kolorem.

komentarz 20 września 2016 przez littlerunaway Obywatel (1,790 p.)
No tak, ale przecież zrobiłam tak że jeżeli a[j] jest mniejsze od a[j+1] to wtedy od a[j+1] odejmuję a[j]. Czyli gdy będzie CM to a[1]<a[j+1] czyli 1000-100=900
komentarz 20 września 2016 przez Benek Szeryf (93,150 p.)

W ten sposób też można. Napisałaś:

I właśnie w dalszej części mam problem, jak połączyć te wartości w jedną całość która daje odpowiedni wynik zależnie od tego czy poprzedzająca liczba jest większa czy mniejsza lub równa.

To widzę że nie masz problemu, bo algorytm:

No tak, ale przecież zrobiłam tak że jeżeli a[j] jest mniejsze od a[j+1] to wtedy od a[j+1] odejmuję a[j]. Czyli gdy będzie CM to a[1]<a[j+1] czyli 1000-100=900

jest poprawny. Wystarczy na sam koniec zsumować wartości umieszczone w tablicy a[], by otrzymać wynik.

+1 głos
odpowiedź 19 września 2016 przez Trucik Obywatel (1,130 p.)
Wystarczy, że swój wynik będziesz dodawął lub odejmował od bufora.

Zastanów się w jaki sposób Ty odczytujesz liczby rzymskie. Robisz to od lewej tj od największej.

Zróbmy to na przykładzie by sie nie zgubić będą tu 5 kroków pętli.

MCMLIV

M - trafia do bufora bufor =1000

C - mniejsze niż poprzedni więc dodajesz do bufora. Bufor = 1100

M - większe niż poprzednia więc musisz z bufora odjąc poprzednią operacje dwukrotnie i dodać tę liczbę bufor = 1100 -2*100 +1000 = 1900

L - dodajesz do bufora Bufor -1950

I - dodajesz do bufora Bufor 1951

V - odejmujesz dwukrotnośc poprzedniej iteracji, a ten dodajesz do bufora Bufor 1951 - 1*2 +5 = 1954

 

To co musisz zapamięywać w petli to bufor, poprzednia wartość i wrzucić w pętle jedną instrukcje warunkową. Dzielisz liczby (a raczej litery) na pojedyncze, a nie podwójne znaki.

Algorytm wymyśliłem samodzielnie bez głębszego zastanowienia, ale powinien działać :). Jeśli będziesz miał problem z implementacją pisz.
komentarz 19 września 2016 przez littlerunaway Obywatel (1,790 p.)
Chyba będę potrzebować pomocy z implementacją. W jaki sposób mam zapamiętywać bufor? Będzie do tego potrzebne while? Jeżeli tak to jaki dać tam warunek bo zupełnie nie mam na to pomysły. Instrukcje warunkowe rozumiem że if oraz else? If >= else czyli <? Do czego mam to wtedy porównywać? Nie powinno być w taki sposób jak jest wyżej w moim pytaniu że porównuję a[i] do a[i+1]?

Podobne pytania

0 głosów
0 odpowiedzi 985 wizyt
pytanie zadane 6 maja 2021 w C i C++ przez Holdapia Nowicjusz (140 p.)
0 głosów
0 odpowiedzi 664 wizyt
0 głosów
2 odpowiedzi 2,343 wizyt
pytanie zadane 6 września 2016 w C i C++ przez Gambr Dyskutant (7,530 p.)

93,443 zapytań

142,434 odpowiedzi

322,691 komentarzy

62,805 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

...