Diskuze: Prosím o pomoc-string/pole...
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.


Zdeněk Pavlátka:31.1.2014 10:09
Co takhle používat ikonku "Vložit zdrojový kód"?
=>
import java.util.Scanner;
import java.util.Arrays;
public class Příklady {
public static void main(String[] args) {
Scanner sc= new Scanner(System.in, "Windows-1250");
String vstup=sc.nextLine();
String[] částix=vstup.split(" ");
int operátor,čísloVzákladním1=0,čísloVzákladním2=0,výsledekZákl;
String znamínko=částix[1];
částix[0]=new StringBuffer(částix[0]).reverse().toString();
částix[2]=new StringBuffer(částix[2]).reverse().toString();
for (int j = 0; j <= částix[0].length(); j++) {
String gh,gg;
gh=""+částix[0].charAt(j*2);
gg=""+částix[0].charAt(j*2+1);
int gg1=Integer.parseInt(gg);
int gh1=Integer.parseInt(gh);
operátor=gg1*gh1;
čísloVzákladním1=čísloVzákladním1+operátor;
operátor=0;
}
for (int j = 0; j <= částix[2].length(); j++) {
String gh=""+částix[2].charAt(j*2);
String gg=""+částix[2].charAt(j*2+1);
int gg1=Integer.parseInt(gg);
int gh1=Integer.parseInt(gh);
operátor=gg1*gh1;
čísloVzákladním2=čísloVzákladním2+operátor;
operátor=0;
}
výsledekZákl=čísloVzákladním1+čísloVzákladním2;
System.out.print(výsledekZákl);
}
}
Zdeněk Pavlátka:31.1.2014 10:10
V názvech proměnných se diakritika nepoužívá...
Každý ověřovací příklad má tvar a op b (jednotlivé části
oddělené mezerou), kde a a b jsou dvě čísla ve zkráceném zápisu,
přičemž pro jejich hodnotu h platí 0 ≤ h(a), h(b) ≤ 263 – 1
a op je jedna z množiny operací +, –, *, /, kde dělení je celočíselné.
Vše spočívá ve zkráceném zápisu čísel. Ten je založen na faktu, že
posloupnost po sobě jdoucích stejných číslic se nahradí počtem
totožných číslic a číslicí samotnou. Například číslo 5555888
zapíšeme jako 4538 (čtyři pětky a tři osmičky). Je-li za sebou více než
devět totožných číslic, zápis zkracujeme po devíti číslicích (pokud to
jde) postupně zleva doprava. Například číslo 11111111111111111 zapíšeme
jako 9181.
Příklad výstupu
10 + 11 = 11
12345678 - 11335577 = 9171
13 * 82 = 86
19 / 12 = 14
edit:
PS: díky, už nebudu používat diakritiku
Ahoj-asi si to děláš zbytečně složitý-jenom tak z hlavy pár
tipů.
1.Dvě stejný transformace nad a, b to si samo říká o vytvoření
samostatné metody do které pošleš jako vstup tu proměnnou jako parametr a
vrátí ti přetransformovanou hodnotu.V tý samostatný metodě se ti to i líp
odladí.
2.Pak tam máš trochu hokej poněvadž používáš dvě různé
proměnné,operátor a znamínko-ale asi jima myslíš to samé-tedy znak
operace ze zadání,tedy to co más uložené v částix[1], je to tak? Čili,
odstraň to co s nima dál provádíš a použij switch( částix[1]) : case
'+': vysl=cislo1+cislo2;break
case '*': vysl=cislo1*cislo2;break atd..
3. Jak vyplývá ze zadání, tak nestačí konečný výsledek jen
vytisknout,ale musíš zase provést zpětnou transformaci do zkráceného
tvaru
4. A ještě je v zadání tohle "h(a) ,h(b) ≤ 263− čili budeš
muset použít proměnné typu long aby se to tam vešlo.
Stačí tohle trochu k nakopnutí?
mkub:31.1.2014 18:41
v kazdom pripade sa snaz v zapisu kodu nepouzivat diakritiku (vynimku tvoria komentare a text, co sa ma zobrazit), najlepsdie je pouzivat na nazvy premien, metod, funkcii, tried anglicke pomenovania (napr. namiesto "vstup" pouzi "input", resp. iny vyraz, co by oznacovalo obsah premennej), lebo parsery jazykov casto mavaju s diakritikou problemy
Pokud bych mohl, tak bych se ještě rád zeptal, proč mi v tomto programu nefunguje procházení stingu po charu. (Má za úkol z řetězce vzít číslo a to převést na římské. Pak vypsat kolik,kterých znaků se v římském číslu vyskytuje...)
package příklady;
import java.util.Scanner;
public class Příklady {
public static void main(String[] args) {
String strvysledek;
String nula="";
Scanner sc= new Scanner(System.in, "Windows-1250");
String ii= sc.nextLine();
int pocetOP=Integer.parseInt(ii);
String vstup[] = new String[pocetOP+1];
String TempkVypisu[]=new String[pocetOP];
for (int i = 0; i < pocetOP; i++) {
vstup[i]=sc.nextLine();
}
for ( int i=0; i <= pocetOP; i++) {
vstup[i] = vstup[i].substring(4, 8);
int cislo = Integer.parseInt(vstup[i]);
String riman[] = { "M", "XM", "CM", "D", "XD", "CD", "C", "XC",
"L", "XL", "X", "IX", "V", "IV", "I" };
int arab[] = { 1000, 990, 900, 500, 490, 400, 100, 90, 50, 40, 10,
9, 5, 4, 1 };
String vysledek="";
while (cislo > 0) {
for (int j = 0; j < arab.length; j++) {
if ((cislo - arab[j]) >= 0) {
cislo =cislo-arab[j];
vysledek=vysledek+(riman[j]);
break;
}
}
}
TempkVypisu[i]=vysledek;
//počet jednotlivých znaků
int M=0,C=0,D=0,L=0,X=0,V=0,I=0;
String m= "M",c="C",l="L",x="X",v="V",t="I",d="D";
for (int j = 0; j < pocetOP; j++) {
strvysledek=TempkVypisu[j];
for (char v1: strvysledek.toCharArray())
{if (strvysledek.contains(String.valueOf(v1)))
{
M++;
}
else
if (strvysledek.contains(String.valueOf(v1)))
{
C++;
}
else
if (strvysledek.contains(String.valueOf(v1)))
{
L++;
}
else
if (strvysledek.contains(String.valueOf(v1)))
{
X++;
}
else
if (strvysledek.contains(String.valueOf(v1)))
{
I++;
}
else
if (strvysledek.contains(String.valueOf(v1)))
{
V++;
}
else
if (strvysledek.contains(String.valueOf(v1)))
{
D++;
}
else{}
}
System.out.printf("%d%d%d%d%d%d%d", I, V, X, L, C, D, M);
I=0;
M=0;
C=0;
D=0;
L=0;
X=0;
V=0;
}
}
}
}
petrph:2.2.2014 8:31
Ahoj-hádám že to procházení stringu po charu asi není jedinej problém poněvadž ti to už předtím padá na 2 chyby při běhu v programu. A to
- v tom řádku for ( int i=0; i <= pocetOP; i++)
nesmí být i <= pocetOP ale jenom i < pocetOP, jinak posledním cyklem překročíš hranici pole a program spadne
- máš nějakej dobrej důvod proč tam máš ten řádek
vstup[i] = vstup[i].substring(4, ; ??
Popřemýšlej o tom, poněvadž tak jak je tak ti generuje dvě chyby, jednak
funkční a jednak běhovou(když zadáš kratší číslo). Teprve když ho
vymažeš tak ti první půlka programu začne fungovat.
Taková drobná rada, zkus ze začátku programovat trochu víc defenzivněji.
Rozdělit si kód do několika metod, ověřit si zda každá funguje
samostatně správně. Když píšeš kód který řeší víc úkolů (viz
zde-napřed převést do římských, pak počítat výskyty znaků), psát
postupně, napřed první úkol, ověřit si že funguje,pak pokračovat v
dopisování dalšího.
Čili, tohle předem,teď se ti konečně podívám na to procházení stringu
po charu
petrph:2.2.2014 11:43
A teď k tomu procházení procházení stringu po charu-tak jak to máš
napsaný ti to asi fungovat nebude. Všimni se máš ve všech větvích if
stejnou podmínku if (strvysledek.contains(String.valueOf(v1)))
ale pokaždé je pak jiný příkaz - C++;L++ atd..
Asi tak nejjednodušší je použít switch jako minule:
for (int i=0;i<strvysledek.length();i++)
{
char v1=strvysledek.charAt(i);
switch(v1)
{case 'M':M++;break;
case 'C':C++;break;
case 'L':L++;break;
case 'V':V++;break;
case 'I':I++;break;
case 'D':D++;break;
}
}
No a pak už jen stačí to spojit dohromady. Hlavně si dej pozor, jak jsem si
všim tak asi v zadání je možnost vkládání několika čísel pod sebou.
Které pak zpracováváš v cyklu se pocetOP]. jestli můžu v kódu vyčíst
tak napřed všechny převádíš všechny do řím do pole TempkVypisu[i].
A pak tohle pole zpracováš v samostatném cyklu pro výpočet počtu
znaků.
Čili, zkontroluj si jestli máš ten přkaz TempkVypisu[i]=vysledek; ve
správńym cyklu....
Jinak hodně štěstí....;)ať to doladíš na tommhle se nejlíp naučíš
základy jazyka..
}
Nakonec jsem to vyřešil takto:
import java.util.Scanner;
public class priklady22 {
public static void main(String[] args)
{
int M=0,C=0,D=0,L=0,X=0,V=0,I=0;
String strvysledek;
Scanner sc= new Scanner(System.in);
String ii= sc.nextLine();
int pocetOP=Integer.parseInt(ii);
String vstup[] = new String[pocetOP];
String TempkVypisu[]=new String[pocetOP];
for (int i = 0; i < pocetOP; i++)
{
vstup[i]=sc.nextLine();
String []Tempvypisu= new String [pocetOP];
}
for ( int i=0; i < pocetOP; i++)
{
vstup[i] = vstup[i].substring(4, 8);
int cislo = Integer.parseInt(vstup[i]);
String riman[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
int arab[] = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
String vysledek="";
while (cislo > 0)
{
for (int j = 0; j < arab.length; j++)
{
if ((cislo - arab[j]) >= 0)
{
cislo =cislo-arab[j];
vysledek=vysledek+(riman[j]);
break;
}
}
}
TempkVypisu[i]=vysledek;
for (int j = 0; j < pocetOP; j++)
{
strvysledek=TempkVypisu[j];
strvysledek=strvysledek+" ";
char VeVysledku[]= new char [14];
VeVysledku[0]=strvysledek.charAt(0);
VeVysledku[1]=strvysledek.charAt(1);
VeVysledku[2]=strvysledek.charAt(2);
VeVysledku[3]=strvysledek.charAt(3);
VeVysledku[4]=strvysledek.charAt(4);
VeVysledku[5]=strvysledek.charAt(5);
VeVysledku[6]=strvysledek.charAt(6);
VeVysledku[7]=strvysledek.charAt(7);
VeVysledku[8]=strvysledek.charAt(8);
VeVysledku[9]=strvysledek.charAt(9);
VeVysledku[10]=strvysledek.charAt(10);
VeVysledku[11]=strvysledek.charAt(11);
VeVysledku[12]=strvysledek.charAt(12);
VeVysledku[13]=strvysledek.charAt(13);
for (int k = 0; k < 14; k++)
{
if (VeVysledku[k] =='M')
{
M++;
}
else
if (VeVysledku[k] =='L')
{
L++;
}
else
if (VeVysledku[k] =='C')
{
C++;
}
else
if (VeVysledku[k] =='X')
{
X++;
}
else
if (VeVysledku[k] =='I')
{
I++;
}
else
if (VeVysledku[k] =='V')
{
V++;
}
else
if (VeVysledku[k] =='D')
{
D++;
}
else{}
}
String Ii,Vv,Xx,Ll,Mm,Cc,Dd;
Ii=Integer.toString(I);
Vv=Integer.toString(V);
Xx=Integer.toString(X);
Ll=Integer.toString(L);
Mm=Integer.toString(M);
Cc=Integer.toString(C);
Dd=Integer.toString(D);
TempkVypisu[j]=Ii+Vv+Xx+Ll+Cc+Dd+Mm;
Ii="";
Vv="";
Cc="";
Xx="";
Ll="";
Dd="";
Mm="";
}
I=0;
V=0;
X=0;
L=0;
C=0;
D=0;
M=0;
System.out.println(TempkVypisu[pocetOP - 1]);
}
}
}
A měl bych dotaz..., jak se moje výstypy liší od požadovaného?
https://pilsprog.fav.zcu.cz/ulohy/1413.pdf
MrPabloz:3.2.2014 21:49
Jak se tak dívám, máš tam docela dost blbostí.
for (int i = 0; i < pocetOP; i++)
{
vstup[i]=sc.nextLine();
String []Tempvypisu= new String [pocetOP];
}
Co tam dělá tenhle řádek : String []Tempvypisu= new String [pocetOP];
Absolutní blbost. Jak můžeš vytvářet ve foru String pořád dokola ?
zbytečné mrhání paměti.
String riman[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
int arab[] = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
Místo tohohle bych použil HashMap a rozhodně to deklaroval před forem, ne ve foru pokaždé znova.
Místo toho mega složitého ifu bych použil jednoduchý switch
switch(veVysledku[k])
**{
case 'M':
M++;
break;
...
atd. až po I
}**
Nezkoušel sem to, ael už jen od pohledu vidím plno věcí co by se dali
předělat a hned by to bylo lepší, ještě na tom zapracuj
Opravil jsem to dle rad, ale stále mi to hlásí, že "chybné řešení". To nejdůležitější totiš pro mě je zjistit proč a v čem se to liší od požadovaných výsledků, ikdyž vypadají stejně. Nicméně děkuji za rady, určitě to je lepší.
import java.util.Scanner;
public class priklady22 {
public static void main(String[] args)
{
int M=0,C=0,D=0,L=0,X=0,V=0,I=0;
String strvysledek;
Scanner sc= new Scanner(System.in);
String ii= sc.nextLine();
int pocetOP=Integer.parseInt(ii);
String vstup[] = new String[pocetOP];
String TempkVypisu[]=new String[pocetOP];
String riman[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
int arab[] = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
for (int i = 0; i < pocetOP; i++){
vstup[i]=sc.nextLine();}
for ( int i=0; i < pocetOP; i++){
vstup[i] = vstup[i].substring(4, 8);
int cislo = Integer.parseInt(vstup[i]);
String vysledek="";
while (cislo > 0){
for (int j = 0; j < arab.length; j++){
if ((cislo - arab[j]) >= 0){
cislo =cislo-arab[j];
vysledek=vysledek+(riman[j]);
break;}}}
TempkVypisu[i]=vysledek;
for (int j = 0; j < pocetOP; j++){
strvysledek=TempkVypisu[j];
strvysledek=strvysledek+" ";
char VeVysledku[]= new char [14];
VeVysledku[0]=strvysledek.charAt(0);
VeVysledku[1]=strvysledek.charAt(1);
VeVysledku[2]=strvysledek.charAt(2);
VeVysledku[3]=strvysledek.charAt(3);
VeVysledku[4]=strvysledek.charAt(4);
VeVysledku[5]=strvysledek.charAt(5);
VeVysledku[6]=strvysledek.charAt(6);
VeVysledku[7]=strvysledek.charAt(7);
VeVysledku[8]=strvysledek.charAt(8);
VeVysledku[9]=strvysledek.charAt(9);
VeVysledku[10]=strvysledek.charAt(10);
VeVysledku[11]=strvysledek.charAt(11);
VeVysledku[12]=strvysledek.charAt(12);
VeVysledku[13]=strvysledek.charAt(13);
for (int k = 0; k < 14; k++){
switch (VeVysledku[k]){
case 'M':M++;
break;
case 'C':C++;
break;
case 'D':D++;
break;
case 'L':L++;
break;
case 'X':X++;
break;
case 'V':V++;
break;
case 'I':I++;
break;}}
String Ii,Vv,Xx,Ll,Mm,Cc,Dd;
Ii=Integer.toString(I);
Vv=Integer.toString(V);
Xx=Integer.toString(X);
Ll=Integer.toString(L);
Mm=Integer.toString(M);
Cc=Integer.toString(C);
Dd=Integer.toString(D);
TempkVypisu[j]=Ii+Vv+Xx+Ll+Cc+Dd+Mm;
Ii="";
Vv="";
Cc="";
Xx="";
Ll="";
Dd="";
Mm="";}
I=0;
V=0;
X=0;
L=0;
C=0;
D=0;
M=0;
System.out.println(TempkVypisu[pocetOP - 1]);}}}
Jan Vargovský:3.2.2014 23:25
char VeVysledku[]= new char [14];
VeVysledku[0]=strvysledek.charAt(0);
VeVysledku[1]=strvysledek.charAt(1);
VeVysledku[2]=strvysledek.charAt(2);
VeVysledku[3]=strvysledek.charAt(3);
VeVysledku[4]=strvysledek.charAt(4);
VeVysledku[5]=strvysledek.charAt(5);
VeVysledku[6]=strvysledek.charAt(6);
VeVysledku[7]=strvysledek.charAt(7);
VeVysledku[8]=strvysledek.charAt(8);
VeVysledku[9]=strvysledek.charAt(9);
VeVysledku[10]=strvysledek.charAt(10);
VeVysledku[11]=strvysledek.charAt(11);
VeVysledku[12]=strvysledek.charAt(12);
VeVysledku[13]=strvysledek.charAt(13);
Co je toto? Řekl bych, že v Jave jde taky přistupovat ke stringu jako k poli znaků. Minimálně bys mohl přímo volat
for (int k = 0; k < 14; k++){
switch (strvysledek.charAt(k)){
case 'M':M++;
break;
case 'C':C++;
break;
case 'D':D++;
break;
case 'L':L++;
break;
case 'X':X++;
break;
case 'V':V++;
break;
case 'I':I++;
break;}}
Jde a máš pravdu, je to
rozhodně hezčí řešení, nicméně to neovlivní výstup programu a můj
hlavní problém není to, co je uvnitř a jak šíleně se k výsledku dostanu,
ale jestli jsou výsledky správné(zadání https://pilsprog.fav.zcu.cz/ulohy/1413.pdf ). Vážím si
Tvé odpovědi, ale není to úplně přesně to, s čím bych potřeboval
pomoct.
MrPabloz:4.2.2014 10:10
A13B0009P
A13B1369K
B02A9999F
1010000
1021301
10102010
tzn. skus ošetřit vstupy, kdy ti to přesáhne dané hodnoty a tak.
PS: co ti to kontroluje? učitel nebo nějaký školní webový program ? (npř.
progtest) ?
//sory za triple-post, prosím o smazání těch dvou dalších příspěvku
Přepracoval jsem to pomocí OOP, že by se to snad mohlo umoudřit, ale vždy se mi to zastaví u "
poleKvypisu[i]=prevod.HRiman;
package hesla_obj1.pkg0;
import java.util.Scanner;
public class Hesla_Obj10 {
public static void main(String[] args) {
Scanner sc=new Scanner (System.in);
Prevod prevod = new Prevod();
prevod.op=sc.nextInt();
String []poleKvypisu=new String [prevod.op];
sc.nextLine();
for (int i = 0; i<prevod.op;i++) {
prevod.vstup = sc.nextLine();
prevod.NaCislo1();
prevod.NaRiman();
prevod.HodnotaRiman();
poleKvypisu[i]=prevod.hRiman;
}
for (int i = 0; i < prevod.op; i++) {
System.out.format("%s%n",poleKvypisu[i]);
}}}
package hesla_obj1.pkg0;
public class Prevod {
public String vstup,scislo,vRiman,hRiman;
public int cPred,op;
public int NaCislo1(){
scislo=vstup.substring(4, 8);
return cPred=Integer.parseInt(scislo);}
public String NaRiman(){
String riman[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
int arab[] = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
while (cPred > 0)
{
for (int i = 0; i < arab.length; i++)
{
if ((cPred - arab[i]) >= 0)
{
cPred =cPred-arab[i];
vRiman=vRiman+(riman[i]);
break;}}}
return vRiman+" "; }
public String HodnotaRiman(){
int I=0,V=0,X=0,L=0,C=0,D=0,M=0;
char[]VslRimanChar=new char[15];
for (int i = 0; i < 15; i++) {
VslRimanChar[i]=vRiman.charAt(i);
switch (VslRimanChar[i])
{
case 'M':
M++;
break;
case 'C':
C++;
break;
case 'D':
D++;
break;
case 'L':
L++;
break;
case 'X':
X++;
break;
case 'V':
V++;
break;
case 'I':
I++;
break;
case ' ':
break;
}}
String Ii,Vv,Xx,Ll,Mm,Cc,Dd;
Ii=Integer.toString(I);
Vv=Integer.toString(V);
Xx=Integer.toString(X);
Ll=Integer.toString(L);
Mm=Integer.toString(M);
Cc=Integer.toString(C);
Dd=Integer.toString(D);
hRiman=Ii+Vv+Xx+Ll+Cc+Dd+Mm;
return hRiman;
} }
Netušite proč?
Zobrazeno 20 zpráv z 20.