Jednořádková kalkulačka – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jednořádková kalkulačka – Java – Fórum – Programujte.comJednořádková kalkulačka – Java – Fórum – Programujte.com

 

Hoffik0
Návštěvník
27. 12. 2010   #1
-
0
-

Dobrý den, mám problém s kalkulačkou. Vstupní data mají být zadávána do jednoho řádku, mají se vyloučit mezery a provést výpočet, nejspíš po stisku klávesy enter. Příklad může být "jakkoliv" dlouhý, použíté pouze základní operace (+,-,*,/), zatím neřeším žádnou prioritu.

Nějak nemohu přijít na to proč mi to hází chybu ohledně převodu Stringu (vstupu od uživatele). Přikládám radši celý kód, předem díky za jakékoliv poznámky :-).

public class Main {


static Scanner sc = new Scanner(System.in);
static String vstup;
static String[] poleOperatoru;
static String[] poleCisel;
static int vysledek;



public static void main(String[] args) {
System.out.println("Zadejte příklad: ");
vstup = sc.nextLine();
vstup = vstup.replaceAll("[a-z] s","");
poleCisel = vstup.split("[0-9]");
poleOperatoru = vstup.split("[*,/,-,+]");
provedOperaci();

}

private static int provedOperaci()
{

for (int i = 0; i < vstup.length(); i++)
{
int prvniCislo = Integer.parseInt(poleCisel[i]);
int dalsiCislo = Integer.parseInt(poleCisel[i++]);
String operator = poleOperatoru[i];
char[] operatorChar = operator.toCharArray();

switch (operatorChar[i])
{
case '+' : vysledek = prvniCislo + dalsiCislo; break;
case '-' : vysledek = prvniCislo - dalsiCislo; break;
case '*' : vysledek = prvniCislo * dalsiCislo; break;
case '/' : vysledek = prvniCislo / dalsiCislo; break;
}
}
return vysledek;
}


private void zobrazVysledek()
{
System.out.println("Pozadovany vysledek je: " + vysledek);
}


}

Nahlásit jako SPAM
IP: 82.150.166.–
"If you enter this world knowing you are loved and you leave this world knowing the same, then everything that happens in between can be dealt with." - Michael Jackson
liborb
~ Redaktor
+18
Guru
28. 12. 2010   #2
-
0
-

Pomocí split se rozdělují řetězce, kde uvádíš, čím jsou rozděleny. Pokud uděláš

vstup.split("[*,/,-,+]")
, tak nedostaneš pole operátorů, ale pole čísel, protože dělíš podle operátoru. Takže je to jednak obráceně a pak také, když uděláš rozdělení podle čísel, tak musíš počítat s tím, že první operátor bude prázdný řetězec, protože rozdělením
1+
podle čísla dostaneš 2 řetězce, a to prázdný "" a "+". To bude asi ten problém, proč ti to hází chybu převodu.

A další chyba bude nejspíše v té funkci. Máš tam cyklus na délku řetězce a pomocí toho indexu přistupuješ i do těch polí, které ovšem budou mnohonásobně kratší, takže tam máš zaděláno na další dotaz :)

Nahlásit jako SPAM
IP: 78.80.52.–
Hoffik0
Návštěvník
28. 12. 2010   #3
-
0
-

To liborb : Zdravím :-) Děkuji za připomínky. Snad mi tu metodu pomohl zpravit další cyklus, nyní vypadá takhle:

 private static int provedOperaci()

{

for (int i = 0; i < vstup.length(); i++)
{
int prvniCislo = Integer.parseInt(poleCisel[i]);
int dalsiCislo = Integer.parseInt(poleCisel[i++]);

for (int k = 0; k < poleOperatoru.length; k++)
{
String operator = poleOperatoru[k];
char[] operatorChar = operator.toCharArray();

switch (operatorChar[k])
{
case '+' : vysledek = prvniCislo + dalsiCislo; break;
case '-' : vysledek = prvniCislo - dalsiCislo; break;
case '*' : vysledek = prvniCislo * dalsiCislo; break;
case '/' : vysledek = prvniCislo / dalsiCislo; break;
}
}
}
return vysledek;
}



Na vymazání toho prvního znaku jsem našel pouze něco ve stylu:
public static String removeCharAt(String s, int pos) {

StringBuffer buf = new StringBuffer( s.length() - 1 );
buf.append( s.substring(0,pos) ).append( s.substring(pos+1) );
return buf.toString();
}
, což mi nepřijde zrovna elegantní. Nenapadlo by tě prosím něco hezčího? Jinak děkuji za super odpovědi, doufal jsem, že se ozveš ty, Libore :-)

Nahlásit jako SPAM
IP: 82.150.166.–
"If you enter this world knowing you are loved and you leave this world knowing the same, then everything that happens in between can be dealt with." - Michael Jackson
liborb
~ Redaktor
+18
Guru
29. 12. 2010   #4
-
0
-

:)

