Vinnaren i pepparkakshustävlingen!
2008-02-21, 00:56
  #1
Medlem
Sitter här och sliter mitt hår över en del av en lite större uppgift, det är så att jag ska dela upp en sträng utan att använda t.ex StringTokenizer. Uppgiften går ut på att ta in en ekvation och dela upp den efter operatorer och stoppa dessa i en array, tex skulle ekvationen "-15+20*-15" se ut som följande:

Citat:
-15
+
20
*
-15

Jag har kommit så långt att jag delar upp strängen "ganska" rätt, dock får den fnatt vid ganska enkla ekvationer. Jag tror att jag har fått den att funka (till viss del) med negativa tal, någon som kan vägleda/ge mig en hint på hur mitt problem skulle kunna lösas? Jag vill inte ha en "hel" lösning, för det kommer förstöra det roliga för mig, peka bara på vad i koden som ställer till det så kommer jag återkomma om jag inte hittar vidare. Observera att problemet skall lösas med endast grundläggande bitar.

Testa följande ekvationer så får ni ett hum om vad som inte funkar:
-10+-20/-15*30 //ok
-10+20/-15*30 //inte ok
-10--20/-15*30 //helt galet!



Som ni ser så lägger jag till de tre sista tecknen (*30) manuellt genom sista if-satsen. Finns det något sätt att komma runt detta så att det görs i looparna istället?
Citera
2008-02-21, 09:00
  #2
Medlem
rahanjams avatar
Jag är inte helt säker, men jag tror att du måste tänka en hel del på prioriteringsreglerna(om det var så det nu hette).

T.ex :


Och sedan att olika ekvationer löses lättast inom parenteser osv?. Jag är inte säker, men så tänker iallafall jag!
Citera
2008-02-21, 09:30
  #3
Medlem
Du menar att innan jag stoppar in de olika substringen i arrayen så ska programet göra om -- till + och +- till - ?

Om vi utgår från det exemplet här exemplet:
-10--20/-15*30

Där skulle --20 ändras till +20, är det så du menar? Det är en lösning och det skulle väl göra att jag slipper negativa tal antar jag, dock ändrar det ju inte felet som gör att substringen blir helt galna.
Citera
2008-02-22, 23:20
  #4
Medlem
Om jag ställer frågan såhär då: Varför gör inte loopen det jag vill att den ska göra? Jag vill att loopen ska kolla varje tecken i input och jämföra med mina operatorer, om en operator hittas så ska alla tecken från tmp fram till operatorns index läggas i en plats i arrayen samt att operatorn läggs i efterföljande plats i arrayen. Därefter skall tmp sättas med hjälp av indexOf till det index som operatorn hittades på. Om vi nu antar att man bara får korrekta och simpla ekvationer, dvs utan negativa tal så bör väl detta funka?

Just nu jämför ju if-satserna bara om det är ett likadant tecken på i och i+1, någon som kan hinta mig?
Citera
2008-02-23, 00:29
  #5
Medlem
Hazs avatar
Jag skulle nog lösa den helt annorlunda, men jag är ju inte du...

Det här verkar funka, tmp måste "flyttas" inom strängen ibland + att jag ändrade så den börjar leta från pos 0 istället för pos 1.
Bara snabbfixat, jag har säkert missat en del. (Och kalla inte klassen Main!!!)
Kod:
public class TalUpp {

    public static void main(String[] args) {
    
        int k = 0;
        int l = 0;
        int tmp = 0;
        String operator = "-+*/";
        String input = "-10+-20/-15*30";
        String[] array = new String[input.length()];
        
        for(int i = 1; i<input.length(); i++ ) {
            for(int j = 0; j<operator.length(); j++) {
                if(input.charAt(i) == operator.charAt(j)) {
                    if(input.charAt(i+1) == operator.charAt(j)) {
                        array[k] = input.substring(tmp, input.indexOf(operator.charAt(j), (tmp + 1)));
                        k++;
                        array[k] = input.substring(input.indexOf(operator.charAt(j), tmp), input.indexOf(operator.charAt(j), ++tmp)+1);
                        tmp = input.indexOf(operator.charAt(j), tmp);
                    } else {
                        array[k] = input.substring(tmp, input.indexOf(operator.charAt(j), (tmp + 1)));
                        k++;
                        tmp = input.indexOf(operator.charAt(j), ++tmp);
                    }
                } 
            }
        }
        if(input.charAt(tmp) != '-') {
            array[k] = input.substring(tmp, tmp+1);
            k++;
            array[k] = input.substring(tmp+1);
        } else {
            array[k] =  input.substring(tmp);
        }
        
        while(array[l] != null) {
            System.out.println(array[l]);
            l++;
        }
    }
}  
Citera
2008-02-24, 10:40
  #6
Medlem
Det här börjar bli alltför krångligt, så jag har tänkt om. Jag gör en metod som kollar om uttrycket är rätt från början och gör om -- till + osv. Dock har jag fastnat när jag ska kontrollera om tecknen som finns i ekvationen stämmer överens med de tecken som är OK. Verkar som den simplaste uppgift men jag kan inte göra det rätt verkar det som. :/

Kod:
String input "12-57*45";
        
String chars "0123456789+-*/)(";
        
boolean doBreak false;
        
        for(
int i 0i<input.length(); i++) {
            for(
int j 0j<chars.length(); j++) {
                if(
input.charAt(i) == chars.charAt(j)) {
                    
doBreak true;
                }
            }
        }
        
        if(
doBreak == false) {
            
System.out.println("Felaktiga tecken!");
        } 



Haz: Hur skulle du löst det ursprungliga problemet? Angående Main, så är det ren lathet att inte orka byta namn på klassen i IDE:n. :P
Citera
2008-02-24, 12:06
  #7
Medlem
Hazs avatar
Du stegar igenom strängarna och sätter doBreak till true om du hittar ett tecken som ska vara med, men du tar ingen hänsyn till tidigare värden. Antag att input innehåller 12+34*6???3 så kommer ju doBreak att sättas till true så fort metoden hittar siffran 1 och sedan sätts den aldrig tll något annat. Gör så här i stället:

Kod:
        for(int i = 0; i<input.length(); i++)
            doBreak = doBreak || chars.indexOf(input.charAt(i)) == -1;
        if(doBreak)
            System.out.println("Felaktiga tecken!");
Du stegar igenom hela input-strängen och kollar tecken för tecken. Metoden indexOf i String-klassen retrunerar -1 om delsträngen (eller tecknet) inte hittas. doBreak sätts till doBrak ELLER tecknet inte hittat, alltså så fort tecknet inte finns i chars-strängen sätts doBreak till true.

Skulle jag lösa uppgiften skulle jag nog stega "bakifrån" och till början, dvs loopa från input.length till 0. Har du exempelvis strängen -5*30+20--12 och letar bakifrån efter siffror får du ju att --12 är sista delen, och första tecknet av den måste vara operatorn. Sedan får man ju "vända" arrayen, men det är ju inga stora problem.
Citera
2008-02-24, 12:18
  #8
Medlem
Antar att du ska beräkna uttrycket sen? Isåfall kan det ju vara idé att kolla på t ex. en enkel recursive descent-parser. Finns massor med exempel på Internet. Här är ett exempel på hur det skulle kunna fungera i Java http://rafb.net/p/QTknje78.html (om än inte det bästa).
Citera
2008-02-26, 02:55
  #9
Medlem
Grunt_Grunts avatar
Jag skulle göra i stort som Haz föreslag. Men jag skulle hellre använda String-funktionen "contains" istället för "indexOf". Det blir mer lättförståeligt och den fula "magiska siffran" försvinner.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback