Page 1 of 1
[C++] Rekenkundige uitdrukking uit een bestand uitlezen
Posted: 14 Apr 2006, 09:47
by HobbeS
Opdracht:
Schrijf een programma dat een rekenkundige uitdrukking van een tekstfile inleest en berekent.
Het antwoordt wordt op het beeldscherm van de terminal gezet..
Wat heb ik nu?
Een bestand som.txt met daarin:
Mijn C++ code tot nu toe:
Is hier te vinden...
Nu geeft hij als uitvoer alleen 125.. Het eerste getal van de berekening. Ik zat al te denken om dan met een iterator elke keer het volgende deel aan te wijzen en dan achter elkaar te zetten alleen wist ik dan niet hoe ik het dan kan laten berekenen.. In wat voor variabel moet ik dan de wiskundige functies zetten(+ - / *)?
Wie kan mijn makkelijk en snel helpen zodat ik eindelijk van dat #$^*&( C++ af ben!
.edit: phpBB maakt een zooi van mijn code.. Mijn code
hier.
Posted: 15 Apr 2006, 16:04
by GBCHEATER
Ik zie dat je voor elk teken een spatie zet. In java is er iets als een tokenizer, is dit er in C++ ook? dan heb je alle tekens apart.
Verder weet ik niet of je strings kan gebruiken tijdens een berekening, dit denk ik niet. Dan zou ik de string gaan vergelijken met een teken. Is dit een + dan een + er neerzetten etc.
Dat is de simpelste oplossing denk ik.
Verder krijg ik een 404 bij je link.
Posted: 17 Apr 2006, 10:40
by Valor
Ik zou het oplossen door de regel in te lezen en vervolgens ook de operatoren in een array te plaatsen.
Vervolgens moet je gaan kijken naar je operatoren. Of deze voorang heeft. Zoals * keer voorheeft op +. Als je dit allemaal gecontroleerd heb kun je beginnen met reken.
Je defineert gewoon voor een functie voor elke operator waar je 2 getallen aan me kan geven en die een return value heeft. Aangezien je ook moet kunnen delen is het makkelijk om alles gelijk naar doubles te converten
Code: Select all
public double Multipli(double a, double b){
return a * b;
}
Zo maak je voor elke operator een functie en dan is het een kwestie van het correct uitlezen van je getallen array en operator array
Posted: 17 Apr 2006, 15:22
by HobbeS
Ik snap nog niet helemaal hoe ik dat moet doen met die array... Moet ik nu 2 array's aanmaken? En die dan bijvoorbeeld 9 groot maken, zo groot is de bewerking...
En hoe zou ik die 2 array's dan met elkaar moeten combineren/vergelijken?
Bij elke spatie leest hij appart uit, dus dat kan gewoon alleen dat vergelijken zoals je voorsteld GB krijg ik niet voor elkaar...
P.S. de link heb ik gefikst...
Posted: 18 Apr 2006, 18:02
by HobbeS
Hey allemaal, nog een paar dingetjes en ik heb hem klaar.. Niet heel netjes maar af zeg maar.. Vanavond zal ik even posten hoe het geworden is!
GB, leuk dat je ook nog even langs kwam! Altijd fijn als iemand nog even meedenkt!
Posted: 18 Apr 2006, 22:08
by madman
Ik krijg bij die 2e file een 404...
Moet je rekening houden met Meneer Van Dale? Dat maakt het namelijk een stuk spannender

Posted: 18 Apr 2006, 22:24
by HobbeS
madman wrote:Ik krijg bij die 2e file een 404...
Moet je rekening houden met Meneer Van Dale? Dat maakt het namelijk een stuk spannender

