Pomozte s programováním v Javě
- CZechBoY
- Master Level 9.5
- Příspěvky: 8813
- Registrován: srpen 08
- Bydliště: Brno
- Pohlaví:
- Stav:
Offline
- Kontakt:
Re: Pomozte s programováním v Javě
static můžeš volat když nemáš incializovanej ten objekt
tedy kodově: AritmetickyPrumerPole.soucet
tedy kodově: AritmetickyPrumerPole.soucet
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW
- Funstorm007
- Level 5
- Příspěvky: 2029
- Registrován: říjen 08
- Pohlaví:
- Stav:
Offline
Re: Pomozte s programováním v Javě
Zdravím, potřeboval bych opět pomoct. Plánem je vytvořit program, který dle určeného algoritmu bude počítat posloupnost, poté jí vypíše a pak ji vypíše ještě jednou ale seřazenou metodou InsertSort. Algoritmus je takový: Vezmu číslo, třeba 67 , které umocním na druhou. Vyjde mi číslo 4489. Z tohoto čísla vezmu první dvě cifry, tedy 44 a přičtu k němu 1. Mám tedy 45 a poté se celý algoritmus opakuje. Pak vyjde 21 no a pak vyjde opět 45 a zde algoritmus končí. Udělal jsem to takto:
ovšem chybí ta "stopka", která algoritmus zastaví ale ta bude sřejmě jinde.
Řazení mám též vyřešené:
Nakonec metoda main:
která ovšem není celá.
Nejvíc naprd je, že podmínkou je použití nejméně pěti metod. Takhle jsem zabil tři, další sežere program, ve kterém graficky tu posloupnost znázorním. Ale nevím, co bude v té páté. Potřebuju ovše aby program vůbec fungoval a jelikož ty pole pořád dost nepobírám, moc mi to nejde. hodila by se pomoc odborníka.
Kód: Vybrat vše
public static int vypocet(int x) {
int mocnina = (x * x);
if (mocnina >= 1000)
return (mocnina / 100) + 1;
else
return (mocnina / 10) + 1;
}
ovšem chybí ta "stopka", která algoritmus zastaví ale ta bude sřejmě jinde.
Řazení mám též vyřešené:
Kód: Vybrat vše
public static void seradPosloupnost(int[] pole) {
for (int k = 1; k < pole.length; k++) {
int pom = pole[k];
int i;
// posun od posledniho prvku
for (i = k - 1; i >= 0 && pole[i] > pom; i--) {
pole[i + 1] = pole[i];
}
pole[i + 1] = pom;
}
}
Nakonec metoda main:
Kód: Vybrat vše
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Zadej dvouciferné číslo: ");
int x = sc.nextInt();
která ovšem není celá.
Nejvíc naprd je, že podmínkou je použití nejméně pěti metod. Takhle jsem zabil tři, další sežere program, ve kterém graficky tu posloupnost znázorním. Ale nevím, co bude v té páté. Potřebuju ovše aby program vůbec fungoval a jelikož ty pole pořád dost nepobírám, moc mi to nejde. hodila by se pomoc odborníka.
Re: Pomozte s programováním v Javě
To první dvojčíslí bych řešil trochu jinak:
Pokud ti tedy extrémně nezáleží na rychlosti, je to trochu pomalejší, ale univerzálnější.
Ta stopka bude muset být tak odkud se ten vypocet() volá, takže někde v hlavním cyklu v main(). Chápu to správně, že vytváření posloupnosti se ukončí, když vyjde číslo které už v ní bylo? Potom bych udělal cyklus, který bude jednu po druhé umísťovat do indexovaného pole, a pokaždé volat test jestli už v něm není, Ten test bude další metoda
Něco jako:
Kód: Vybrat vše
int mocnina=(x*x);
while (mocnina>100)
mocnina=mocnina/10;
Pokud ti tedy extrémně nezáleží na rychlosti, je to trochu pomalejší, ale univerzálnější.
Ta stopka bude muset být tak odkud se ten vypocet() volá, takže někde v hlavním cyklu v main(). Chápu to správně, že vytváření posloupnosti se ukončí, když vyjde číslo které už v ní bylo? Potom bych udělal cyklus, který bude jednu po druhé umísťovat do indexovaného pole, a pokaždé volat test jestli už v něm není, Ten test bude další metoda

