Showing posts with label chapter 4. Show all posts
Showing posts with label chapter 4. Show all posts

Friday, 29 March 2024

Chapter 4 // Exercises 1-10 - The C++ Programming Language

 For this exercise I'm using Visual Studio Community 2022 and the header file std_lib_facilities:

The exercises can be found online and are not actually in the book:

Chapter 4 - A Tour of C++: Containers and Algorithms
Exercise 1
When first reading this chapter, keep a record of information that was new or surprising to you. Later, use that list to focus your further studies.

1. I didn't know that for_each() is classed as an algorithm. The more you know.

Exercise 2
List 5 standard library containers.

1. std::vector
2. std::array
3. std::map
4. std::deque
5. std::list

Exercise 3
List 5 standard library algorithms.

1. for_each()
2. find()
3. search()
4. copy()
5. remove()

Exercise 4
List 5 standard library headers.

1. #include <string>
2. #include <list>
3. #include <iostream>
4. #include <vector>
5. #include <random>

Exercise 5
Write a program that reads a name (a string) and an age (an int) from the standard input stream cin. Then output a message including the name and age to the standard output stream cout.


Exercise 6
Redo exercise 5, storing several (name, age) pairs in a class. Doing the reading and writing using your own >> and << operators.


Exercise 7
Initialise a vector<int> with the elements 5, 9, -1, 200 and 0. Print it. Sort it, and print it again.


Exercise 8
Repeat exercise 7 with a vector<string> initialised with "Kant", "Plato", "Aristotle", "Kierkegaard", and "Hume".


Exercise 9
Open a file for writing (as an ofstream) and write a few hundred integers to it.


Exercise 10
Open the file of integers from exercise 9 for reading (as an ifstream) and read it.













Thursday, 11 August 2016

Chapter 4 // Exercise 19, 20, 21 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 Exercise // 4.19

Write a program where you first enter a set if name-and-value pairs, such as Joe 17 and Barbara 22. For each pair, add the name to a vector called names and the  number to a vector called scores (in corresponding positions, so that if names[7]=="Joe" then scores[7]=="17"). Terminate input with NoName 0. Check that each name is unique and terminate with an error message if a name is entered twice. Write out all the (name,score) pairs, one per line.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

int main()
{
vector<string> names;
vector<int> scores;

string inputName;
int inputScores;
char loop = 'y';

cout << "Please enter a name followed by the score. To stop input enter 'NoName' in name and 0 in scores.\n";

//get names and scores
while (loop == 'y')
{
cout << "Name: ";
cin >> inputName;
cout << "Score: ";
cin >> inputScores;

for (int i = 0; i < names.size(); ++i)
{
if (names[i] == inputName)
{
cout << "Sorry, that name has already been entered. Please Re-Name it: \n" << endl;
cin >> inputName;
}
}

if (inputName == "NoName" && inputScores == 0)
{
loop = 'n';
}

names.push_back(inputName);
scores.push_back(inputScores);
}

cout << '\n';

//print them out
for (int x = 0; x < names.size()-1; ++x)
{
cout << names[x] << '\t' << scores[x] << '\n';
}

keep_window_open();

return 0;
}


Chapter 4 Exercise // 4.20

Modify the program from exercise 19 so that when you enter a name, the program will output the corresponding score or name not found.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

int main()
{
vector<string> names;
vector<int> scores;

string inputName;
int inputScores;
char loop = 'y';

cout << "Please enter a name followed by the score. To stop input enter 'NoName' in name and 0 in scores.\n";

//get names and scores
while (loop == 'y')
{
cout << "Name: ";
cin >> inputName;
cout << "Score: ";
cin >> inputScores;

for (int i = 0; i < names.size(); ++i)
{
if (names[i] == inputName)
{
cout << "Sorry, that name has already been entered. Please Re-Name it: \n" << endl;
cin >> inputName;
}
}

if (inputName == "NoName" && inputScores == 0)
{
loop = 'n';
}

names.push_back(inputName);
scores.push_back(inputScores);
}

cout << '\n';

string findName;
loop = 'y';
char nameFound = 's';

while (loop == 'y')
{
cout << "Whose score do you want to find?: \n";
cin >> findName;

for (int x = 0; x < names.size() - 1; ++x)
{
if (names[x] == findName)
{
cout << names[x] << '\t' << scores[x] << '\n';
nameFound = 'y';
}
}

loop = 'n';

if (nameFound != 'y')
{
cout << "Sorry, name not found. Do you what to try again? y/n: \n";
cin >> loop;
}

}

keep_window_open();

return 0;
}



Chapter 4 Exercise // 4.21

Modify the program from exercise 19 so that when you enter an integer, the program will output all the names with that score or score not found.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

int main()
{
vector<string> names;
vector<int> scores;

string inputName;
int inputScores;
char loop = 'y';

cout << "Please enter a name followed by the score. To stop input enter 'NoName' in name and 0 in scores.\n";

//get names and scores
while (loop == 'y')
{
cout << "Name: ";
cin >> inputName;
cout << "Score: ";
cin >> inputScores;

for (int i = 0; i < names.size(); ++i)
{
if (names[i] == inputName)
{
cout << "Sorry, that name has already been entered. Please Re-Name it: \n" << endl;
cin >> inputName;
}
}

if (inputName == "NoName" && inputScores == 0)
{
loop = 'n';
}

names.push_back(inputName);
scores.push_back(inputScores);
}

cout << '\n';

int findScore;
loop = 'y';
char scoreFound = 's';

while (loop == 'y')
{
cout << "Please enter a score to find: \n";
cin >> findScore;

for (int x = 0; x < scores.size() - 1; ++x)
{
if (scores[x] == findScore)
{
cout << names[x] << '\t' << scores[x] << '\n';
scoreFound = 'y';
}
}

loop = 'n';

if ( scoreFound != 'y')
{
cout << "Sorry, no scores found. Do you what to try again? y/n: \n";
cin >> loop;
}

}

keep_window_open();

return 0;
}

And so the chapter 4 exercises were rounded out by some nice easy questions. I'll be honest, when I first read them I honestly didn't think I'd be able to solve them. I just thought they were too hard and impossible to do at my level. When I started exercise 1 I still didn't understand vectors all that well or loops. I didn't even know how to print a vector or compare them, now I can do all those things. It's taken me around 2 months to fully work through this chapter but I work full time and some of these exercises would take me around 6 hours to solve.

It feels good though,when you do solve them. And it's amazing to see just how far I've come in 2 months.

Tuesday, 9 August 2016

Chapter 4 // Exercise 18 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 Exercise // 4.18

Write a program to solve quadratic equations. A quadratic equation is of the form:



Use doubles for the user inputs for a, b and c. Since there are two solutions to a quadratic equation, output both x1 and x2.

For those of you (like me) who haven't touched the quadratic formula in almost ten years, I found this site useful as a refresher.


#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

double get_xPos();
double get_xNeg();
double a;
double b;
double c;

int main()
{
cout << "Let's solve some quadratic equations.\n";
cout << "What is a?: \n";
cin >> a;
cout << "What is b?: \n";
cin >> b;
cout << "What is c?: \n";
cin >> c;

double x1 = get_xPos();
double x2 = get_xNeg();

cout << "\nX is: " << x1 << " and " << x2 << "\n";

cout << '\n';
keep_window_open();

return 0;
}

double get_xPos() 
{
double x = ((-b + sqrt((b*b) - (4 *a*c))) / (2 * a));

if ((b*b) - (4 *a*c) < 0) //cannot square root negative, this turns it to positive
{
double q = ((b*b) - (4 * a*c))*-1;
x = (-b + sqrt(q))/(2*a);
}

return x;
}

double get_xNeg()
{
double x = ((-b - sqrt((b*b) - (4 *a*c))) / (2 * a));

if ((b*b) - (4 *a*c) < 0) //cannot square root negative, this turns it to positive
{
double q = ((b*b) - (4 * a*c))*-1;
x = (-b - sqrt(q)) / (2 * a);
}

return x;

}


Ok, I found this one really easy however Bjarne doesn't mention if he wants us to include imaginary numbers. For example you can't square root a negative number, so I created an if statement which changes it to a positive and then continues. It may give a different answer but otherwise it just kept showing invalid.

I also created separate functions for this one as I'm trying to get into the habit of removing as much as possible from int main. Here, I just forward declare the functions as the beginning by ending the function with a ';'. The computer then knows to look elsewhere for the declaration

Sunday, 7 August 2016

Chapter 4 // Exercise 17 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 Exercise // 4.17