Meneer Van Dale??
Ik heb er wel in zitten dat eerst * en / gedaan worden en daar + en -... Niet echt nette code maarja, het werkt en ik moet mijn school opdrachten af hebben voor 1 mei...
Posted: 18 Apr 2006, 22:52
by madman
Voor 1 mei? Terig dan heb je nog tijd zat!
Code: Select all
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
Input : TextFile;
LineFromFile : string;
function ParseLine (formule : string) : string;
var
i : integer;
elements : array of string;
tmp_str : string;
current_value : real;
begin
//Loop door de forumle heen op zoek naar spaties (scheidingstekens)
for i := 1 to length(formule) do
begin
//Als die is gevonden wordt het stukje struk dat we tot nu toe hebben gevonden opgeslagen in array
//Let op: de paties worden er al automatisch uit gevist!
if formule[i] = ' ' then
begin
SetLength(elements,length(elements)+1);
elements[length(elements)-1] := tmp_str;
tmp_str := '';
end
else
// Zo niet, dan plakken we het er aan vast
tmp_str := tmp_str + formule[i];
end;
// En nog ff de laatste bewaren:
SetLength(elements,length(elements)+1);
elements[length(elements)-1] := tmp_str;
// Eerste teken moet altijd een nummer zijn! (je kan niet beginnen met een *, /, + of -)
current_value := StrToFloat(elements[0]);
for i := 1 to length(elements)-1 do
if odd(i) then // pak alleen de oneven elementen uit de array (dit zijn de commando's
//Helaas kan Delphi niet een Case statement bouwen voor strings...
if elements[i] = '*' then
current_value := current_value * StrToFloat(elements[i+1])
else if elements[i] = '/' then
current_value := current_value / StrToFloat(elements[i+1])
else if elements[i] = '+' then
current_value := current_value + StrToFloat(elements[i+1])
else if elements[i] = '-' then
current_value := current_value - StrToFloat(elements[i+1]);
result := FloatToStr(current_value);
end;
begin
AssignFile(Input, 'c:\som.txt');
Reset(Input);
while not eof(Input) do
begin
Readln(Input,LineFromFile);
Writeln(LineFromFile, ' = ', ParseLine(LineFromFile));
end;
Writeln ('Hit RETURN to exit the program');
Readln;
end.
De Delphi Console versie (zonder meneer van dale dan !)
Posted: 18 Apr 2006, 23:00
by HobbeS
Mijn versie is nu
hier te vinden....
P.S. Jammer genoeg gaat het niet goed als ik hem in de code tags gooi...
Posted: 18 Apr 2006, 23:05
by madman
Brr... wat een ranzige if statements daar onderin ..

