Fraktály - řešení problému – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Fraktály - řešení problému – Java – Fórum – Programujte.comFraktály - řešení problému – Java – Fórum – Programujte.com

 

GoliathL0
Newbie
24. 12. 2014   #1
-
0
-

Zdravím, 
včera jsem napsal program, který vytváří fraktálové řetězce. Program funguje, ale bylo třeba jedné drobné úpravy, která tak trochu narušila moje chápání běhu programů :D Mohli byste se podívat na tento kód (obě jeho verze) a potvrdit nebo vyvrátit to, jak jsem to pochopil ? Děkuju
public class fraktalytrida {
 // promenne:
    private String retezec1;
    private String retezec2;
    public int cykly;
    public char znak1;
    private char znak2 = '*';
    private static int loop =0;
    
 // konstruktor:
    public fraktalytrida(int cykly, String retezec1) {  
    this.cykly= cykly;
    this.retezec1 = retezec1;
    znak1 = this.retezec1.charAt(0);  
    this.findchars();
    
}
    //metody:
    public void findchars() {
        for (int j=1; j<retezec1.length();j++) {
         if (retezec1.charAt(j) != znak1) { 
        znak2 = retezec1.charAt(j); 
         break;
    }
} }
    public void zobrazfraktaly() {
        while (loop<cykly) {     
         for (int i=0; i<retezec1.length(); i++ ) {
             if (retezec1.charAt(i) == znak1) {
                 retezec2 += "" +znak1 + znak2;
             } else { retezec2 += "" +znak1;}
     }
         loop++;
         System.out.println(retezec2);
         retezec1 =retezec2;
         retezec2="";
    }
} }

Tohle je třída a tady je první, nefunkční verze programu, který ji využívá: 
public class pouzititridyfraktalu {
    public static void main (String [] args) {
        int poccykl;
        String pocatecnistring;
        Scanner vstup = new Scanner(System.in);
        System.out.print("urci pocet cyklu: ");
        poccykl = vstup.nextInt();
        System.out.println();
        System.out.print("zadej pocatecni sekvenci: ");
        pocatecnistring = vstup.nextLine();
        fraktalytrida A = new fraktalytrida(poccykl, pocatecnistring);
        A.zobrazfraktaly();
    }
}

Tato verze vyhodi tuto chybu : Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0


Zjistil jsem, že problém je v pořadí zadávání dat (poctu cyklu a pocatecni frekvence) a tak jsem to obrátil :
public class pouzititridyfraktalu {
    public static void main (String [] args) {
        int poccykl;
        String pocatecnistring;
        Scanner vstup = new Scanner(System.in); 
        
        System.out.print("zadej pocatecni sekvenci: ");
        pocatecnistring = vstup.nextLine();
        System.out.println();
        System.out.print("urci pocet cyklu: ");
        poccykl = vstup.nextInt();
        fraktalytrida A = new fraktalytrida(poccykl, pocatecnistring);
        A.zobrazfraktaly();
    }
}

