Obliczanie NWD i NWW algorytmem Euklidesa w C# i Javie

0

Cześć.

Napisałem sobie porównawczo ten sam algorytm w tych dwóch językach i chciałbym się zapytać czy w obu z nich kod źródłowy jest dobrze skonstruowany. Oto on:

C#:

 
using System;

namespace Euklides {

	class Euklides {

		int a, b, nw, nd;
		
		Euklides(int _a, int _b) {

			a = _a;
			b = _b;
		}
		
		int nwd() {

			int x=a, y=b;
			
			while (x!=y) 	{

				if(x>y)
					x=x-y;
				else
					y=y-x;
			}
			
			nd=x;
			return nd;
		}
		
		int nww() {

			nw = Math.Abs(a*b)/nd;
			return nw;
		}
		
	
		public static void Main(string[] args) {

			int a,b;
			
			Console.Write("a = ");
			a = int.Parse(Console.ReadLine());
			Console.Write("b = ");
			b = int.Parse(Console.ReadLine());
			
			Euklides wynik = new Euklides(a,b);
			
			Console.WriteLine("NWD = " + wynik.nwd());
			Console.WriteLine("NWW = " + wynik.nww());
			
			Console.Write("Press any key to continue . . . ");
			Console.ReadKey(true);
		}
	
	}
	
}

Java:

package euklides;

import java.io.*;

public class Euklides {

    int a, b, nwd, nww;

    public Euklides(int _a, int _b) {
        a = _a;
        b = _b;
    }

    public void nwd() {
        int x = a, y = b;

        while (x != y) {
            if (x > y) {
                x = x - y;
            } else {
                y = y - x;
            }
        }
        nwd = x;
        System.out.println("NWD = " + nwd);
    }

    public void nww() {
        nww = Math.abs(a * b) / nwd;
        System.out.println("NWW = " + nww);
    }

    public static void main(String[] args) {

        int a, b;
        BufferedReader znak = new BufferedReader(new InputStreamReader(System.in));


        System.out.print("a= ");

        try {
            a = Integer.parseInt(znak.readLine());
        } catch (IOException ex) {
            System.out.println("Błąd odczytu klawiatury.");
        }

        System.out.print("b= ");

        try {
            b = Integer.parseInt(znak.readLine());
        } catch (IOException ex) {
            System.out.println("Błąd odczytu klawiatury.");
        }

        Euklides wynik = new Euklides(a,b);

        wynik.nwd();
        wynik.nww();
    }
}

Po prostu jeśli dobrze napisałem oba te programy to miałbym jakaś bazę porównawczą odnośnie obu języków.
0