Kód: Vybrat vše
int vyskyt(int hodnota, int pole, int velikost)
{
int i;
for (i=0;i<velikost;++i)
if (hodnota=pole[i]
return 1;
return 0;
}
"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
- Funstorm007
- Level 5
- Příspěvky: 2029
- Registrován: říjen 08
- Pohlaví:
- Stav:
Offline
Re: Pomozte s programováním v Javě
Ano, chápeš to dobře. Tvůj algoritmus ale nevezme z 4-ciferného čísla první dvě ale tři. Proto ta podmínka. Když zadám dvojciferné číslo, pohybujeme se na intervalu <100;9801> proto dvě podmínky. Na rychlosti samosebou záleží, vzhledem k tomu, že to bude dělat i graf...
Ten výpočet zavolám do metody main. Nejsem si jistý, jestli vytvořit metodu pro neseřazené pole zvlášť nebo to hodit do mainu. To pole se pak seřadí v metodě seradPosloupnost, tu zavolám opět do mainu a vypíšu. Asi bude lepší pole vytvořit a naplnit v tom mainu ne? Ovšem nevím, jak to udělat aby bylo pole velké podle toho, kolik v něm bude hodnot právě z toho algoritmu. Bylo by to asi nějak takhle:
ovšem zde je velikost pole pevná a to 20. To nechci ale nevím jak to udělat aby bylo pole "pohyblivé". Ale stejně se mi pole naplní jen první vypočítanou hodnotou. Takže po zadaní čísla 67 mi to vyplivne 20 [45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45]. Tkhle něja by to mělo vypadat akorát jen s čísli a velikostí pole podle toho algoritmu...
Ten výpočet zavolám do metody main. Nejsem si jistý, jestli vytvořit metodu pro neseřazené pole zvlášť nebo to hodit do mainu. To pole se pak seřadí v metodě seradPosloupnost, tu zavolám opět do mainu a vypíšu. Asi bude lepší pole vytvořit a naplnit v tom mainu ne? Ovšem nevím, jak to udělat aby bylo pole velké podle toho, kolik v něm bude hodnot právě z toho algoritmu. Bylo by to asi nějak takhle:
Kód: Vybrat vše
int[] pole = new int[20];
// naplneni
for (int i = 0; i < pole.length; i++) {
pole[i] = vypocet(x);
}
ovšem zde je velikost pole pevná a to 20. To nechci ale nevím jak to udělat aby bylo pole "pohyblivé". Ale stejně se mi pole naplní jen první vypočítanou hodnotou. Takže po zadaní čísla 67 mi to vyplivne 20 [45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45]. Tkhle něja by to mělo vypadat akorát jen s čísli a velikostí pole podle toho algoritmu...
Re: Pomozte s programováním v Javě
Pardon, chybička se vloudila, ta podmínka propustí i číslo 100, takže tam mělo být:
To už vrátí první dvě číslice z každého čísla většího než 99 (jen do INT_MAX, samozřejmě). Dalo by se to udělat velmi elegantně (pro matematiky) přes logaritmy, ale bylo by to mnohem pomalejší.
Jestli ti jde o to namrskat tam co nejvíc metod, zkus třeba volat ošetřený vstup z main(): x=dvouciferne();
Když si takhle "odložíš jinam" každou činnost, tak ti v tom main() nakonec zůstanou jen čtyři příkazy a o všechno ostatní se postarají jednotlivé metody (jen od oka bych jich tam udělal minimálně sedm):
Pokud bysme to dotáhli do extrému, tak by v main() mohl zůstat jen jeden jediný příkaz:
return udelej_ukol();
Kód: Vybrat vše
while (mocnina>=100)
Jestli ti jde o to namrskat tam co nejvíc metod, zkus třeba volat ošetřený vstup z main(): x=dvouciferne();
Kód: Vybrat vše
int dvouciferne(void)
{
int cislo;
do {
printf("Zadej dvouciferné číslo: "); // napíše pokyn
while (scanf("%d",&cislo)!=1) // dokud není načteno číslo ze vstupu
getchar(); // odstraní neplatný znak a zkusí to znovu
cislo=abs(cislo); // převede na kladné
} while (cislo<10 || cislo>99); // není-li dvouciferné, požaduje nový vstup
return cislo;
}
Když si takhle "odložíš jinam" každou činnost, tak ti v tom main() nakonec zůstanou jen čtyři příkazy a o všechno ostatní se postarají jednotlivé metody (jen od oka bych jich tam udělal minimálně sedm):
Kód: Vybrat vše
int main(void)
{
int x,pocet,pole[1000];
x=dvouciferne(); // vstupní hodnota
pocet=vypocitat(pole,x); // vytvoření sekvence a naplnění pole, vrací počet prvků
seradit(pole,pocet); // seřadí pole
zobrazit(pole,pocet); // zobrazí výsledky
return 0;
}
Pokud bysme to dotáhli do extrému, tak by v main() mohl zůstat jen jeden jediný příkaz:
return udelej_ukol();

"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
- Funstorm007
- Level 5
- Příspěvky: 2029
- Registrován: říjen 08
- Pohlaví:
- Stav:
Offline
Re: Pomozte s programováním v Javě
Jasně, s tím algoritmem je to ale nějaké divné. Je tam sice podmínka, že číslo musí být větší než 99 ale tys mě sřejmě nepochopil. Tys napsal podmínku, že když bude čílo rovno nebo větší než 100, vrátí mocnitu zadaného čísla vydělenou deseti. Takže zaprvé, chybí ti tam ještě ta +1 ale to je detail. Ovšem co se stane, když zadáš číslo 80? Mocnina je 6400/10 = ?
640
Už mě chápeš. Ta moje podmínka tam je proto aby brala v potaz tří i čtyř-ciferná čísla. Jasně, můžu vše nacpat do metod, to není problém ale pro mě se to pak ještě víc komplikuje a pak mi to nefunguje. Pořád tu ale visí několik nejasných z minulého dotazu. Tak nějak dám ty metody dokupy ale co se pole týče mam hlavu jako meloun. Zkusím to nějak slátat a dát to sem celé ať to vidíš...


Re: Pomozte s programováním v Javě
O metodách mi povídej, viděl jsi jak jsem na to koukal já
Aspoň něco málo jsem zatím pochopil, už mám i učebnici, ale dřív než za rok se Javu dostatečně dobře nenaučím. Takže zatím aspoň v Céčku, s vynecháním věcí které v Javě nejsou 
Na to přičtení jedničky jsem zapomněl, ale pozor, po vypočtení mocniny tam není if ale while, takže to není podmínka ale cyklus, který dělí deseti, dokud vypočtené číslo není menší než 100. Takže finální verze, jak mi teď běhá:
Když zadám počáteční hodnotu 80, tak mi vyjde: 64 40 16 25 62 38 14 19 36 12 14...
S přičítáním jedničky to bude: 65 43 19 37 14 20 41 17 29 85 73 54 30 91 83 69 48 24 58 34 12 15 23 53 29...
Mimochodem, ono to fungovalo i s tím (x>100), protože prostě neexistuje celé číslo, jehož umocněním by ses dostal do rozsahu 1000..1009
A 10000 ti také nemohlo vyjít, protože by musela být vstupní hodnota 100, jenže ta se tam nemohla nijak dostat.
Ono to dělení na menší celky (dekompozice) program právě naopak zpřehledňuje a zjednodušuje, v podstatě si ho musíš postupně rozdělit na tak malé kousky, jaké jsi schopen řešit jednotlivě. Ne mít jednu velkou hromadu instrukcí, ale jednotlivé stavební kostky jako v Legu. Na tohle je zrovna výborný ten Karel
Někdy si musíš udělat čas, a koukneme se na ty moje domečky.
V Javě je dekompozice tvoření jednotlivých metod, které udělají každá svůj kousek práce...
A asi největší výhoda je ta, že každou tu metodu můžeš zvlášť odzkoušet, takže se v nich hledají chyby snáze a rychleji.
Extrémní příklad:
Dejme tomu že v načítání můžeš udělat deset programových chyb, dalších deset ve výpočtu, deset v řazení a deset v zobrazení.
Když to budeš mít všechno nahamtané v jedné metodě, tak máš 10000 možností, proč ti nefunguje (10x10x10x10).
Zatímco když budeš hledat která ze čtyř metod nepracuje správně, budeš mít jen 40 možností (10+10+10+10).


Na to přičtení jedničky jsem zapomněl, ale pozor, po vypočtení mocniny tam není if ale while, takže to není podmínka ale cyklus, který dělí deseti, dokud vypočtené číslo není menší než 100. Takže finální verze, jak mi teď běhá:
Kód: Vybrat vše
x=x*x;
while (x>=100)
x=x/10;
x=x+1;
Když zadám počáteční hodnotu 80, tak mi vyjde: 64 40 16 25 62 38 14 19 36 12 14...
S přičítáním jedničky to bude: 65 43 19 37 14 20 41 17 29 85 73 54 30 91 83 69 48 24 58 34 12 15 23 53 29...
Mimochodem, ono to fungovalo i s tím (x>100), protože prostě neexistuje celé číslo, jehož umocněním by ses dostal do rozsahu 1000..1009

Ono to dělení na menší celky (dekompozice) program právě naopak zpřehledňuje a zjednodušuje, v podstatě si ho musíš postupně rozdělit na tak malé kousky, jaké jsi schopen řešit jednotlivě. Ne mít jednu velkou hromadu instrukcí, ale jednotlivé stavební kostky jako v Legu. Na tohle je zrovna výborný ten Karel

V Javě je dekompozice tvoření jednotlivých metod, které udělají každá svůj kousek práce...
A asi největší výhoda je ta, že každou tu metodu můžeš zvlášť odzkoušet, takže se v nich hledají chyby snáze a rychleji.
Extrémní příklad:
Dejme tomu že v načítání můžeš udělat deset programových chyb, dalších deset ve výpočtu, deset v řazení a deset v zobrazení.
Když to budeš mít všechno nahamtané v jedné metodě, tak máš 10000 možností, proč ti nefunguje (10x10x10x10).
Zatímco když budeš hledat která ze čtyř metod nepracuje správně, budeš mít jen 40 možností (10+10+10+10).
"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
- Funstorm007
- Level 5
- Příspěvky: 2029
- Registrován: říjen 08
- Pohlaví:
- Stav:
Offline
Re: Pomozte s programováním v Javě
No ono to ošetření vstupu také není zlý nápad ale jsou tam věci, které java prostě nerozchodí a já nevím, co přesně dělají a tak je nemůžu ani nijak nahradit. Takže já budu muset celý ten výpočet hodit do cyklu aby to furt a furt počítalo... Ano, když to dělá to co to dělá pak ti to fungovat bude. Já si to vykládal trošku jinak... měla by tam ale být nějaká podmínka, která cyklus zastaví když bude mít číslo požadované dvě cifry ne?
Re: Pomozte s programováním v Javě
Ten vstup si musíš udělat podle svého jak to Java umí, nakonec bys také mohl sám načítat jednotlivé zadané znaky a testovat jestli jsou to číslice, číslo vynásobit deseti a číslici přičíst... Na to by sis mohl udělat další metodu, prakticky si napsat vlastní scanf()
Já tam využívám toho že scanf() vrací počet načtených hodnot, takže když se na vstupu objeví nějaký nečíselný znak, nechá ho tam, do proměnné nic neuloží a vrátí nulu. Já ten zlobivý znak načtu a zahodím, aby nepřekážel, a zkouším to znovu do té doby, dokud mi scanf() konečně nevrátí jedničku.
Ty bys to asi musel řešit přes nějaké odchytávání chyb, nevím jestli i v Javě je try a catch nebo je to tam ještě jinak...
Ale pokud budeš předpokládat že se tam objeví jen čísla, stačí abys ve vstupní metodě ohlídal že bylo v rozmezí 10..99, takže nic z tohohle nepotřebuješ, jen jeden cyklus do s podmínkou na konci.
Ta podmínka co zastaví cyklus je právě to while, česky dokud. V Karlovi je tohle:
To znamená že Karel bude dělat KROK, KROK, KROK... tak dlouho, DOKUD nebude stát před zdí. Tam se cyklus ukončí a program pokračuje dalšími příkazy.
While je cyklus s podmínkou na začátku, takže se testuje ještě než se do něj poprvé vstoupí! Tím pádem, když Karel stojí přímo u zdi, neudělá vůbec nic.
Kdyby tam byl cyklus s podmínkou na konci, udělal by nejdřív krok a teprve pak by se podíval jestli nedošel ke zdi, takže by si mohl pěkně natlouct žárovku! To se hodí třeba pro testování vstupních hodnot, ale ne pro takovouhle rizikovou činnost.
Ale zpátky k programu.
Takže to naplnění pole by mohlo proběhnout takhle:
V C-jazycích je for obdobou příkazu while, jen na rozdíl od něj dělá ještě pár věcí navíc. Malinko přehlednější a delší ekvivalent s příkazem while by tedy vypadal takhle:
Cyklus dělá tohle:
0. nuluje se počet (tohle do cyklu vlastně nepatří, musí se to udělat ještě před jeho rozběhem),
1. otestuje jestli se hodnota v poli už nevyskytuje,
2. vloží hodnotu do pole,
3. nechá si vypočítat další následující,
4. inkrementuje počet položek,
a skočí na bod 1, kde se opět rozhoduje jestli ta nově vypočítaná hodnota v poli ještě není. Kdy ne, cyklus se opakuje, když ano, jede se dál.
Předpokládám že v poli má být uložená i ta zadaná počáteční hodnota, pokud ne, stačí před začátek cyklu přidat x=dalsi(x); což je metoda, která z čísla co jí pošleš vypočítá a vrátí další hodnotu v pořadí, a ta se hned uloží do x :
I to by samozřejmě šlo napsat jako for, dokonce se to dá všechno naprasit do samotné deklarace bez těla:
for (cislo=cislo*cislo; cislo>=100; cislo=cislo/10);
return cislo+1;
Takhle teda ne, když se v tomhle sekneš o jediné písmenko, tak tu chybu už v životě nenajdeš!
A ještě by neškodilo ukázat jak se zjistí jestli to číslo v poli už je, nebo není:
Pohledem do hlavičky zjistíš, že se parametry předávají v pořadí hledané číslo, ukazatel na pole, počet položek v poli.
Další výhoda toho rozdělení na jednotlivé podmetody je ta, že si pěkně procvičíš jak se jim správně předávají pole ke zpracování
Pokud bys za každou cenu trval na tom že to musíš mít na jedné kupě v main(), tak bys tam musel napsat něco takového:
Čili třináct řádků místo čtyř, a další dvě proměnné navíc, ve kterých se v main() musíš orientovat
"Když programátor neví jak dál, přidá další proměnnou." - mám pocit že to bylo v Murphyho zákonech, a na ty je dobré dávat zatraceně bacha.
Ten poslední příklad jsem netestoval, takže tam může být nějaká chybka. Ono je to už moc dlouhé a nepřehledné, není na první pohled vidět co se vlastně kde děje...
Takhle se programovalo v BASICu, říkalo se tomu špagetový kód. Program jako talíř zamíchaných špaget, kde nepoznáš který konec které patří
Jen pro zajímavost jsem si vypočítal pár statistik. Říká se že "gram analýzy nahradí kilogram ladění", takže neuškodí si úlohu předem trochu rozpitvat, aby člověk věděl kam se v ní až může dostat, a čím nemá cenu se zabývat
Takže nejdřív mapa, ze kterého čísla vyjde jaké:
V ní jsou krásně vidět dvě vzestupné řady, ta první (do čísla 31) vychází z třímístných výsledků, druhá (od 32) ze čtyřmístných
Zajímavé je také, která čísla s jakou pravděpodobností vlastně můžou vyjít:
A nakonec, jak dlouhé sekvence vycházejí ze všech možných vstupů:
Z toho vyplývá že pole[100] je zbytečně velké, když nejdelší možná sekvence má do prvního opakování jen 27 čísel, takže pokud se do sekvence bude počítat i vstupní hodnota, tak úplně stačí alokovat pole[28] 
Měnit velikost pole za běhu jde, jen musíš přijít na to jaká metoda to v Javě dělá. V Céčku je obdoba toho new funkce dynamické alokace paměti malloc(), a pro změnu velikosti alokovaného bloku je realloc().
Ale asi bych to zatím nekomplikoval, vzhledem k tomu že je jen pár desítek možností bych použil statické pole.
Proč je jich tak málo? Z každého počátečního čísla se výpočet dřív nebo později dostane do nekonečné smyčky. V daném rozsahu jsou tři možnosti:
1. Nejkratší smyčka je číslo 99, které dá vždy výsledek 99.
2. Druhá smyčka jsou čísla 21<->45, která se střídají mezi sebou. Do téhle smyčky spadne i číslo 67.
3. Všechna ostatní čísla se nejpozději po několika skocích dostanou do poslední smyčky, která má šestnáct členů:

Já tam využívám toho že scanf() vrací počet načtených hodnot, takže když se na vstupu objeví nějaký nečíselný znak, nechá ho tam, do proměnné nic neuloží a vrátí nulu. Já ten zlobivý znak načtu a zahodím, aby nepřekážel, a zkouším to znovu do té doby, dokud mi scanf() konečně nevrátí jedničku.
Ty bys to asi musel řešit přes nějaké odchytávání chyb, nevím jestli i v Javě je try a catch nebo je to tam ještě jinak...
Ale pokud budeš předpokládat že se tam objeví jen čísla, stačí abys ve vstupní metodě ohlídal že bylo v rozmezí 10..99, takže nic z tohohle nepotřebuješ, jen jeden cyklus do s podmínkou na konci.
Ta podmínka co zastaví cyklus je právě to while, česky dokud. V Karlovi je tohle:
Kód: Vybrat vše
DOKUD NENÍ ZEĎ
KROK
KONEC
While je cyklus s podmínkou na začátku, takže se testuje ještě než se do něj poprvé vstoupí! Tím pádem, když Karel stojí přímo u zdi, neudělá vůbec nic.
Kdyby tam byl cyklus s podmínkou na konci, udělal by nejdřív krok a teprve pak by se podíval jestli nedošel ke zdi, takže by si mohl pěkně natlouct žárovku! To se hodí třeba pro testování vstupních hodnot, ale ne pro takovouhle rizikovou činnost.
Ale zpátky k programu.
Takže to naplnění pole by mohlo proběhnout takhle:
Kód: Vybrat vše
x=dvouciferne();
for (pocet=0; !vyskyt(x,pole,pocet); ++pocet)
{
pole[pocet]=x;
x=dalsi(x);
}
V C-jazycích je for obdobou příkazu while, jen na rozdíl od něj dělá ještě pár věcí navíc. Malinko přehlednější a delší ekvivalent s příkazem while by tedy vypadal takhle:
Kód: Vybrat vše
pocet=0;
while (!vyskyt(x,pole,pocet))
{
pole[pocet]=x;
x=dalsi(x);
++pocet;
}
Cyklus dělá tohle:
0. nuluje se počet (tohle do cyklu vlastně nepatří, musí se to udělat ještě před jeho rozběhem),
1. otestuje jestli se hodnota v poli už nevyskytuje,
2. vloží hodnotu do pole,
3. nechá si vypočítat další následující,
4. inkrementuje počet položek,
a skočí na bod 1, kde se opět rozhoduje jestli ta nově vypočítaná hodnota v poli ještě není. Kdy ne, cyklus se opakuje, když ano, jede se dál.
Předpokládám že v poli má být uložená i ta zadaná počáteční hodnota, pokud ne, stačí před začátek cyklu přidat x=dalsi(x); což je metoda, která z čísla co jí pošleš vypočítá a vrátí další hodnotu v pořadí, a ta se hned uloží do x :
Kód: Vybrat vše
int dalsi(int cislo)
{
cislo=cislo*cislo;
while (cislo>=100)
cislo=cislo/10;
cislo=cislo+1;
return cislo;
}
for (cislo=cislo*cislo; cislo>=100; cislo=cislo/10);
return cislo+1;
Takhle teda ne, když se v tomhle sekneš o jediné písmenko, tak tu chybu už v životě nenajdeš!
A ještě by neškodilo ukázat jak se zjistí jestli to číslo v poli už je, nebo není:
Kód: Vybrat vše
int vyskyt(int cislo,int pole[],int pocet)
{
int i;
for (i=0;i<pocet;++i)
if (cislo==pole[i])
return 1;
return 0;
}
Další výhoda toho rozdělení na jednotlivé podmetody je ta, že si pěkně procvičíš jak se jim správně předávají pole ke zpracování

Pokud bys za každou cenu trval na tom že to musíš mít na jedné kupě v main(), tak bys tam musel napsat něco takového:
Kód: Vybrat vše
x=dvouciferne();
pocet=0;
vyskyt=0;
while (!vyskyt)
{
pole[pocet]=x;
x=x*x;
while (x>=100)
x=x/10;
x=x+1;
++pocet;
for (i=0; i<pocet; ++i)
if (x==pole[i])
vyskyt=1;
}

"Když programátor neví jak dál, přidá další proměnnou." - mám pocit že to bylo v Murphyho zákonech, a na ty je dobré dávat zatraceně bacha.
Ten poslední příklad jsem netestoval, takže tam může být nějaká chybka. Ono je to už moc dlouhé a nepřehledné, není na první pohled vidět co se vlastně kde děje...
Takhle se programovalo v BASICu, říkalo se tomu špagetový kód. Program jako talíř zamíchaných špaget, kde nepoznáš který konec které patří

Jen pro zajímavost jsem si vypočítal pár statistik. Říká se že "gram analýzy nahradí kilogram ladění", takže neuškodí si úlohu předem trochu rozpitvat, aby člověk věděl kam se v ní až může dostat, a čím nemá cenu se zabývat

Takže nejdřív mapa, ze kterého čísla vyjde jaké:
Kód: Vybrat vše
0 1 2 3 4 5 6 7 8 9
+------------------------------+
10 |11 13 15 17 20 23 26 29 33 37 |
20 |41 45 49 53 58 63 68 73 79 85 |
30 |91 97 11 11 12 13 13 14 15 16 |
40 |17 17 18 19 20 21 22 23 24 25 |
50 |26 27 28 29 30 31 32 33 34 35 |
60 |37 38 39 40 41 43 44 45 47 48 |
70 |50 51 52 54 55 57 58 60 61 63 |
80 |65 66 68 69 71 73 74 76 78 80 |
90 |82 83 85 87 89 91 93 95 97 99 |
+------------------------------+

Zajímavé je také, která čísla s jakou pravděpodobností vlastně můžou vyjít:
Kód: Vybrat vše
0 1 2 3 4 5 6 7 8 9
+------------------------------+
10 | 0 3 1 3 1 2 1 3 1 1 |
20 | 2 1 1 2 1 1 2 1 1 2 |
30 | 1 1 1 2 1 1 0 2 1 1 |
40 | 1 2 0 1 1 2 0 1 1 1 |
50 | 1 1 1 1 1 1 0 1 2 0 |
60 | 1 1 0 2 0 1 1 0 2 1 |
70 | 0 1 0 2 1 0 1 0 1 1 |
80 | 1 0 1 1 0 2 0 1 0 1 |
90 | 0 2 0 1 0 1 0 2 0 1 |
+------------------------------+
použitých: 68
A nakonec, jak dlouhé sekvence vycházejí ze všech možných vstupů:
Kód: Vybrat vše
0 1 2 3 4 5 6 7 8 9
+------------------------------+
10 |20 19 16 18 20 16 20 17 21 22 |
20 |19 2 22 16 16 20 19 17 21 16 |
30 |16 19 20 20 16 19 19 21 17 21 |
40 |18 18 22 23 20 2 23 17 16 21 |
50 |20 18 22 16 16 20 21 21 16 20 |
60 |22 18 22 19 19 24 21 3 18 16 |
70 |21 19 23 16 21 22 17 23 19 20 |
80 |25 22 19 16 20 16 22 18 20 26 |
90 |20 16 17 19 27 17 20 18 19 1 |
+------------------------------+
nejdelší: 27

Měnit velikost pole za běhu jde, jen musíš přijít na to jaká metoda to v Javě dělá. V Céčku je obdoba toho new funkce dynamické alokace paměti malloc(), a pro změnu velikosti alokovaného bloku je realloc().
Ale asi bych to zatím nekomplikoval, vzhledem k tomu že je jen pár desítek možností bych použil statické pole.
Proč je jich tak málo? Z každého počátečního čísla se výpočet dřív nebo později dostane do nekonečné smyčky. V daném rozsahu jsou tři možnosti:
1. Nejkratší smyčka je číslo 99, které dá vždy výsledek 99.
2. Druhá smyčka jsou čísla 21<->45, která se střídají mezi sebou. Do téhle smyčky spadne i číslo 67.
3. Všechna ostatní čísla se nejpozději po několika skocích dostanou do poslední smyčky, která má šestnáct členů:
Kód: Vybrat vše
+-> 12 -> 15 -> 23 -> 53 -> 29 -> 85 -> 73 -> 54 -> 30 -> 91 -> 83 -> 69 -> 48 -> 24 -> 58 -> 34 -+
| |
+-------------------------------------------------------------------------------------------------+
"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
Re: Pomozte s programováním v Javě
Tak jak jsi s tím programem daleko? Já jsem si včera dvě hodiny listoval v té učebnici a už mi to chodí
Akorát jsem musel udělat pár "strašně velkých" změn, abych z Céčka vyrobil Javu, například u zjištění výskytu čísla v poli:
bylo potřeba přehodit [] v hlavičce před název proměnné:
Ono to sice může být stejně jako v C až za názvem, ale prý je to nejavovské... No hlavně že to to pole zpracuje, víc mě nezajímá.
A také jsem ještě připsal všude to public static a obalil to jednou velkou třídou, protože čím víc zbytečného kódu, tím víc macho programátoři jsme, žejo
Třeba u metody výpočtu dalšího čísla v pořadí stačilo jen přidat tahle dvě slova, víc jsem na něj nemák'.
Jenom to načítání vstupu mi dalo trochu zabrat, ten Scanner už snad fakt blběji vymyslet nešel, zlaté scanf()!
Hlavní program mám takhle, celkem mi to dalo na sedm metod včetně main():
Ta deklarace pole je také zbytečně komplikovaná (holt si borci v Sunu ušetřili práci na interpretu a oddře to za ně programátor aplikace), zatímco v Céčku stačí zadat kompilátoru
int pole[100];
tak tady musím i na staticé pole v každém případě zavolat dynamickou alokaci
int[] pole=new int[100];

Potřeboval bych teď ještě vědět jak má vypadat ten graf (nastojato, naležato, úprava...), zatím to vypisuji jen lineárně:

Akorát jsem musel udělat pár "strašně velkých" změn, abych z Céčka vyrobil Javu, například u zjištění výskytu čísla v poli:
Kód: Vybrat vše
int vyskyt(int cislo,int pole[],int pocet)
{
int i;
for (i=0;i<pocet;++i)
if (cislo==pole[i])
return 1;
return 0;
}
Kód: Vybrat vše
public static int vyskyt(int cislo,int[] pole,int pocet)
{
int i;
for (i=0;i<pocet;++i)
if (cislo==pole[i])
return 1;
return 0;
}
A také jsem ještě připsal všude to public static a obalil to jednou velkou třídou, protože čím víc zbytečného kódu, tím víc macho programátoři jsme, žejo

Jenom to načítání vstupu mi dalo trochu zabrat, ten Scanner už snad fakt blběji vymyslet nešel, zlaté scanf()!
Hlavní program mám takhle, celkem mi to dalo na sedm metod včetně main():
Kód: Vybrat vše
public static void main (String[] args)
{
int x,pocet;
int[] pole=new int[100];
x=dvouciferne();
pocet=naplnit(x,pole);
vypsat(pole,pocet);
seradit(pole,pocet);
vypsat(pole,pocet);
}
Ta deklarace pole je také zbytečně komplikovaná (holt si borci v Sunu ušetřili práci na interpretu a oddře to za ně programátor aplikace), zatímco v Céčku stačí zadat kompilátoru
int pole[100];
tak tady musím i na staticé pole v každém případě zavolat dynamickou alokaci
int[] pole=new int[100];

Potřeboval bych teď ještě vědět jak má vypadat ten graf (nastojato, naležato, úprava...), zatím to vypisuji jen lineárně:
Kód: Vybrat vše
Zadej dvouciferné číslo: 94
94 89 80 65 43 19 37 14 20 41 17 29 85 73 54 30 91 83 69 48 24 58 34 12 15 23 53
12 14 15 17 19 20 23 24 29 30 34 37 41 43 48 53 54 58 65 69 73 80 83 85 89 91 94
"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
- Funstorm007
- Level 5
- Příspěvky: 2029
- Registrován: říjen 08
- Pohlaví:
- Stav:
Offline
Re: Pomozte s programováním v Javě
J, takhle se načítají vesměs všechny proměnné.
Ten výskyt se dá napsat i zkráceně takto:
Neboli proměnnou int vytvoříš přímo ve for cyklu. Přijde mi to elegantnější. :)
Takže ty sis udělal metodu i pro ten vstup?
Já mám main zatím takto:
Ovšem nejsem si jist tím naplněním. Respektivě to nefunguje, protože nevím, k čemu patří proměnná pocet.
Jinak, jestli ten for cyklus chápu správně. Vytvořím proměnnou i , která se rovná nule; i se nesmí rovnat vyskyt(x,pole,pocet) což je vlasně metoda pro hledání jestli už tam to číslo nebylo; a nakonec i++ aby i o jednu vyrostlo. ALE, nejsem si jist právě tím i =! vyskyt(x,pole,pocet).
Jo a pro výpis použij příkaz:
Pro seřazení pole jsem použil metodu:
A její výpis v mainu:
Graf necháme až nakonec. Je tu ještě jedna malá komplikace. Program musí fungovat pro vstup z klávesnice, to v případě, že bude na příkazové řídce nebude žádný parametr, no a pak musí ještě fungovat pro vstup ze souboru s tím, že tím parametrem bude název stupního souboru. Jako vždy, ošetření není nutné, soubor bude existovat a data v něm budou zadána správně. Data ve vstupním souboru budou dvouciferná čísla, zadaná každé na jedné řádce. Tedy:
No a na výstupu to pro každé číslo vyplivne Neseřazenou a seřazenou posloupnost.
Ten výskyt se dá napsat i zkráceně takto:
Kód: Vybrat vše
public static int vyskyt(int cislo,int[] pole,int pocet) {
for (int i=0;i<pocet;++i)
if (cislo==pole[i])
return 1;
return 0;
}
Neboli proměnnou int vytvoříš přímo ve for cyklu. Přijde mi to elegantnější. :)
Takže ty sis udělal metodu i pro ten vstup?
Já mám main zatím takto:
Kód: Vybrat vše
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
System.out.println(dalsi(x));
int[] pole = new int[20];
for (int i = 0; i =! vyskyt(x,pole,pocet); i++) {
pole[i] = x;
x = dalsi(x);
}
System.out.println(pole.length + " " + Arrays.toString(pole));
seradPosloupnost(pole);
System.out.println(pole.length + " " + Arrays.toString(pole));
}
Ovšem nejsem si jist tím naplněním. Respektivě to nefunguje, protože nevím, k čemu patří proměnná pocet.

