Problem z programem – zmiana liczb rzymskich na arabskie i odwrotnie

0

Witam, otóż mam mały problem. Napisałem program który ma zamieniać liczby arabskie na rzymskie i odwrotnie. Wiem, że były takie tematy na forum ale nie chcę gotowego programu.Wiem także, że mojemu programowi potrzeba wyjątków , które oczywiście dodam ale program i tak się odpalić ponieważ nie wiem jak zwrócić stringa.

public class RzymArab
{
   private static String[] liczby= {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"};
   private static int[] liczby1={1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
  
   public static String arab2rzym(int arab)
   {
      for(int i=13; i>=0; --i)
      {
         while(arab>=liczby1[i])
         {
           arab=arab-liczby1[i];
           return liczby1[i];
         }
      }
   }

   public static int rzym2arab(String rzym)
   {       
      int n=0;
      for(int i=rzym.length(); i>=1; i--)
      {
         for(int a=13; a>=0; --a)
         {
            if(rzym.charAt(i)==liczby[a].charAt(0))
            { 
               n=n+liczby1[a];   
            }
         }
      }
   return n;
   }
}
0

arab2rzym ma zwrócić String a Ty próbujesz zrobić:

return liczby[i];

Napisałeś że masz problem ale nie napisałeś o co dokładnie chodzi.

0

Poprawiłem to return ale cały czas wyskakuje :

missing return statement
   }
   ^
1 error

I ogólnie chciałbym się dowiedzieć czy algorytm przekształcania jest dobry czy czegoś brakuje?

0

Brakuje return dlatego że powinieneś mieć zwracany jakiś domyślny wynik na samym końcu funkcji.
Czyli:

public static String arab2rzym(int arab) {
	for (int i = 0; i ... ) { ... }
	return "";
}

Dzięki temu wiesz że funkcja na pewno coś zwróci (bo warunek w while może być false i return nie wykona się).

0

No ok wszystko rozumiem tylko teraz nie mam pojęcia jak stworzyć w while takie coś żebym potem mógł zwrócić całego Stringa np MMV. To co miałem było dla mnie zrozumiałe ale miało ten błąd, że może to być fałszywe.

0

Użyj np. StringBuilder i dodawaj rzeczy do niego a potem zwróć String:

public static String arab2rzym(int arab) {
    StringBuilder builder = new StringBuilder();

    for (int i = 12; i >= 0; --i) {
        while (arab >= liczby1[i]) {
            arab = arab - liczby1[i];
            builder.append(liczby[i]);
        }
    }

    return builder.toString();
}
0

Ok wszystko rozumiem :) Teraz tworząc maina muszę uzyć metod statycznych bo tak mam w poleceniu. Muszę tam dać jakieś warunki czy wartość która idzie to tablicy jest liczba rzymską czy arabską i co ma być w princie tzn RzymArab.arab2rzym() czy RzymArab.rzym2arab()?

0

wartość która idzie to tablicy

Chyba do metody?
Możesz sprawdzać na samym początku metody czy przekazany String w rzym2Arab() jest poprawny (tj. czy nie ma np. znaku 'F' którego nie ma systemie rzymskim). Jeżeli jest niepoprawny to możesz rzucić wyjątek i obsłużyć go w main().

co ma być w princie tzn RzymArab.arab2rzym() czy RzymArab.rzym2arab()?

To zależy czy chcesz przekonwertować liczbę z systemu arabskiego na rzymski czy odwrotnie, mnie nie pytaj :P.

0

Tylko, że ja muszę stworzyć klasę Exception gdzię chyba muszę to zawrzeć. Muszę w niej zawrzeć, że arab <1,3999> i chyba, że mogą być tylko znaki I V M D C o czymś jeszcze zapomniałem?

0

Tak, jest jeszcze X :).

Sprawdzasz w metodzie czy liczba jest OK - jeżeli nie jest rzucasz wyjątek używając nowej klasy dziedziczącej po Exception (poniżej zamieszczam przykład gdzie klasa nazywa się NumberException):

public static String arab2rzym(int arab) throws NumberException {
	if (arab < 1 || arab > 3999) {
		throw new NumberException("Nieprawidłowa liczba");
	}
	...
}
0

Utknąłem i nie wiem co mam zrobić. Nie mam pojęcia jak zrobić bład gdy pojawi się np Z. Może stworzyć tablice która będzie obsługiwałą tylko te moje znaki. Nie mam pojęcia.