Jeżeli się kompiluje i działa to fajnie, ale od dobrze napisanego programu (przynajmniej w C#) jest baaaardzo daleko.

0

No to całkiem możliwe, bo to mój pierwszy program w C#. :)

A co tam takiego "nieciekawego" w nim jest?

0

Nie o to chodzi. Po prostu w C# nie da się napisać dobrego programu :D

BTW. programy w obu językach to przerost formy nad treścią.
Starałem się naśladować Twoją klasę w języku Python:

class Eukidles:
	def __init__(self,a,b):
		self.a=a
		self.b=b
		self.nw=self.nd=0
	def nwd(self):
		x,y=a,b
		while (x!=y):
			if x>y:
				x=x-y
			else:
				y=y-x
		self.nd=x
		return x
	def nww(self):
		nw = abs(a*b)/self.nd
		return nw
a=int(raw_input("a = "))
b=int(raw_input("b = "))
wynik=Eukidles(a,b)
print wynik.nwd()
print wynik.nww()

Mniej linijek o ponad połowę...

I te programy nie są identycznie napisane, więc nie mogą stanowić bazy porównawczej. W C# jest return, a w Javie już nie da się :D ?

0

Ojej...

1

Jeśli chodzi o C#, to nazwy metod przyjęło się zaczynać wielkimi literami. W takim przypadku, chyba całe nazwy napisałbym wielkimi.
Nie wiem, jaki jest w ogóle sens istnienia klasy Euklides i tworzenia jej obiektów, nie ma to raczej sensu (no chyba, że oszczędność na obliczeniach w przypadku liczenia NWD i NWW dla tej samej pary liczb, tylko czy jest to przypadek praktyczny?), za to zaciemnia kod. W tym wypadku wystarczyłyby funkcje, które zwracałyby po prostu wynik na podstawie przekazanych im parametrów.

0

A czy w językach w pełni obiektowych takich jak Java i C# może nie być żadnej klasy czy też tutaj wystarczyłaby tylko klasa "uruchomieniowa" z funkcją main plus funkcje nww() i nwd()?

0

Java i C# to nie są takie w pełni obiektowe języki :P - http://pl.wikipedia.org/wiki/Programowanie_obiektowe#Elementarna_charakterystyka_popularnych_j.C4.99zyk.C3.B3w_obiektowych
Pewnych cech nie spełniają.

0

Na angielskiej Wikipedii za to piszą, że "pure OO" to: Scala, Smalltalk, Eiffel, Ruby, JADE i Emerald. No ale z kolei do kategorii "mainly OO" wrzucają C#, Javę ale i C++. Z kolei gdzie indziej czytałem, że właśnie C++ to nie jest język obiektowy a raczej taki "język-śmietnisko", gdzie obecne są wymieszane chyba wszystkie paradygmaty programowania, a Java i C# to w przeciwieństwie do C++ jak najbardziej czysto obiektowe języki.

0

Najpoważniejszy błąd - liczenie NWW złym wyrażeniem. Zamiast NWW(a, b) = a * b / NWD(a, b) użyj NWW(a, b) = a / NWD(a, b) * b. Pomyśl co się stanie gdy odpalisz swoją i moją wersję NWW dla np a = 5 000 000 i b = 6 000 000.

Cortes:
Język obiektowy to język w którym wszystko jest obiektem. W Scali (chyba) wszystko jest. Na pewno typ obiektu jest klasą, funkcje czy krotki są klasami.

0

No faktycznie, zmieniłem wzór i liczy NWW dla dużych liczb. Ale spisałem go bezpośrednio z książki matematycznej. No ale raczej to jest błąd wynikający z braku praktyki programowania bez względu na użyty język. Zresztą już trochę późno jak na kodowanie - przynajmniej dla mnie! :)

0

Nie zmieniałem mojego kodu w Python'ie, a policzyło :P

a = 5000000
b = 6000000

1000000
30000000

I ja to wiem dlaczego :)

Jak skończył się zakres int'a, to przeszedł sobie na long'a, a long jest w Python'ie praktycznie nieograniczony.

0

Bo Pajton nie ma prawdziwych sprzętowych intów :]

Błąd przepełnienia jest dość powszechny przy indeksowaniu dużych zbiorów danych. Przykładowo wyciąganie średniej z nieujemnych intów (ze znakiem) trzeba zrobić w taki sposób: a + (b - a) / 2, a nie w taki: (a + b) / 2, ponieważ w tym drugim przypadku może dojść do przepełnienia. Ważne np przy pisaniu quicksorta.

0

A co sądzicie o takiej książce do C# na początek: Andrew Troelsen "Język C# 2010 i platforma .NET 4.0" a do Javy o najnowszym wydaniu dwutomowego działa "Java Core 1 i 2" Hortsmanna i Cornella (omawia Java 6)?

1

Podobno Horstmann do Javy jest OK. Jeśli interesują cię kruczki językowe to podobno dobre jest "Thinking in Java" Eckela. Jeżeli interesują cię nowinki Javowe to oczywiście The Java Tutorials: http://download.oracle.com/javase/tutorial/

0
somekind napisał(a)

Jeśli chodzi o C#, to nazwy metod przyjęło się zaczynać wielkimi literami. W takim przypadku, chyba całe nazwy napisałbym wielkimi.

Do capitalize only the first character of acronyms with three or more characters
http://msdn.microsoft.com/en-us/library/ms229043.aspx

public static int GreatestCommonDivisor(int first, int second)
{
    if (first == 0 || second == 0)
        throw new ArgumentException("Arguments must be non-zero");

    first = Math.Abs(first);
    second = Math.Abs(second);

    while (first != second)
    {
        if (first > second)
            first -= second;
        else
            second -= first;
    }

    return first;
}

public static int LeastCommonMultiple(int first, int second)
{
    if (first == 0 || second == 0) return 0;

    return Math.Abs(first / GreatestCommonDivisor(first, second) * second);
}
0
Spine napisał(a)