Write a program that finds the min, max and mode of a sequence of strings.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{
vector<string> words;
vector<string> smWords;
vector<string> lgWords;
vector<int> wordSizes;

cout << "Enter a set of whitespaced separated words (press enter then ctrl+z when finished): \n";
string w;
while (cin >> w)
{
words.push_back(w);
}

sort(words);

string word;
string mode;
string mostOccurring;
int highCount = 0;
int count = 0;

//print the words entered in order
for (int i = 0; i < words.size(); ++i)
{
cout << words[i] << " ";
}

//calculate mode
for (int i = 0; i < words.size(); ++i)
{
//get the ball rolling
if (i == 0)
{
word = words[i];
++count;
}

else
{
if (word == words[i])
{
++count;
mode = words[i];
}
else
{
if (highCount == 0)
{
highCount = count;
mostOccurring = mode;
}

else if (count > highCount)
{
highCount = count;
mostOccurring = mode;
}

word = words[i];
count = 1;

}
}
}

//calculate min & max
for (int x = 0; x < words.size(); ++x)
{
wordSizes.push_back(words[x].size());
}

sort(wordSizes);

int smallestWS = wordSizes[0];
int largestWS = wordSizes[wordSizes.size() - 1];

for (int x = 0; x < words.size(); ++x)
{
if (words[x].size() == smallestWS)
smWords.push_back(words[x]);

if (words[x].size() == largestWS)
lgWords.push_back(words[x]);
}


//print results
if (highCount == 1)
cout << "\nThere is no mode in this set of words.";
else
{
cout << "\nThe mode is: " << mostOccurring;
cout << "\nAppearing " << highCount << " time(s)";
}

cout << "\nThe largest word(s): ";
for (int x = 0; x < lgWords.size(); ++x)
if(x == 0 || lgWords[x] != lgWords[x-1])
cout << lgWords[x] << " ";

cout << "\nThe smallest words(s): ";
for (int x = 0; x < smWords.size(); ++x)
if (x == 0 || smWords[x] != smWords[x - 1])
cout << smWords[x] << " ";


cout << '\n';

keep_window_open();

return 0;
}

This one took me a while but only because towards the end I started to get a bit pedantic over what exactly should be printed. For example, what if someone entered words that were the same size? What would be the largest and smallest then? Also, what if there was no mode?

Originally testing for the min and max was in the same part as the mode but it just wouldn't work so I devised a new test for them. Basically in that section, it creates a new vector that contains the word sizes of <words>. These are then sorted (to get the smallest and largest) and assigned to variables. Another loop is created that checks to see if there are any words within <words>  that match these sizes, if so they are pushed back into their respective new vectors. I did this because when you sort a vector of strings, it sorts it alphabetically, so searching for the largest and smallest by checking on the previous number won't work.

Friday, 5 August 2016

Chapter 4 // Exercise 16 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 Exercise // 4.16

In the drill you wrote a program that, given a series of numbers, found the max and min of that series. the number that appears the most times in a sequence is called the mode. Create a program that finds the mode of a set of positive integers.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

int main()
{
vector<int> numbers;

cout << "Enter a set of numbers (press enter then ctrl+z when finished): \n";
int n;
while (cin >> n)
{
numbers.push_back(n);
}

sort(numbers);

int number = 0;
int mode = 0;
int highCount = 0;
int mostOccurring;
int count = 0;

for (int i = 0; i < numbers.size(); ++i)
{
cout << numbers[i] << " ";
}

for (int i = 0; i < numbers.size(); ++i)
{

if (i == 0) // get the ball rolling
{
number = numbers[i];
++count;
}

else 
{
if (number == numbers[i])
{
++count;
mode = numbers[i];
}
else
{
if (highCount == 0) 
{
highCount = count;
mostOccurring = mode;
}

if (count > highCount)
{
highCount = count;
mostOccurring = mode;
}
else
{
number = numbers[i];
count = 1;
}

}

}

}

cout << "\nThe mode is: " << mostOccurring;
cout << "\nAppearing " << highCount << " time(s)" << endl;


keep_window_open();

return 0;
}

This one took me a while but it was just a matter of getting the if statements to execute correctly. I mainly took inspiration from the exercise he mentions above and edited it.

Basically, it reads a set of integers into a vector. Sorts them, then on every loop checks if the current number was the same as the last. If it is, the count increases until it hits a different number. Then that number and count is stored, the comparing numbers are reset and it starts all over again. If it encounters a count higher than the one stored, the most occurring number and highest count is replaced by those. 

Wednesday, 3 August 2016

Chapter 4 // Exercise 11, 12, 13, 14, 15 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 Exercise // 4.11

Create a program to find all the prime numbers between 1 and 100. One way to do this is to write a function that will check if a number is a prime (i.e., see if the number can be divided by a prime smaller than itself) using a vector of primes in order (so that if the vector is called primes, primes[0]==2, primes[1]==3, primes[2]==5, etc). Then write a loop that goes from 1 to 100, checks each number to see if it is a prime, and stores each prime found in a vector. Write another loop that lists the primes you found. You might check your result by comparing your vector of prime number with primes. Consider 2 the first prime.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

vector<int> user_primes; // vector to put found primes into
vector<int> primes{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,}; // to compare against

bool isItPrime(int n) 
{
for (int p = 0; p < user_primes.size(); ++p)
{
if (n % user_primes[p] == 0)
return false;
}
return true;

}