Posted: 18 Apr 2006, 23:08
by HobbeS
Ja ik ben er een hele tijd mee bezig geweest om het anders te doen.. Toe naar een docent geweest om raad te vragen.. Het enige wat die kon zeggen was na elkaar doen..
Toen dacht ik barst doe ik dat wel, klaar en hij blij.. Kijken wat hij er morgen van zegt.. Had echt geen idee hoe ik het anders moest doen MET prioriteit van * en /...
Posted: 19 Apr 2006, 00:04
by madman
En V2, nu met Van Dale:
Code: Select all
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, classes, math;
var
Input : TextFile;
LineFromFile : string;
function ParseLine (formule : string) : TStrings;
var
i : integer;
elements: TStrings;
tmp_str : string;
begin
elements := TStringlist.Create;
//Loop door de forumle heen op zoek naar spaties (scheidingstekens)
for i := 1 to length(formule) do
begin
//Als die is gevonden wordt het stukje struk dat we tot nu toe hebben gevonden opgeslagen in array
//Let op: de paties worden er al automatisch uit gevist!
if formule[i] = ' ' then
begin
if (elements.count > 0) then
// Aftrekkingen hanteren als het optellen van een negatief getal: dit ivm de Van Dale regels
if (elements[elements.count-1] = '-') then
begin
elements[elements.count-1] := '+';
tmp_str := '-' + tmp_str;
end;
elements.Add(tmp_str);
tmp_str := '';
end
else
// Zo niet, dan plakken we het er aan vast
tmp_str := tmp_str + formule[i];
end;
// En nog ff de laatste bewaren:
elements.Add(tmp_str);
result := elements;
end;
procedure doCommmand (var elements: TStrings; index : integer);
begin
// met een case van het ascii nummer bepalen we we moeten doen (volgende is het zelfde als Van Dale, maar niet noodzakelijk zo)
case ord(elements[index][1]) of
94 : elements[index -1] := FloatToStr(power(StrToFloat(elements[index -1]),StrToFloat(elements[index +1])));
42 : elements[index -1] := FloatToStr(StrToFloat(elements[index -1]) * StrToFloat(elements[index +1]));
47 : elements[index -1] := FloatToStr(StrToFloat(elements[index -1]) / StrToFloat(elements[index +1]));
43 : elements[index -1] := FloatToStr(StrToFloat(elements[index -1]) + StrToFloat(elements[index +1]));
45 : elements[index -1] := FloatToStr(StrToFloat(elements[index -1]) - StrToFloat(elements[index +1]));
end;
elements.Delete(index+1);
elements.Delete(index);
end;
function CalcFormule (elements: TStrings) : string;
const vandale : array[0..4] of char = ('^', '*', '/', '+', '-');
var
i : integer;
found : boolean;
vandale_key : integer;
begin
vandale_key := 0;
while elements.Count > 1 do
begin
found := false;
// de eerste en de laatste kunnen we altijd overslaan (dat zijn cijfers geen commando's)
for i := 1 to elements.count - 1 do
// Alleen verder gaan als we nog niets gedaan hebben ( i loopt anders niet meer synchroon met het aantal elementen in de list)
if not found then
// Als we een commando hebben gevonden dat we mogen uitvoeren, dan voeren we hem uit.
if (elements[i] = vandale[vandale_key]) then
begin
doCommmand(elements, i);
found := true;
end;
// Als er geen commando's meer waren die uitgevoerd moesten worden, gaan we naar de volgende
if not found then
vandale_key := vandale_key +1;
end;
result := elements[0];
end;
begin
AssignFile(Input, 'c:\som.txt');
Reset(Input);
while not eof(Input) do
begin
Readln(Input,LineFromFile);
Writeln(LineFromFile, ' = ', CalcFormule(ParseLine(LineFromFile)));
end;
Writeln ('Hit RETURN to exit the program');
Readln;
end.
Posted: 19 Apr 2006, 20:16
by GBCHEATER
HobbeS wrote:Hey allemaal, nog een paar dingetjes en ik heb hem klaar.. Niet heel netjes maar af zeg maar.. Vanavond zal ik even posten hoe het geworden is!
GB, leuk dat je ook nog even langs kwam! Altijd fijn als iemand nog even meedenkt!
Sure, jammer dat ik niet zo heel erg veel heb kunnen doen.

Nog genoten van het gebakje?
Volgens mij kan je - wanneer die gast niet tevreden is - het scriptje hier onder aan zo ff doorgooien naar C++, en ben je klaar.
Posted: 19 Apr 2006, 21:24
by madman
Right.. Ik geloof dat ik wel wat beters te doen heb

Een progsel dat aan de opdracht voldoet, en daar boven op nog eens meerdere regels per file aan kan en niet gebonden is aan het aantal commando's dat er per regel staat vond ik wel mooi zat.. Per slot van rekening moet ie zelf ook nog wat te doen hebben

Posted: 19 Apr 2006, 22:18
by HobbeS
madman wrote:Right.. Ik geloof dat ik wel wat beters te doen heb

Een progsel dat aan de opdracht voldoet, en daar boven op nog eens meerdere regels per file aan kan en niet gebonden is aan het aantal commando's dat er per regel staat vond ik wel mooi zat.. Per slot van rekening moet ie zelf ook nog wat te doen hebben

Nou ik moet echt zeggen dat ik het er heel mooi uit vind zien, en dat ik je dankbaar bent dat je er moeite in hebt gestoken!
Alleen denk ik niet dat ik dit om kan bouwen naar C++ code, maar misschien als ik wat tijd over heb dat ik er mee bezig ga.
Posted: 20 Apr 2006, 07:49
by madman
Oh, dat maakt mij verder niet uit.. Ik vond het wel een grappige opdracht en heb hem daarom ff uitgewerkt
Denk overigens dat het niet super moeilijk is hoor om hem om te zetten naar C++: je hoeft hem namelijk niet helemaal te gaan ombouwen naar OO of zo

Posted: 21 Apr 2006, 16:27
by GBCHEATER
Hehe, die opmerking was ook voor Hobbes bedoelt.