Java i C# to nie są takie w pełni obiektowe języki :P - http://pl.wikipedia.org/wiki/Programowanie_obiektowe#Elementarna_charakterystyka_popularnych_j.C4.99zyk.C3.B3w_obiektowych
Pewnych cech nie spełniają.

Tzn. których?

Wibowit napisał(a)

Język obiektowy to język w którym wszystko jest obiektem.

To jakaś nowa definicja? Język obiektowy to taki, w którym program definiuje się jako zbiór współpracujących ze sobą abstrakcyjnych bytów - obiektów, charakteryzujących się swoim stanem i możliwymi zachowaniami.

1

To jakaś nowa definicja? Język obiektowy to taki, w którym program definiuje się jako zbiór współpracujących ze sobą abstrakcyjnych bytów - obiektów, charakteryzujących się swoim stanem i możliwymi zachowaniami.

A więc implikuje to, że wystarczy do C wprowadzić lokalny namespace dla każdej struktury i już mamy język obiektowy. Czy kogoś to satysfakcjonuje?

0
Wibowit napisał(a)

A więc implikuje to, że wystarczy do C wprowadzić lokalny namespace dla każdej struktury i już mamy język obiektowy. Czy kogoś to satysfakcjonuje?

I ta struktura będzie miała swoje metody? No i potrzeba jeszcze umożliwić enkapsulację, dziedziczenie i polimorfizm.

No to jak ma działać coś w rodzaju: zwykły_int_obiekt + inteligentny_typ_obiekt? Jest to wywołanie operatora z klasy zwykły_int, która nic nie wie o klasie inteligentny_typ.

Ale inteligentny_typ wie o int, więc wystarczy sobie wszystko skonwertować:

using System;

namespace ConsoleApplication14
{
    class Program
    {
        static void Main(string[] args)
        {
            var x = 7 + new SuperInt(5);
            Console.WriteLine(x);
            var y = new SuperInt(-7) + 3;
            Console.WriteLine(y);
        }
    }

    class SuperInt
    {
        private int value;

        public int Value
        {
            get { return this.value; }
        }

        public SuperInt(int i)
        {
            this.value = i;
        }

        public static SuperInt operator +(SuperInt a, SuperInt b)
        {
            return new SuperInt(a.value + b.value);
        }

        public static implicit operator SuperInt(int a)
        {
            return new SuperInt(a);
        }

        public override string ToString()
        {
            return string.Format("SuperInt wartość: {0}", this.value);
        }
    }
}

@Spine, zminusowanie posta, nie jest odpowiedzią na pytanie w nim zawarte.

0

I ta struktura będzie miała swoje metody? No i potrzeba jeszcze umożliwić enkapsulację, dziedziczenie i polimorfizm.

Grasz nie fair. Oficjalnie to:

Object-oriented programming (OOP) is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction, encapsulation, messaging, modularity, polymorphism, and inheritance

A więc moja propozycja rozszerzenia C zamieni go w język obiektowy, z tym, że nie będzie miał nic z listy "may include".

0

Dlaczego używasz wersji algorytmu Euklidesa z odejmowaniem? Pomyśl co się stanie, gdy odpalisz algorytm dla a=2 200 000 000 i b=1.

0

No to jak ma działać coś w rodzaju: zwykły_int_obiekt + inteligentny_typ_obiekt? Jest to wywołanie operatora z klasy zwykły_int, która nic nie wie o klasie inteligentny_typ.
działa tak, że wcale nie jest to wywołanie operatora z klasy zwykły_int tylko z inteligentny_typ_obiekt. kompilator szuka pasującego operatora w obu klasach.

0

To fajnie bo okazuje się, że wygrzebałem pierwszy tom "Java Core" tylko jest to wydanie sprzed kilku lat, bo omawia wersję JDK 1.3. Jednak jeśli chodzi o podstawy języka to zmian w późniejszych JDK nie wprowadzono chyba jakichś zasadniczych?

Używam algorytmu Euklidesa z "podwójnym odejmowaniem", bo taki akurat pierwszy wpadł mi w ręce. Zapodałem ten program jako bazę porównawczą obu języków na poziomie "basic" a nie jako przyczynek do dyskusji o wyższości jednych algorytmów nad innymi.