Začnu obecně. Asi se budeš chtít vyrovnat i s tímto:

-2 + 5


3 + -8
a další vypečené příklady. Základem je tedy dostat vstup do normalizovaného tvaru. To děláš a nejspíše to děláš i správně. Když uděláš split na ten první příklad, tak dostaneš pro čísla "", "2", "5" a pro operátory "-", "+". U toho druhého příkladu dostaneš "3", "", "8" a "", "+-".

Radši jsem si to zkusil, abych nepsal kraviny a alespoň ti můžu opravit regulární výraz:
poleCisel = vstup.split("[*/\\-+]");


Tím se mimo jiné ukazuje, že jenom split celý problém neřeší. Následně při zpracování musíš prostě počítat "se vším".

Funkci si upravil, ale stejně to máš navázané na délku řetězce, takže se u čísel jistě dostaneš mimo rozsah pole. V každém průchodu by si totiž měl zpracovat pouze jedno číslo s tím, že na začátku je výsledek 0. A v každém průchodu zpracovat i jeden řetězec operátorů - může tam být např. výše zmíněné "+-" apod., tj. v průchodu cyklem z toho řetězce vyplodit operátor ("--" -> + atd.). Čísel bude vždy stejně nebo o jeden více než operátorů a může jich být lichý počet, i proto v každém průchodu jen jedno číslo.

A vymazávat první znak nepotřebuješ, ale potřebuješ vědět, co máš udělat, když operátor nebo číslo bude při zpracování prázdný řetězec.

Nahlásit jako SPAM
IP: 78.80.52.–
filippop0
Návštěvník
29. 12. 2010   #5
-
0
-

o jave toho moc nevim, ale myslim ze split a regexp je vsude stejny a i ten od liborb opraveny se mi moc nezda a viděl bych ho takhle:

poleCisel = vstup.split("[\*\/-+]");


a aby se nemuselo řešit nějaké mezery, tak proč to nesplitnout i s mezerama?
poleCisel = vstup.split(" [\*\/-+] ");


Pak mi ze stringu: "-2 + 5"
vypadne "-2", " + ", "5"

prošel bych to a kdyz to bude obsahovat cislo, tak to prevedu na cislo, kdyz to bude obsahovat mezery a nejaky symbol uprostred, tak to bude operator...

Jakmile budu mit string spravne rozdeleny na cisla a operatory, rak by to uz tak tezky byt nemelo.

Nahlásit jako SPAM
IP: 90.178.215.–
liborb
~ Redaktor
+18
Guru
30. 12. 2010   #6
-
0
-

To filippop : Asi takto, nejsem odborník na regulární výrazy, vždycky, když nějaký potřebuji, tak ho nějak splácám :), ale ten můj zápis je správně :). Pokud si to myslel tak, že je potřeba, aby všechny speciální znaky předcházelo zpětné lomítko, tak by to mělo vypadat nějak takto:

[\*/\-\+]
tj. pro Javu takto:
"[\\*/\\-\\+]"


V tom tvém zápisu je stejná chyba jako tam měl Hoffik, tj. znak - je použit pro vyznačení rozsahu. Hoffikuv zápis projde, protože rozsah od , do , je platný, ale tvůj rozsah (/ až +) platný není. A "moje" (pro zápis v Javě nutné dvojité) zpětné lomítko jenom opravuje tuto jednu drobnost, protože jinak je ten regulární výraz platný. Ale souhlasím, že by (pro jistotu) měl být zpětným lomítkem uvozen každý speciální znak, aby nedošlo k nedorozumění.

Nahlásit jako SPAM
IP: 78.80.52.–
easy_burn0
Newbie
16. 1. 2011   #7
-
0
-

Pozor na to, pokud chceš jednořádkovou kalkulačku, která ti spočítá výraz ve smyslu "2+3*4-9", tak to bude chtít zpracovat z jiného pohledu.

Ze začátku to půjde,ale pozdeji zjistis, že to je honička, hlavně až budeš řešit prioritu znamének. Taky zjistíš, že zadávání závorek bude asi nezbytnost (ted to kolega řešil tím výrazem, ale pak, až to bude fungovat, budeš chtít zadávat (2 + (-3))^2, atd... tak jak to má v matematice být.)

Napsat řádkovou kalkulačku není tak banální, jak to asi vypadá. Možná odpověď nalezneš v problematice binárních stromů. Viz první odkaz google : http://www.cs.vsb.cz/benes/vyuka/upr/texty/adt/ch01s07s06.html

Omlouvám se, že jsem více nepomohl, ale doufám, že jsem tě navedl na správnou cestu.

Nahlásit jako SPAM
IP: 80.188.120.–
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, 5 hostů

Podobná vlákna

Kalkulacka — založil tomas

Kalkulacka — založil mravenec

Kalkulačka — založil Lukáš

Kalkulačka — založil anajkaa@seznam.cz

Kalkulačka — založil Anakin

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ý