Tato verze už funguje, ale jak už jsem říkal, trochu mě zmátlo, že program pracoval právě takhle, respektive nebyl schopný pracovat bez sekvence na prvním místě. Když jsem problem vyřešil prohozením zadávání dat, napadlo mě, že program nejspíš hned při zadání počtu cyklů provede část kódu třídy, uloží mezivýsledky a pokračuje k příjímaní dalších dat, které pak dosadí k mezivýsledkům. Původně jsem si ale myslel, že program postupuje po řádcích, a tak s vyhne tomu, aby pracoval bez kompletních dat. 
Podobný problem nastal, když jsem vyzkoušel upravit samotnou třídu a to takhle :
public class fraktalytrida {
 // promenne:
    private String retezec1;
    private String retezec2;
    public int cykly;
    public char znak1 =retezec1.charAt(0);  /* zde jsem určil hodnotu proměnné ještě před vytvořením instance (objektu)  /**
    private char znak2 = '*';
    private static int loop =0;
    
 // konstruktor:
    public fraktalytrida(int cykly, String retezec1) {  
    this.cykly= cykly;
    this.retezec1 = retezec1;
    this.findchars();
    
}
    //metody:
    public void findchars() {
        for (int j=1; j<retezec1.length();j++) {
         if (retezec1.charAt(j) != znak1) { 
        znak2 = retezec1.charAt(j); 
         break;
    }
} }
    public void zobrazfraktaly() {
        while (loop<cykly) {     
         for (int i=0; i<retezec1.length(); i++ ) {
             if (retezec1.charAt(i) == znak1) {
                 retezec2 += "" +znak1 + znak2;
             } else { retezec2 += "" +znak1;}
     }
         loop++;
         System.out.println(retezec2);
         retezec1 =retezec2;
         retezec2="";
    }
} }
Budu vděčný za jakékoliv připomínky a rady :) 
PS: veselé vánoce :D

Nahlásit jako SPAM
IP: 89.102.251.–
Flowy0
Věrný člen
24. 12. 2014   #2
-
0
-

neviem z akeho jazyka si prisiel (predpokladam ze nieco ako javascript) ale java ma vlastny scope pre kazdy blok ktory sa vytvori ... cize trieda ma scope tak isto metoda a vsetko co zabalis do zlozenych zatvoriek ... vo vysledku to mozes pouzit na docasne premenne ako napr cislo iteracie (na co je ale lepsie pouzit cyklus for ale ako chces ...) ... tak isto 'static' - v aktualnom kontexte je to zbytocne a moze ti to spravit len problemy

ak by si nazov triedy dal velkym pismenom tak tam nemusis davat suffix 'trieda' a bolo by to prehladnejsie

neviem presne aky sposob generovania fraktalu si si zvolil ale davat priamo do vstupu * ako funkcny znak neni velmi vhodne ... lepsie by to vyzeralo pouzit sprosty text a k nemu nejaky pattern alebo ten pattern implementovat priamo do triedy a spravit rozne triedy s jednym interface

ak s tymy charmi ides takto intenzivne pracovat tak by som nepouzival String ... je to sice dost rychle ale na tvoje potreby by si mal vhodnejsi array ... a mozno by som potom pouzil aj nejaku kolekciu ale to by asi nebolo nutne myslim ze array ma take veci ako vlozit na index a pod

Nahlásit jako SPAM
IP: 95.103.187.–
https://github.com/Flowy
GoliathL0
Newbie
24. 12. 2014   #3
-
0
-

Static jsem už odstranil, to byl jen pozůstatek původní úvahy. Chápu, ze java má v třídě Object a jejích podtřídách plno metod (tyto metody myslíš těmi scope, že ?), které by schopně nahradili většinu mého kódu, ale protože je tento program jen zkouškou mých dosavadních schopností a neučím se primárně Javu jako jazyk, ale hlavně myslet tím správným způsobem a programovat obecně (samozřejmě objektově, jak jen to s tím, co zatím umím jde :D ), tak je vlastní kód, myslím, vhodnější, než poskládat to všechno jako puzzle. Nicméně jsem udělal ještě pár úprav a posílám i kód, který pracuje s polem (tak napůl, no :D ) 
Tady je ta upravená verze, asi jen pro zajímavost: 

public class fraktalytrida {

 // promenne:
    public String retezec1;
    private String retezec2 ="";
    public int cykly;
    public char znak1;
    private char znak2 = '*';
    private  int loop =0;
    public String [][] Pole;
    private String POM ="";
    
    
 // konstruktor:
    public fraktalytrida(int cykly, String retezec1) {  
    this.cykly= cykly;
    this.retezec1 = retezec1;
    znak1 = retezec1.charAt(0); 
    this.findchars();
    Pole = new String [cykly+1][1];  
    Pole[0][0] = retezec1; 
}
    //metody:
    public void findchars() {
        for (int j=1; j<retezec1.length();j++) {
         if (retezec1.charAt(j) != znak1) { 
        znak2 = retezec1.charAt(j); 
         break;
    }
} }
    public void zobrazfraktaly() {
        while (loop<cykly) {     
         for (int i=0; i<retezec1.length(); i++ ) {
             if (retezec1.charAt(i) == znak1) {
                 retezec2 += ""+ znak1 + znak2;
             } else { retezec2 += "" +znak1;}
     }
         
         System.out.println(retezec2);
         loop++;
         Pole[loop][0] = retezec2;
         retezec1 =retezec2;
         retezec2="";
    }

         public String zobrazfraktal (int cislocyklu) {
             return this.Pole[cislocyklu][0];
         } 
         public String nahradznaky (char novyZnak1, char novyZnak2, int zdrojovycyklus) {
             
             for (int k =0; k<this.Pole[zdrojovycyklus][0].length(); k++) {
                 if (this.Pole[zdrojovycyklus][0].charAt(k)== znak1) {
                     POM += ""+ novyZnak1;
                 }
                 else { POM += "" + novyZnak2;
             } 
         } 
             return POM;
    }
}         

A její použití: 

public class pouzititridyfraktalu {
    public static void main (String [] args) {
      int poccykl;
      int zdrojovycyklus;
      char nahrada1;
      char nahrada2;
      String pocatecnistring;
        Scanner vstup = new Scanner(System.in); 
        
        System.out.print("zadej pocatecni sekvenci: ");
          pocatecnistring = vstup.nextLine();
        System.out.println();
        System.out.print("urci pocet cyklu: ");
          poccykl = vstup.nextInt();
             fraktalytrida A = new fraktalytrida(poccykl, pocatecnistring);
         A.zobrazfraktaly();
             fraktalytrida B = new fraktalytrida(poccykl, A.Pole[poccykl][0]); 
         B.zobrazfraktaly();
        System.out.print("zobraz jakykoliv z prave vytvorenych fraktalu (0 pro pocatecni sekvenci) : ");
        System.out.println( A.zobrazfraktal(vstup.nextInt()));
        System.out.print("Chces-li zamenit znaky za jine, zadej nejprve první: ");
          nahrada1 = vstup.next().charAt(0);
        System.out.println();
        System.out.print("a nyní druhý: ");
          nahrada2 = vstup.next().charAt(0);
        System.out.println("a konečně, zvol, z jakého cyklu chceš odvodit nový řetězec: ");
          zdrojovycyklus = vstup.nextInt();
           String novasekvence = A.nahradznaky(nahrada1, nahrada2,zdrojovycyklus);
             fraktalytrida C = new fraktalytrida(poccykl, novasekvence);
         C.zobrazfraktaly();
        
}
}
Chápu, že je to docela nepřehledné, a tak trochu skriptovací, ale to je jen proto, že kód nemá žádný určity smysl, jak už jsem říkal, je jen zkouškou toho, co umím.

Ještě k tomu znaku, který se vypíše namísto druhého chybějícího znaku :D Ta hvězdička tam samozřejmě nemusí být, původně jsem tam místo ní měl, myslím, ♦ :D . 

tady je tedy ten kód, který využívá pole (není objektový a pracuje jen s dvěma znaky (A a B) , protože jsem jej psal ještě před tím, který je výše). Je to podobné tomu, co jsi měl na mysli ?  : 

public class Fraktaly {
    public static void main(String [] args) {
       Scanner vstup = new Scanner(System.in);
        System.out.print("urci pocatecni sekvenci: ");
       String zacatek = vstup.nextLine();
        System.out.println();
        System.out.print("urci pocet cyklu: ");
       int pocetcyklu = vstup.nextInt();
       int loop=0;
       int Max;
       
     while (loop<pocetcyklu) {
       char [] znakypocatku = zacatek.toCharArray();
       Max = zacatek.length();
       zacatek= "";
       
        for (int i=0; i<Max; i++) {
          if (znakypocatku[i] == 'a' ){
              zacatek += "ab";
          } else {
              zacatek += "a";
        
       } }
       System.out.println(zacatek);
       loop++;
    }        
}
    

Nahlásit jako SPAM
IP: 89.102.251.–
GoliathL0
Newbie
25. 12. 2014   #4
-
0
-

Už vím, co je scope. Ano, vím , že s tím pracuju špatně, poznal jsem to po chybách, které v původní verzi nastaly a dostudoval si to. Děkuju za pomoc :)

Nahlásit jako SPAM
IP: 89.102.251.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 9 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý