We did some vector and string processing on Monday (first four programs below) and then explored how to use a tally vector on Wednesday (the freq and bellcurve progras).
//countfunc.cpp
#include <iostream>
using namespace std;
// Function declarations (aka prototypes)
// parameters in the parentheses
// return type is to the left
// void = doesn't return a value
void print_countdown_from(int n);
int factorial_of(int n);
int main()
{
const int NUM = 10;
print_countdown_from(NUM); // function call (call site)
cout << "Ready?" << endl;
cout << "Factorial of " << NUM << " is " << factorial_of(NUM) << endl;
// above: function call embedded within a cout
return 0;
}
// Definition looks just like the prototype, but
// curly braces instead of semi-colon.
void print_countdown_from(int n)
{
// do something here
cout << "Counting down!!!!!" << endl;
for(int i = n; i > 0; i--)
{
cout << i << endl;
}
}
int factorial_of(int n)
{
// do something here
cout << "Calculating factorial!!!!" << endl;
// example: 5*4*3*2*1
// Here is the loop definition:
int result = 1; // accumulator variable
for(int i = n; i > 0; i--) // countdown; i is counter variable
{
result *= i;
}
return result;
// Here is the recursive definition:
// if(n == 1) return 1;
// else return n * factorial_of(n-1); // recursive!
// factorial_of(5)
// 5 * factorial_of(4)
// 5 * 4 * factorial_of(3)
// 5 * 4 * 3 * factorial_of(2)
// 5 * 4 * 3 * 2 * factorial_of(1)
// 5 * 4 * 3 * 2 * 1
// 20 * 3 * 2 * 1
// 60 * 2 * 1
// 120 * 1
// 120
}
// vecfunc.cpp
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Prototype
void print_roster(vector<string> roster);
int how_many_long_names(vector<string> list);
int main()
{
vector<string> names;
names.push_back("alice");
names.push_back("robert");
names.push_back("christophe");
names.push_back("dee");
names.push_back("evelyn");
names.push_back("frank");
names.push_back("george");
print_roster(names); // call
cout << "There are " << how_many_long_names(names)
<< " long names!" << endl;
}
void print_roster(vector<string> roster)
{
cout << "printing roster..." << endl;
for(int i = 0; i < roster.size(); i++)
{
cout << i+1 << ". " << roster.at(i) << endl;
}
return; // Can still specify return, but no value because it's void
}
// Suppose a "long" name is MORE than 5 characters.
int how_many_long_names(vector<string> list)
{
int count = 0;
for(int i = 0; i < list.size(); i++)
{
if( list.at(i).size() > 5 )
{
//cout << "LONG: " << list.at(i) << endl;
count++;
}
}
return count;
}
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// Vector with two integers
vector<int> v;
v.push_back(99);
v.push_back(42);
// Array with two integers
int a[2] = { 99, 42 };
cout << "Access array out of bounds:" << endl;
cout << a[2] << endl; // probably some arbitrary integer
// that could leak sensitive information!
cout << "Access vector out of bounds:" << endl;
cout << v.at(2) << endl; // controlled termination
return 0;
}
// nulchar.cpp
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char s3[] = "I like pizza\0and hamburgers.";
cout << "BEFORE: " << strlen(s3) << " chars" << endl;
cout << s3 << endl;
s3[12] = '!';
cout << "AFTER: " << strlen(s3) << " chars" << endl;
cout << s3 << endl;
return 0;
}
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
#include <iomanip>
using namespace std;
int main()
{
const int ALPHABET_SIZE = 26;
cout << "Enter a sentence, and press enter:" << endl;
string sentence;
getline(cin, sentence);
// I believe this will automatically set each entry to zero.
// If not, we'll need to do that ourselves, in a loop.
vector<int> tally(ALPHABET_SIZE);
for(int i = 0; i < sentence.length(); i++)
{
if( islower(sentence.at(i)) ) { // Only process lower-case
cout << sentence.at(i) << '*';
// Convert a-z into 0-25.
int position = sentence.at(i) - 'a';
// Increase the count at that position.
tally.at(position)++;
}
}
cout << endl;
// Print the tally
for(int i = 0; i < ALPHABET_SIZE; i++) {
if(i%5 == 0) {
cout << endl;
}
char letter = 'a' + i;
cout << letter << ":" << setw(5) << tally.at(i) << " ";
}
cout << endl;
return 0;
}
// bell curve you get for probability of the sum of two dice
#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main()
{
const int NUM_ROLLS = 50000000;
srand(time(NULL)); // Initialize PRNG
// We have to add or subtract 2 when converting from
// the sum of dice to a position in the tally vector.
// 0 1 2 3 4 5 6 7 8 9 10 <- vector indices
// 2 3 4 5 6 7 8 9 10 11 12 <- possible sums
vector<int> tally(11);
cout << "Rolling a pair of dice, " << NUM_ROLLS << " times." << endl;
for(int i = 0; i < NUM_ROLLS; i++)
{
int d1 = (rand()%6) + 1; // Roll a number 1-6
int d2 = (rand()%6) + 1; // Roll a number 1-6
int sum = d1 + d2;
int position = sum - 2;
tally.at(position)++;
}
// Print out the tally
for(int i = 0; i < tally.size(); i++)
{
int sum = i + 2;
cout << setw(2) << sum << ": "
<< setw(6) << tally.at(i) << " ";
// bar graph
int num_stars = tally.at(i) / (NUM_ROLLS / 250);
for(int j = 0; j < num_stars; j++)
{
cout << '*';
}
cout << endl;
}
return 0;
}
What’s the real difference between an array and a vector?
A vector
carries its size along with its elements, so it’s always available.
An array also has a limited size, but it’s not stored along with the elements so you have to pass around the size separately. This can be error-prone.
With a vector
, the .at(i)
function is checked – is i
within the size of the array? (See the arrayvsvec.cpp
program, above.)
C strings vs C++ strings
The string
data type we’ve been using was introduced in C++, but not in the original, “core” C language. So now there are two ways to represent strings, and two different sets of functions on them.
// C-style string is a "pointer" to a (sequence of) character(s)
const char* s1 = "Hello";
string s2 = "World";
// In both cases, the string is terminated by a NUL character, '\0'
string s3 = "I like pizza\0and hamburgers.";
cout << s3
See the nulchar.cpp
program for an example.
We access the C-style functions by including the cstring
library:
#include <cstring>
This includes these, and others:
strlen
– calculates the length of the string (up to the first null character.)
strcmp
– string comparison – alphabetic order. Returns == 0 if strings are the same, or < 0 if first comes before second in alphabet, or > 0 for opposite.
strchr
– searches for position of a character within a string.