```public class RzymArab
{
   private static String[] liczby= {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"};
   private static int[] liczby1={1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
  
   public static String arab2rzym(int arab)
   {
      if (arab < 1 || arab > 3999)
      {
         throw new RzymArabException("Nieprawidłowa liczba");
      }
      StringBuilder builder = new StringBuilder();
      for (int i = 12; i >= 0; --i)
      {
         while (arab >= liczby1[i])
         {
            arab = arab - liczby1[i];
            builder.append(liczby[i]);
        }
    }
 
    return builder.toString();
}

   public static int rzym2arab(String rzym) throws RzymArabException
   {       
      int n=0;
      for(int i=rzym.length(); i>=1; i--)
      {
         for(int a=13; a>=0; --a)
         {
            if(rzym.charAt(i)==liczby[a].charAt(0))
            { 
               n=n+liczby1[a];   
            }
         }
      }
   return n;
   }

   public static void main(String[] args) throws RzymArabException
   {
      
   }
}
0

Może stworzyć tablice która będzie obsługiwałą tylko te moje znaki.

No to jaki jest problem?
Zrób dodatkową tablicę char która będzie zawierała prawidłowe znaki a następnie sprawdź czy String jest poprawny poprzez szukanie czy każdy jego znak występuje w tablicy - jeżeli nie, to argument jest nieprawidłowy i rzucasz wyjątek.
Polecałbym wydzielić sobie to do osobnej metody boolean która zwraca true jeżeli przekazany do niej znak znajduje się w tablicy prawidłowych znaków i false jeśli się nie znajduje.

0

Coś takiego?


```   private static int[] liczby1={1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
   private static char[] liczby2={"I", "V", "X", "L", "C", "D", "M"};
   public static String arab2rzym(int arab)
   {
      if (arab < 1 || arab > 3999)
      {
         throw new RzymArabException("Nieprawidłowa liczba");
      }
      StringBuilder builder = new StringBuilder();
      for (int i = 12; i >= 0; --i)
      {
         while (arab >= liczby1[i])
         {
            arab = arab - liczby1[i];
            builder.append(liczby[i]);
        }
    }
 
    return builder.toString();
}

   private boolean isGood(string rzym)
   {
      for(int i=1; i<=rzym.length(); i++)
      {
         for(int n=0; n<13; n++)
         {
            if(rzym.charAt(i)==liczby2[n].charAt(0))
            {
               return true;
            }
            else
            {
               return false;
            }
         }
      }
   }   

   public static int rzym2arab(String rzym) throws RzymArabException
   {
      if(isGood(String rzym))
         {       
            int n=0;
            for(int i=rzym.length(); i>=1; i--)
            {
               for(int a=13; a>=0; --a)
               {
                  if(rzym.charAt(i)==liczby[a].charAt(0))
                  { 
                     n=n+liczby1[a];   
                  }
               }
            }
         return n;
      }
   else
   {
      throw new RzymArabException("Nieprawidłowa dana");
   }
}
0

Piszesz bez IDE? Bo parę problemów od razu widać i kodu nie da się skompilować:

  1. To jest tablica char - jej elementy nie mogą być typu String.
private static char[] liczby2={"I", "V", "X", "L", "C", "D", "M"};
  1. Tutaj
for(int i=1; i<=rzym.length(); i++)

Pierwsza litera to indeks 0, ostatnia to length() - 1 więc ta pętla powinna wyglądać tak:

for (int i = 0; i < rzym.length(); i++)
  1. Skąd się bierze magiczne 13?
for(int n=0; n<13; n++)

liczby2 ma 7 elementów, ale lepiej pobrać ilość niż hard-kodować ją:

for (int n = 0; n < liczby2.length; n++)
  1. Poniższe trzeba będzie poprawić po naprawieniu pierwszego problemu.
if(rzym.charAt(i)==liczby2[n].charAt(0))
  1. Zobacz co tutaj się dzieje:
if(rzym.charAt(i)==liczby2[n].charAt(0))
{
		return true;
}
else
{
		return false;
}

Zauważ że nie ma szans aby pozostałe znaki były sprawdzone bo już przy pierwszym zwracasz prawdę albo fałsz. Zaneguj warunek w if i zwróć false, else wywal, dopiero na samym końcu metody zrób return true.

0

Tam dałem 13 bo za szybko robiłem i policzyłem elementy tablicy liczby a nie liczby2.
Mam takie coś, ujdzie?


   private boolean isGood(string rzym)
   {
      int k=0;
      int s=0;
      for(int i=0; i<rzym.length(); i++)
      {
         for(int n=0; n<7; n++)
         {
            if(rzym.charAt(i)==liczby2[n].charAt(0))
            {
               k++;
            }
            else
            {
               s++;
            }
         }
      }
   if(k=rzym.length()-1)
   {
      return true;
   }
   else
   {
      return false;
   }
} 
0

Zobacz jeszcze raz 1), 3) i 5) komentarz pod spodem - nie mówiłem abyś pozbywał się return false w for tylko zmienił zasadę działania na:

for(int i=0; i<rzym.length(); i++)
{
    for(int n=0; n<7; n++)
    {
        if(rzym.charAt(i)==liczby2[n].charAt(0)) {
            return false; // Nieprawidłowy znak! Zwracamy false
        }
    }
}
return true; // Wszystkie znaki OK (inaczej zwróciłoby już false) - zwracamy true
0

Nie rozumiem jednej rzeczy co oznacza to valid w sumie mogę się domyslać ale chciałbym dokładnie wiedzieć.
Co mamy:


