Nadesłany przez Krzysztof Kwiatkowski, 05 marca 2006 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
Kod_Graya.java:
// Generowanie podzbiorów zbioru n-elementowego za pomocą Kodu Grey’a. // www.algorytm.org // (c) 2006 Krzysztof Kwiatkowski, implementacja Java Tomasz Lubinski public class Kod_Graya { private static int n; /** * @param args */ public static void main(String[] args) { String[] imie; int[] w; System.out.println("Ilosc elementow (wartosc większa od 2): "); n = Console.readInt("?"); if (n < 2) { System.out.println("Zła liczba elementów"); return; } imie = new String[n]; int[] v = new int[n]; for (int i=0; i<n; i++) { System.out.println("Podaj imie " + (i+1)); imie[i] = Console.readString(); } w = GenerujWektorPrzejsc(n); for (int i=0; i<n; i++) v[i] = 0; for (int i=0; i<w.length; i++) { if (v[w[i]-1] == 0) v[w[i]-1] = 1; else v[w[i]-1] = 0; System.out.println(""); System.out.print((i+1) + ": "); for (int j=0; j<n; j++) if (v[j] == 1) System.out.print(imie[j] + ", "); } } /** * * Funkcja przeksztalcajaca liczbe calkowita * na zapis dwojkowy. Wynikiem jest wektor * * Pierwsza liczba w zwracanym wektorze to ilosc elementow * obliczonej liczby. * */ private int[] ZmianaPodstawy2Wektor(int pods, int liczba) { int v[] = new int[n]; int w[] = new int[n]; int i, j; if (liczba < 0) { System.out.println("Liczba mniejsza od 0. Nie obsluguje"); return null; } if (liczba == 0) { v[0] = 1; v[1] = 0; return v; } i = 0; while (liczba > 0) { i++; v[i] = liczba % pods; liczba = liczba / pods; } for (j=1; j<i; j++) w[j] = v[i-j+2]; w[0] = i-1; return w; } /** * * Ta funkcja przeszktalca liczbe z systemu o podstawie pods zapisanej * w wektorze, do liczby w systemie dziesietnym. * Podana liczba w wektorze v, musi miec specyficzna postac, tzn. * pierwszy element tablicy to liczba mowiaca ile cyfr ma liczba * do przeksztalcenia. * * np. v=[3,1,1,0]; (czyli w systemie dziesietnym jest to = 6) * */ private int ZmianaPodstwy2Liczba(int pods, int[] v) { int suma, i, j; suma = 0; j = 0; for (i=v[0]+1; i>1; i--) { suma = (int) (suma+(v[i]*Math.pow(pods,j))); j++; } return suma; } /** * * Funkcja na podstawie indexu generuje slowo Grey'a * */ private int[] IndeksNaSlowoGreya(int i, int ile_m) { int g[] = new int[ile_m]; int h[] = new int[ile_m]; int j,z; for (j=0; j<h.length; j++) h[j] = 0; g = ZmianaPodstawy2Wektor(2,i); if (ile_m<g[1]) { System.out.println("Za mala liczba miejsc na ktorych nalezy przedstawic liczbe."); System.out.println("Wychodze z funkcji."); return null; } for (i=2; i<=g[1]+1; i++) h[ile_m-g[1]+i-1] = g[i]; for (i=1; i<=ile_m; i++) { z = ile_m-i+1; g[ile_m-i+1] = (h[z]+h[z-1]) % 2; } for (j=0; j<h.length; j++) h[j] = 0; h[1] = ile_m; for (i=2; i<=ile_m+1; i++) h[i]=g[i-1]; return h; } /** * * Ta funkcja zwraca numer indeksu dla pobranego slowa Graya. * * Parametry * v [in] - macierzy wyjsciowa zawierajaca w pierwszym elemencie * warosc ile_m oraz w ile_m kolejnych elementow * szukane slowo Grey'a * * n [out] - szukany indeks slowa Gray'a * */ private int SlowoGrayaNaIndeks(int v[]) { int b[] = new int[v.length + 1]; int i, j, suma; b[1] = v[1]; for (j=v[1]+1; j>=2; j--) { suma = 0; for (i=j; i>=2; i--) suma = suma+v[i]; b[j] = suma % 2; } return ZmianaPodstwy2Liczba(2,b); } /** * * Funkcja ta generuje wektor przejsc korzystajac z tablic. * Wektor przejsc zawiera numery bitow, ktore ulegaja zmianie w generowaniu * kolejnych slow kodu Grey'a. * Podawany argument n oraz dlugosc rozpatrywanych slow w kodzie Grey'a, * maja taka sama wartosc. * * n [in] - dlugosc wektora wejsciowego * Tout [out] - wygenerowany wektor przejsc * * UWAGA: * Pierwszy element w wektorze wyjsciowym zawiera dlugosc tego wygenerowanego * wektora. */ private static int[] GenerujWektorPrzejsc(int n) { int i,k,Twsk,j; boolean flag; int v[] = new int[n]; int warunekZak; // inicjowanie wartosci poczatkowych i = 1; Twsk = 0; flag = true; warunekZak = (int) (Math.pow(2,n)-1); int Tout[] = new int[warunekZak]; for (j=0; j<n; j++) v[j] = j; while (flag) { if (v[i]>0) { Tout[Twsk] = v[i]; Twsk++; v[i] = 0; for (k=i-1; k>=1; k--) v[k] = k; i = 1; } else i++; // obliczamy wartosci do polowy, poniewaz wartosci w ciagu sa takie same // jak wartosci w obliczonym ciagu ale od tylu. // TO DO: dla n= 2 ten program nie dziala. Powodem jest ten warunek ponizej. // Powoduje on wystepowanie petli nieskonczonej if (Twsk ==((warunekZak) / 2 )) flag = false; } // wartosc 2^(n-1) jest zawsze rowna n (jest to srodek ciagu, miejsce // w kodzie Grey'a gdzie pierwsza wartosc kodu zmienia sie z 0 na 1) Tout[Twsk] = n; j = 1; for (i=Twsk+1; i<warunekZak; i++) { Tout[i] = Tout[Twsk-j]; j++; } return Tout; } }