© Harry Broeders.
Op het SOPX2 practicum wordt wel eens een uitwerking van een practicumopdracht gekopieerd. Vaak is een student die een programma kopieert wel zo slim om de namen van variabelen te wijzigen en de opmaak van het programma te veranderen. Bij SOPX3 komt dit gelukkig niet meer voor ;-). Een docent wil daarom een programma maken dat een aantal kenmerken van een (ander) C++ programma vaststelt zodat verschillende door studenten ingeleverde programma's op deze kenmerken met elkaar kunnen worden vergeleken. De docent is van mening dat het aantal maal dat elk C++ keyword in een C++ programma voorkomt een belangrijk kenmerk van een programma is om de originaliteit van een programma vast te stellen. | ![]() |
Opdracht 4a.
Schrijf een C++ programma dat in een ander C++ programma telt hoeveel maal
elk C++ keyword daarin voorkomt. Maak gebruik van de file
keywords.txt
|
Als datastructuur kan een map
met per keyword een teller gebruikt
worden. Het programma uit paragraaf 6.5 van het
dictaat kan prima als uitgangspunt gebruikt
worden. Natuurlijk moet je er dan wel voor zorgen dat alleen de keywords
geteld worden. Dit kan op twee manieren:
set
aan met daarin alle keywords. Met de memberfunctie
count
van set
kan eenvoudig bepaald worden of een
ingelezen woord een keyword is (en geteld moet worden).
map
voordat je gaat beginnen met tellen eerst met alle
keywords (alle tellers op 0
). Je moet dan alleen woorden tellen
die al in de map
voorkomen. Met de functie count
van map
kan eenvoudig bepaald worden of een ingelezen woord
al in de map
voorkomt.
Als je er voor hebt gekozen om een set
te gebruiken dan kun
je de inhoud van de file keywords.txt naar de
set
kopiëren met het copy
algoritme door gebruik
te maken van istream_iterator
's
De inhoud van de map
kun je op het scherm afdrukken door gebruik
te maken van het copy
algoritme en
ostream_iterators
's. Het is dan wel nodig om een
operator<<
te definieren voor de standaard class template
pair
(de elementen in de map
zijn in ons geval
van het type pair<const string, int>
). Deze operator kan
als volgt gedefinieerd worden:
template <typename Key, typename Value>
ostream& operator<<(ostream& o, pair<Key, Value> p) {
return o<<p.first<<" "<<p.second<<endl;
}
De bovenstaande code blijkt in gcc 3.4.2 (wx-devcpp)
niet te werken! Zie:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8529.
Je kunt de volgende workaround toepassen:
namespace std {
template <typename Key, typename Value>
ostream& operator<<(ostream& o, pair<Key, Value> p) {
return o<<p.first<<" "<<p.second<<endl;
}
}
-
Het programma uit de vorige opdracht is niet zo gebruiksvriendelijk. Als de docent twee programma's wil vergelijken dan moet hij het programma 2 keer uitvoeren en de uitvoer handmatig met elkaar vergelijken. De docent wil dit vergelijken automatiseren.
Opdracht 4b.
Schrijf een C++ programma dat in een twee andere C++ programma telt hoeveel
elk C++ keyword daarin voorkomt. Maak gebruik van de file
keywords.txt
Melding 1 moet worden gegeven als alle C++ keywords in beide programma's exact evenvaak voorkomen. Melding 2 moet gegeven worden als het aantal maal dat een keyword gebruikt wordt slechts bij hoogstens 3 keywords afwijkt. In alle andere gevallen moet de derde melding gegeven worden. Maak zoveel mogelijk gebruik van datastructuren en algoritmen uit de standaard C++ library. Een overzicht van de STL kun je vinden op: http://www.sgi.com/tech/stl/table_of_contents.html. Een ander overzicht van STL algoritmen kun je vinden op: http://www.cppreference.com/ of http://cplus.about.com/library/blstl.htm. Lees de hierna volgende tip als je zelf geen plan van aanpak kunt bedenken. |
Je kan natuurlijk voor elke file een aparte map
gebruiken maar
het is eenvoudiger om 1 map
te gebruiken en bij het inlezen
van de ene file de bij de keyword's behorende tellers te verhogen en bij
het inlezen van de andere file de bij de keyword's behorende tellers te verlagen.
Voor alle keyword's die even vaak in beide files gebruikt worden zullen de
tellers na afloop op 0
staan. Met een count_if
kun je vervolgens tellen hoeveel tellers ongelijk aan 0
zijn.