int main()
{
user_primes.push_back(2);

for (int i = 3; i <= 100; ++i)
{
if (isItPrime(i))
user_primes.push_back(i);
}

for (int i = 0; i < primes.size(); ++i)
{
cout << primes[i] << '\t' << user_primes[i] << '\n';
}

keep_window_open();

return 0;
}

I spent so many hours trying to solve this one, so many hours scouring the internet but they all solved it using methods that hadn't been taught yet. I then even found Bjarne himself answer this question using methods he had fucking taught yet (talk about not even reading your own book). The way the question is written it sounds like he is implicitly asking you to check all numbers from 1 to 100 are prime by dividing them by a smaller number from within another vector called primes containing primes numbers from 1 - 100. Talk about misleading. He actually wants you to just write a function that finds a prime and then returns that number into a vector. 

So basically I had to end up using a bool function which I still don't fully understand. In chapters 1 - 4 all he has said is that a bool is true or false. I also had to start at 3 otherwise it would never work (even though he says to start at 1 in the book, his own website solves this starting at 3. I was rage quitting for hours). So it checks to see if the number is divisible by any primes already pushed back (so obviously, primes smaller than itself).

For a better understanding of bool values, look here. This is the website I use when Bjarne makes no fucking sense. The author Alex, makes things much easier to understand. 

This was a terribly written exercise.

Chapter 4 Exercise // 4.12

Modify the program described in the previous exercise to take an input value max and then find all the prime numbers from 1 to max.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

vector<int> user_primes; // vector to put found primes into
vector<int> primes{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,}; // to compare against

bool isItPrime(int n)
{
for (int p = 0; p < user_primes.size(); ++p)
{
if (n % user_primes[p] == 0)
return false; // n divided
}
return true; // n couldn't be divided

}

int main()
{
user_primes.push_back(2);

cout << "Please give a maximum number the computer should stop finding primes at:\n";
int max;
cin >> max;

for (int i = 3; i <= max; ++i)
{
if (isItPrime(i))
user_primes.push_back(i);
}

for (int i = 0; i < user_primes.size(); ++i)
{
cout << '\n' << user_primes[i];
}

cout << '\n';
keep_window_open();

return 0;
}



Chapter 4 Exercise // 4.13

Create a program to find all the prime numbers between 1 and 100. there is a classic method for doing this, called the "Sieve of Eratosthenes." Write your program using this method.

At this point in my programming knowledge, I honestly don't know how to do this using only methods he has shown us so far in the book. I've looked everywhere and I just don't understand whats going on. If someone could perhaps explain it to me in dunce terms that would be greatly appreciated but until I'm a more proficient programmer the answer to this one (and below) will have to wait.

EDIT 17/09/2019 - 3 years later I have now completed exercises 13 & 14. You can find the code for them at my git repository: https://github.com/l-paz91/principles-practice/tree/master/Chapter%204

I followed the pseudocode given on Wikipedia here: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Algorithmic_complexity

This time is took me around 30 minutes to solve and I'm quite happy to see just how much my ability to read other code (pseudo or not) has progressed. It also is very possible to do this exercise using methods only shown up to chapter 4 but my problem solving skills were not as developed. I still have a long way to go but I've improved. 

Basically though, this method is quite a contrived way of doing it but I understand why he made us do it. I don't fully understand how it works, but the pseudocode is simple enough to follow to get it working.

Chapter 4 Exercise // 4.14

Modify the program described in the previous exercise to take an input value max and then find all the prime numbers from 1 to max.



Chapter 4 Exercise // 4.15

Write a program that takes an input value n and then finds the first n primes.


#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

vector<int> user_primes; // vector to put found primes into
vector<int> primes{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,}; // to compare against

bool isItPrime(int n)
{
for (int p = 0; p < user_primes.size(); ++p)
{
if (n % user_primes[p] == 0)
return false; // n divided
}
return true; // n couldn't be divided

}

int main()
{
user_primes.push_back(2);

cout << "What number do you want to find primes from?: \n";
int countFrom;
cin >> countFrom;

double maxPrime = countFrom * 100;

for (int i = 3; i <= maxPrime; ++i)
{
if (isItPrime(i))
user_primes.push_back(i);
}

int countTo = countFrom*2;

for (int i = countFrom-1; i <= countTo-2; ++i) //this starts at n and continues n times
{
cout << '\n' << user_primes[i];
}

cout << '\n';
keep_window_open();

return 0;
}

I was a little confused on this one for a while as I thought he meant enter a number (n) and then find that many primes starting from the beginning. But then I realised that was exactly the same as 4.12, so he actually meant start at 'n' and then find the next 'n' numbers from 'n'. 

After some messing around it wasn't too hard, the function to find primes doesn't actually need to be tinkered all that much, you just need to make sure that it finds enough primes to print out.