Jo a pro výpis použij příkaz:
Kód: Vybrat vše
System.out.println(pole.length + " " + Arrays.toString(pole));
Pro seřazení pole jsem použil metodu:
Kód: Vybrat vše
public static void serazeni(int[] pole) {
for (int k = 1; k < pole.length; k++) {
int pom = pole[k];
int i;
for (i = k - 1; i >= 0 && pole[i] > pom; i--) {
pole[i + 1] = pole[i];
}
pole[i + 1] = pom;
}
}
A její výpis v mainu:
Kód: Vybrat vše
serazeni(pole);
System.out.println(pole.length + " " + Arrays.toString(pole));
Graf necháme až nakonec. Je tu ještě jedna malá komplikace. Program musí fungovat pro vstup z klávesnice, to v případě, že bude na příkazové řídce nebude žádný parametr, no a pak musí ještě fungovat pro vstup ze souboru s tím, že tím parametrem bude název stupního souboru. Jako vždy, ošetření není nutné, soubor bude existovat a data v něm budou zadána správně. Data ve vstupním souboru budou dvouciferná čísla, zadaná každé na jedné řádce. Tedy:
Kód: Vybrat vše
55
45
86
48
No a na výstupu to pro každé číslo vyplivne Neseřazenou a seřazenou posloupnost.
Naposledy upravil(a) Funstorm007 dne 03 pro 2011 16:16, celkem upraveno 1 x.
Re: Pomozte s programováním v Javě
To není zkrácené, to je jen znepřehledněné
Mě zase přijde elegantnější mít všechny proměnné deklarované v jednom bloku na začátku metody, abych je měl pěkně na očích. Nesvědčí o kvalitách programátora když plácne proměnnou tam kde se mu to zrovna hodí, to by ses mohl na nějaké deklarace rovnou vykašlat a používat BASIC nebo FORTRAN, které to dělaly automaticky - překladače vytvořily proměnnou v místě jejího prvního použití, a rovnou do ní uložily nulu. A nebo také ne, záleželo na dialektu...
Mimochodem, v C se dají proměnné deklarovat zvlášť pro každý blok, takže například můžu udělat vlastní sadu proměnných pro každý vnořený cyklus for()
Metodu jsem si udělal úplně na všechno, tak jak jsem ti psal předtím, prostě systém Lego. Mapa vnořování vypadá takhle:
Ten vstup nakonec hlídá jen rozsah zadaného čísla, víc chyb jsem neřešil:
Jak s tím grafem? Stačí sloupečky pro vzestupnou křivku nebo se má nějak znázornit výskyt na ose? Na to by se také dala přilepit nějaká pomocná metoda...