Czytając Waszą dyskusję o zrobieniu z języka C języka obiektowego to może już istnieje coś takiego o nazwie Objective-C?

0

Objective-C jest hybrydą C i Smalltalka, tzn konkretnie to do C zostały dołączone elementy filozofii Smalltalka. Każdy prawidłowy kod C jest też prawidłowym kodem Objective-C (oczywiście implikacja w drugą stronę jest nieprawdziwa).

W Javie 1.5 było sporo zmian na poziomie języka, najważniejsze to oczywiście genericsy bez których kod wygląda po prostu brzydko i często nieczytelnie. W Javie 1.6 chyba nic, albo prawie nic. W Javie 1.7 dodano/ uproszczono kilka (niewiele) rzeczy. Na Javę 1.8 (planowo: przełom 2012/ 2013) planowane są np domknięcia, defender methods, kolejna iteracja Project Coin, etc

PS:
Jako, że Java 1.7 jest jeszcze świeża to pewnie książek jest mało do niej. Niemniej minimum to Java 1.5, lista (nie wiem czy wszystkich) nowości w Javie 1.5: Genericsy (dzięki temu mniej rzutowań), Adnotacje (bardzo ważne w Javie EE, ale w innych przypadkach też), Autoboxing (automatyczne konwersje np między Integer i int), Enumy (z dość dobrą funkcjonalnością), Foreach. Ponadto np wprowadzenie sztywnego modelu pamięci, tzn określenie zachowania VM-ki w przypadku programów wielowątkowych ze współdzieloną pamięcią.

0

No to niestety musiałbym zakupić najnowsze wydania obu tomów "Java Core" za jakieś 180 zł a tu za rok już Java 1.8 i znów być może książki do kosza. Nie wiecie czy postęp w rozwoju C# jest tak duży, że literatura dezaktualizuje się jeszcze szybciej niż przy Javie? Podobno .NET 4.5 wyjdzie w przyszłym roku wraz z VS11 a już wypuścili jej wersję zapoznawczą...chyba nie nadążają z tłumaczeniem na polski książek o najnowszych wersjach Javy i C# a już są dostępne ich nowsze wersje!

0

Na razie spokojnie wystarczy Java 1.5. Myślę, że co najmniej z rok czy dwa lata nikt z polskich pracodawców nie będzie wymagał Javy 1.7. Genericsy są generalnie chyba najtrudniejszym tematem w języku Java jak na razie (tzn do wersji Java 1.7), więc spokojnie możesz douczyć się nowości z The Java Tutorials. Niektórzy polscy "eksperci" Javy nie znają dobrze Javy 1.5, np metod generycznych, więc znając na wylot Javę 1.5 i tak będziesz do przodu.

Język C# rozwijał się do tej pory znacznie dynamiczniej niż język Java. Java 1.6 nie wprowadziła nic nowego do języka, a między Javą 1.5, a Javą 1.7 MS zdążył wypuścić C# 2.0, C# 3.0 i C# 4.0. Oracle obecnie inwestuje w rozwój Javy (ma w końcu więcej kapusty niż Sun miał), ale nie oczekuj, że pracodawcy się na to nagle rzucą i znajomość nowych wersji Javy będzie wielkim atutem. Nie ma jeszcze Javy EE opartej na Javie SE 7, nie ma też Androida z Javą 7, pewnie długo nie będzie, więc przestań trząść gaciami.

0

C#/.NET i teraz można z powodzeniem uczyć się z książek do wersji 2.0. Od strony języka nie pozna się od razu pewnych uproszczeń, które doszły w kolejnych wersjach, ale za to będzie się miało więcej pojęcia o tym, jak wszystko działa. Natomiast jeśli chodzi o kilka nowych technologii, to mając te podstawy można się ich już nauczyć bez większych problemów.

Zawsze jak wychodzi polskie tłumaczenie, to jest ono już nieaktualne. Bez angielskiego ani rusz.

0

OK, a czy można gdzieś kupić u nas bardziej aktualne książki po angielsku do Javy i C#?

1

Proponuję brytyjski Amazon. Przesyłka w przypadku przedmiotów kupowanych bezpośrednio na Amazonie bardzo często jest darmowa (przy zamówieniach powyżej 25 funtów), a w przypadku (bardzo często) tańszych ofert na Amazon Marketplace wynosi 4,02 funta za sztukę.

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