```public class RzymArab
{
   private static String[] liczby= {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"};
   private static int[] liczby1={1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
   private static char[] liczby2={'I', 'V', 'X', 'L', 'C', 'D', 'M'};
   public static String arab2rzym(int arab)
   {
      if (arab < 1 || arab > 3999)
      {
         throw new RzymArabException("Nieprawidłowa liczba");
      }
      StringBuilder builder = new StringBuilder();
      for (int i = 12; i >= 0; --i)
      {
         while (arab >= liczby1[i])
         {
            arab = arab - liczby1[i];
            builder.append(liczby[i]);
         }
      }
   return builder.toString();
   }
   private boolean isGood(string rzym)
   {
      for(int i=0; i<rzym.length(); i++)
      {
         for(int n=0; n<7; n++)
         {
            if(rzym.charAt(i)==valid[n].charAt(0))
            {
               return false;
            }
        }
     }
   }
   return true;
 
   public static int rzym2arab(String rzym) throws RzymArabException
   {
      if(isGood(String rzym))
         {       
            int n=0;
            for(int i=rzym.length(); i>=1; i--)
            {
               for(int a=13; a>=0; --a)
               {
                  if(rzym.charAt(i)==liczby[a].charAt(0))
                  { 
                     n=n+liczby1[a];   
                  }
               }
            }
         return n;
      }
   else
   {
      throw new RzymArabException("Nieprawidłowa dana");
   }
}
0

valid przez przypadek pomyliłem z liczby2 :/.

private boolean isGood(string rzym)
{
    for(int i=0; i<rzym.length(); i++)
    {
        for(int n=0; n<7; n++)
        {
            if(rzym.charAt(i)==liczby2[n].charAt(0))
            {
                return false;
            }
        }
    }
}
return true;

Zobacz gdzie to return true jest.
W Javie nie ma string - jest za to String.

Pisałem aby nie obliczać w głowie ilości elementów w tablicy tylko aby użyć liczby2.length w tym kawałku kodu:

for(int n=0; n<7; n++)
0

?


```public class RzymArab
{
   private static String[] liczby= {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"};
   private static int[] liczby1={1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
   private static char[] liczby2={'I', 'V', 'X', 'L', 'C', 'D', 'M'};
   public static String arab2rzym(int arab)
   {
      if (arab < 1 || arab > 3999)
      {
         throw new RzymArabException("Nieprawidłowa liczba");
      }
      StringBuilder builder = new StringBuilder();
      for (int i = 12; i >= 0; --i)
      {
         while (arab >= liczby1[i])
         {
            arab = arab - liczby1[i];
            builder.append(liczby[i]);
         }
      }
   return builder.toString();
   }
   private boolean isGood(String rzym)
   {
      for(int i=0; i<rzym.length(); i++)
      {
         for(int n=0; n<liczby2.length(); n++)
         {
            if(rzym.charAt(i)==liczby2[n].charAt(0))
            {
               return false;
            }
        }
     }
   return true;
   } 
   public static int rzym2arab(String rzym) throws RzymArabException
   {
      if(isGood(rzym))
         {       
            int n=0;
            for(int i=rzym.length(); i>=1; i--)
            {
               for(int a=13; a>=0; --a)
               {
                  if(rzym.charAt(i)==liczby[a].charAt(0))
                  { 
                     n=n+liczby1[a];   
                  }
               }
            }
         return n;
      }
   else
   {
      throw new RzymArabException("Nieprawidłowa dana");
   }
}
0

Masz jakieś IDE czy w notatniku klepiesz?

if(rzym.charAt(i)==liczby2[n].charAt(0))

Ma być:

if (rzym.charAt(i) == liczby2[n])
  1. Tu
public static String arab2rzym(int arab) /* tutaj */ {

Musisz dodać throws RzymArabException.

0

W notatniku :D ok poprawiłem tylko w if(isGood(rzym)) wyskakuje, że tam nie może być stringa :D

0

Może być String, problem jest taki że metoda isGood() nie jest statyczna.

0

Czytam o metodach statycznych i tych zwykłych, patrze na swój poprzedni program, który działał w podobny sposób więc nie widzę tu żadnego błędu..

0

Ale z metody statycznej możesz odwoływać się do innych metod/zmiennych tylko pod warunkiem że również są statyczne, w przeciwnym razie musisz skorzystać z obiektu tej klasy. A więc isGood() musi być metodą statyczną.

Jeżeli na serio z tym notatnikiem - ściągnij jakieś IDE (np. IntelliJ IDEA) - łatwiej będzie Ci programować bo będzie Cię informować o problemach na bieżąco a nie tylko przy kompilacji.

0

Kurde no nie wiem jak to zmienić a to pewnie jest banalnie proste..Tzn możliwe, że pamiętasz poprzedni program i to wyglądało identycznie..

0

No jak nie wiesz jak to zmienić jak wszystko inne masz statyczne, po prostu dodaj static przed boolean:

private static boolean isGood(String rzym) {
0

haha wybacz już chyba nie myślę :D

0

A teraz nie mam pojęcia co mam zrobić w mainie :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1