Mě zase přijde elegantnější mít všechny proměnné deklarované v jednom bloku na začátku metody, abych je měl pěkně na očích. Nesvědčí o kvalitách programátora když plácne proměnnou tam kde se mu to zrovna hodí, to by ses mohl na nějaké deklarace rovnou vykašlat a používat BASIC nebo FORTRAN, které to dělaly automaticky - překladače vytvořily proměnnou v místě jejího prvního použití, a rovnou do ní uložily nulu. A nebo také ne, záleželo na dialektu...
Mimochodem, v C se dají proměnné deklarovat zvlášť pro každý blok, takže například můžu udělat vlastní sadu proměnných pro každý vnořený cyklus for()

Metodu jsem si udělal úplně na všechno, tak jak jsem ti psal předtím, prostě systém Lego. Mapa vnořování vypadá takhle:
Kód: Vybrat vše
main -+- dvouciferne
|
+- naplnit -+- vyskyt
| |
| +- dalsi
|
+- vypsat
|
+- seradit
Ten vstup nakonec hlídá jen rozsah zadaného čísla, víc chyb jsem neřešil:
Kód: Vybrat vše
public static int dvouciferne()
{
int cislo;
Scanner scan = new Scanner(System.in);
do {
System.out.print("Zadej dvouciferné číslo: ");
cislo=scan.nextInt();
cislo=Math.abs(cislo);
} while (cislo<10 || cislo>99);
return cislo;
}
Jak s tím grafem? Stačí sloupečky pro vzestupnou křivku nebo se má nějak znázornit výskyt na ose? Na to by se také dala přilepit nějaká pomocná metoda...
"Král Lávra má dlouhé oslí uši, král je ušatec!
(pravil K. H. Borovský o cenzuře internetu)
(pravil K. H. Borovský o cenzuře internetu)
Zpět na “Programování a tvorba webu”
Kdo je online
Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 3 hosti