tracking dice see dieroll2 cpp
play

Tracking Dice, see dieroll2.cpp Defining tvector objects const int - PowerPoint PPT Presentation

Vectors Vector basics Were using the class tvector , need #includetvector.h Vectors are homogeneous collections with random access Based on the standard C++ (STL) class vector, but safe Store the same type/class of object,


  1. Vectors Vector basics ● We’re using the class tvector , need #include”tvector.h” ● Vectors are homogeneous collections with random access ➤ Based on the standard C++ (STL) class vector, but safe ➤ Store the same type/class of object, e.g., int, string, … ➤ Safe means programming errors are caught rather than ➤ The 1000 th object in a vector can be accessed just as quickly ignored: sacrifice some speed for correctness as the 2 nd object ➤ In general correct is better than fast, programming plan: • Make it run ● We’ve used files to store text and StringSets to store sets of • Make it right strings; vectors are more general and more versatile, but are • Make it fast simply another way to store objects ● Vectors are typed, when defined must specify the type being stored, vectors are indexable, get the 1 st , 3 rd , or 105 th element ➤ We can use vectors to count how many times each letter of the alphabet occurs in Hamlet or any text file tvector<int> ivals(10); // store 10 ints ➤ We can use vectors to store CD tracks, strings, or any type vals[0] = 3; ● Vectors are a class-based version of arrays , which in C++ are tvector<string> svals(20); // store 20 strings svals[0] = “applesauce”; more low-level and more prone to error than are Vectors A Computer Science Tapestry 8.1 A Computer Science Tapestry 8.2 Tracking Dice, see dieroll2.cpp Defining tvector objects const int DICE_SIDES = 4; ● Can specify # elements in a vector, optionally an initial value int main() { tvector<int> values(300); // 300 ints, values ?? int k, sum; tvector<int> nums(200,0); // 200 ints, all zero Dice d(DICE_SIDES); tvector<int> diceStats(2*DICE_SIDES+1); tvector<double> d(10,3.14); // 10 doubles, all pi int rollCount = PromptRange("how many rolls",1,20000); tvector<string> w(10,"foo");// 10 strings, "foo" tvector<string> words(10); // 10 words, all "" for(k=2; k <= 2*DICE_SIDES; k++) diceStats { diceStats[k] = 0; } ● The class tvector stores objects with a default constructor for(k=0; k < rollCount; k++) 0 1 2 3 4 5 6 7 8 { sum = d.Roll() + d.Roll(); ➤ Cannot define tvector<Dice> cubes(10); since Dice diceStats[sum]++; } doesn’t have default constructor cout << "roll\t\t# of occurrences" << endl; ➤ Standard class vector relaxes this requirement if vector for(k=2; k <= 2*DICE_SIDES; k++) { cout << k << "\t\t" << diceStats[k] << endl; uses push_back , tvector requires default constructor } return 0; } A Computer Science Tapestry 8.3 A Computer Science Tapestry 8.4

  2. Vectors as lists Reading words into a vector tvector<string> words; ● The “vector as counters” example constructs and initializes a string w; vector with a specific number of elements string filename = PromptString("enter file name: "); ● Other uses of vector require the vector to “grow” to ifstream input(filename.c_str()); accommodate new elements while (input >> w) ➤ Consider reading words from Hamlet , storing them in a { vector words.push_back(w); ➤ How big should we define vector to be initially? What are } potential problems? cout << "read " << words.size() << " words" << endl; ➤ Analogy of shopping list on the refrigerator, what happens cout << "last word read is " << words[words.size() - 1] << endl; when we run out of room on the list? ● When a vector is used as a list we’ll use a different method for adding elements to the vector so that the vector can “grow” ● What header files are needed? What happens with Hamlet ? Where does push_back() put a string? ➤ The vector grows itself, we (as client programmers) don’t A Computer Science Tapestry 8.5 A Computer Science Tapestry 8.6 Using tvector::push_back Comparing size() and capacity() ● The method push_back adds new objects to the “end” of a ● When a vector is defined with no initial capacity, and push_back is used to add elements, size() returns the vector, creating new space when needed number of elements actually in the vector ➤ The vector must be defined initially without specifying a ➤ This is the number of calls of push_back() if no elements size are deleted ➤ Internally, the vector keeps track of its capacity , and when ➤ If elements deleted using pop_back(), size updated too capacity is reached, the vector “grows” ➤ A vector grows by copying old list into a new list twice as ● The capacity of vector is accessible using big, then throwing out the old list tvector::capacity(), clients don’t often need this value ➤ An initial capacity can be specified using reserve() if ● The capacity of a vector doubles when it’s reached: 0, 2, 4, 8, client programs know the vector will resize itself often ➤ The function resize() grows a vector, but not used in 16, 32, … conjunction with size() – clients must track # objects in ➤ How much storage used/wasted when capacity is 1024? vector separately rather than vector tracking itself ➤ Is this a problem? A Computer Science Tapestry 8.7 A Computer Science Tapestry 8.8

  3. Passing vectors as parameters Vectors as data members ● Vectors can be passed as parameters to functions ● A tvector can be a (private) instance variable in a class ➤ Constructed/initialized in class constructor ➤ Pass by reference or const reference (if no changes made) ➤ If size given, must be specified in initializer list ➤ Passing by value makes a copy, requires time and space class WordStore void ReadWords(istream& input, tvector<string>& v); { // post: v contains all strings in input, public: // v.size() == # of strings read and stored WordStore(); private: void Print(const tvector<string>& v) tvector<string> myWords; }; // pre: v.size() == # elements in v WordStore::WordStore() // post: elements of v printed to cout, one per line : myWords(20) { ● If tvector::size() is not used, functions often require an } ➤ What if push_back() used? What if reserve() used? int parameter indicating # elements in vector A Computer Science Tapestry 8.9 A Computer Science Tapestry 8.10 Vectors as data members (continued) David Gries ● It’s not possible to specify a size in the class declaration Advocates formal methods as ● integral part of program ➤ Declaration is what an object looks like, no code involved development ➤ Size specified in constructor, implementation .cpp file ➤ Formal means well- class WordStore founded mathematically { ➤ Loop invariants are an private: example of formalisms that tvector<string> myWords(20); // NOT LEGAL SYNTAX! help program development }; A programmer needs a bag of ticks, a collection of methods for ● If push_back is used, explicit construction not required, but ok attacking a problem. … One technique will never suffice WordStore::WordStore() : myWords() // default, zero-element constructor In 1999 is developing a CD- ● { } based book for learning to ➤ No () ’s for local variable: tvector<string> words; program with Java A Computer Science Tapestry 8.11 A Computer Science Tapestry 8.12

  4. Picking a word at random First approach, pick a word at random tvector<string> words; ● Suppose you want to choose one of several words at random, string w, filename = “words.txt”; e.g., for playing a game like Hangman RandGen gen; ➤ Read words into a vector, pick a random string from the ifstream input(filename.c_str()); vector by using a RandGen or Dice object. Drawbacks? while (input >> w) { words.push_back(w); ➤ Read words, shuffle the words in the vector, return starting } from front. Drawbacks? for(k=0; k < words.size(); k++) { int index = gen.RandInt(0,words.size()-1); ● Steps: read words into vector, shuffle, return one-at-a-time cout << words[index] << endl; ➤ Alternatives: use a class, read is one method, pick at } random is another method ➤ Don’t use a class, test program with all code in main, for ● What could happen in the for-loop? Is this desired behavior? example A Computer Science Tapestry 8.13 A Computer Science Tapestry 8.14 Shuffling the words ( shuffle.cpp ) Why this is a good shuffling technique tvector<string> words; ● Suppose you have a CD with 5 tracks, or a vector of 5 words string w, filename = “words.txt”; ➤ The first track stays where it is one-fifth of the time, that’s RandGen gen; ifstream input(filename.c_str()); good, since 1/5 of all permutations have track one first while (input >> w) ➤ If the first track is swapped out (4/5 of the time) it will then { words.push_back(w); end up in the second position with probability 1/4, that’s } // note: loop goes to one less than vector size 4/5 x 1/4 = 1/5 of the time, which is what we want for(k=0; k < words.size()-1; k++) ➤ Also note five choices for first entry, # arrangements is { int index = gen.RandInt(k,words.size()-1); 5x4x3x2x1 = 5! Which is what we want. string temp = words[k]; words[k] = words[index]; ● One alternative, make 5 passes, with each pass choose any of words[index] = temp; the five tracks/words for each position } ➤ Number of arrangements is 5x5x5x5x5 > 5!, not // Print all elements of vector here desired, there must be some “repeat” arrangements ● Key ideas: swapping elements, choosing element “at random” ➤ All arrangements/permuations equally likely A Computer Science Tapestry 8.15 A Computer Science Tapestry 8.16

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend