Sunday, 13 May 2018

Chapter 8 // Exercise 14 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

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


Chapter 8 // Exercise 14



14. Can we declare a non-reference function argument const (e.g., void f(const int);)? What might that mean? Why might we want to do that? Why don't people do that often? Try it; write a couple of small programs to see what works.


#include "stdafx.h"
#include "std_lib_facilities.h"

void f(const int);

int main()
{
 int n1 = 1;
 const int n2 = 2;

 f(n1);
 f(n2);
 f(3);

 keep_window_open();

 return 0;
}

void f(const int i)
{
 cout << i << endl;
}

You can declare a non-reference argument const. As you cannot change the value it is only really useful for printing to the screen or extracting data for other calculations. 

And thus concludes Chapter 8. When I first read this chapter almost a year and a half ago now, I honestly couldn't wrap my head around pointers and pass-by-value/reference. I just thought I wasn't going to get it. Then I had to build engines using DirectX9 and DirectX11 and everything is a pointer. The more time I spend programming the more comfortable I feel using more advanced concepts. However, going back to the basics is useful as there are many things in this chapter I've implemented in my code. I kept passing the d3d device by reference between classes, that's now a pointer instead. The next chapter is about classes which I needed as I feel like I needed to seriously brush up.

Wednesday, 9 May 2018

Chapter 8 // Exercise 13 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

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


Chapter 8 // Exercise 13



13. Write a function that takes a vector<string> argument and returns a vector<int> containing the number of characters in each string. Also find the longest and the shortest string and the lexicographically first and last string. How many separate functions would you use for these tasks? Why?


#include "stdafx.h"
#include "std_lib_facilities.h"

void print(const vector<int>& vInt, const vector<string>& vStr1, const vector<string>& vStr2)
{
 cout << "Chars in each string: ";
 for (int i = 0; i < vInt.size(); ++i)
  cout << vInt[i] << " ";

 cout << "\n\nLongest String: " << vStr1[0] << endl;
 cout << "\nSmallest String: " << vStr1[1] << endl;

 cout << "\nAlphabetically First Word: " << vStr2[0] << endl;
 cout << "\nAlphabetically Last Word: " << vStr2[1] << '\n' << endl;
}

//number of characters in each string
vector<int> findNumChars(const vector<string>& v)
{
 vector<int> numChar;

 for (int i = 0; i < v.size(); ++i)
 {
  //push back size of each string
  numChar.push_back(v[i].size());
 }

 return numChar;
}

//find longest&shortest string in vector
vector<string> findMinMax(const vector<string>& v)
{
 vector<string> minMax;

 int largest = v[0].size();
 int smallest = v[0].size();
 int iterator1 = 0;
 int iterator2 = 0;  //to pushback correct items from vector

 for (int i = 0; i < v.size(); ++i)
 {
  //if largest is smaller than value, make that new largest
  if (largest < v[i].size())
  {
   largest = v[i].size();
   iterator1 = i;
  }

  //if smallest is bigger than value, make that new smallest
  if (smallest > v[i].size())
  {
   smallest = v[i].size();
   iterator2 = i;
  }
 }

 minMax.push_back(v[iterator1]); //push back largest string
 minMax.push_back(v[iterator2]); //push back smallest string

 return minMax;
}

//find alphabetically first and last string
vector<string> findAlphaB(vector<string> v_copy)
{
 vector<string> alpha;

 //sort the copy to be in alphabetical order
 sort(v_copy.begin(), v_copy.end());

 alpha.push_back(v_copy[0]);
 alpha.push_back(v_copy[v_copy.size() - 1]);

 return alpha;
}

int main()
{
 vector<string> words = { "keyboard", "cat", "nyan", "cat", "tank", "cat", "hipster", "kitty", "grumpy", "cat" };

 //find number of character in each string
 vector<int> numChar = findNumChars(words);

 //find largest and shortest strings
 vector<string> minMax = findMinMax(words);

 //find alphabetically first and last string
 vector<string> alphaB = findAlphaB(words);

 //print results
 print(numChar, minMax, alphaB);

 keep_window_open();

 return 0;
}

You could do separate functions for every task, for example, a function that only finds the longest string and a function that only finds the shortest string however, to save on code and efficiency, I decided to return these values as vectors. That way we know that the vectors (apart from number of chars in a string) will only ever have 2 values in them; the largest followed by the smallest and the first alphabetical word followed by the last. There should technically be separate print functions however we know exactly what the size of 2 vectors will be, so I consider it OK to directly access the items in them.

Saturday, 5 May 2018

Chapter 8 // Exercise 12 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

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


Chapter 8 // Exercise 12



12. Improve print_until_s() from section 8.5.2. Test it. What makes a good set of test cases? Give reasons. Then, write a print_until_ss() that prints until it sees a second occurrence of its quit argument.


#include "stdafx.h"
#include "std_lib_facilities.h"

void print_until_s(const vector<string> &v, string quit)
{
 //for every 's' in 'v'
 for (string s : v)
 {
  if (s == quit)
   return;

  cout << s << " ";
 }
}

int main()
{
 vector<string> words = { "this", "is", "the", "ultimate", "showdown", "of", "ultimate", "destiny",
 "good", "guys", "bad", "guys", "and", "explosions", "as", "far", "as", "the", "eye", "can", "see" };

 print_until_s(words, "and");

 cout << '\n' << endl;

 keep_window_open();

 return 0;
}


I made the vector a const pointer as we aren't modifying any values and generally formatted it to a style that I prefer (it really annoys me when the bracket starts on the same line as the argument). As for testing, this works quite well but stops at the first instance of the word, which is a given. It also prints the entire vector if no quit word is found.


#include "stdafx.h"
#include "std_lib_facilities.h"

void print_until_ss(const vector<string> &v, string quit)
{
 int quitFound = 0;

 //for every 's' in 'v'
 for (string s : v)
 {
  if (s == quit)
   ++quitFound;
  else if (quitFound == 2)
   return;

  cout << s << " ";
 }
}

int main()
{
 vector<string> words = { "this", "is", "the", "ultimate", "showdown", "of", "ultimate", "destiny",
 "good", "guys", "bad", "guys", "and", "explosions", "as", "far", "as", "the", "eye", "can", "see" };

 print_until_ss(words, "ultimate");

 cout << '\n' << endl;

 keep_window_open();

 return 0;
}

Wednesday, 2 May 2018

Chapter 8 // Exercise 11 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

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


Chapter 8 // Exercise 11



11. Write a function that finds the smallest and the largest element of a vector argument and also computes the mean and median. Do not use global variables. Either return a struct containing the results or pass them back through reference arguments. Which of the two ways of returning several result values do you prefer and why?

#include "stdafx.h"
#include "std_lib_facilities.h"

struct stats
{
 double smallest;
 double largest;
 double mean;
 double median;
};

//print vectors to the screen
void print(const vector<double>& price)
{
 for (int i = 0; i < price.size(); ++i)
 {
  cout << price[i] << endl;
 }

 cout << "--------------------------------" << endl;
}

//print struct
void print(const stats& s)
{
 cout << "Largest: " << s.largest << endl;
 cout << "Smallest: " << s.smallest << endl;
 cout << "Mean: " << s.mean << endl;
 cout << "Median: " << s.median << endl;
}

stats findVectorStats(const vector<double>& v, vector<double> v_copy, stats& stat)
{ 
 //initialise values
 stat.largest = v[0];
 stat.smallest = v[0];
 stat.mean = v[0];
 stat.median = v[0];
 
 //if vector only has 1 value return that
 if (v.size() == 1)
  return stat;

 for (int i = 0; i < v.size(); ++i)
 {
  //if next value is bigger than last, make that new largest
  if (stat.largest < v[i])
   stat.largest = v[i];
  //if next value is smaller than last, make than new min
  else if (stat.smallest > v[i])
   stat.smallest = v[i];

  //add numbers together for mean calculation
  stat.mean += v[i];
 }

 //find mean
 stat.mean = stat.mean / v.size();

 //find median by sorting to find middle number
 sort(v_copy.begin(), v_copy.end()); //put in ascending order

 //if vector has odd number of items
 if (v_copy.size() % 2 != 0)
 {
  stat.median = v_copy[(v_copy.size() / 2)];
 }
 //if vector has even number of items
 else
 {
  stat.median = (v_copy[v_copy.size() / 2 - 1] + v_copy[v_copy.size() / 2]) / 2;
 }

 //return struct
 return stat;
}

int main()
{
 vector<double> numbers = { 1, -9, 2, 3, 3, 3, 1500 };

 stats findStats;
 
 findVectorStats(numbers, numbers, findStats);

 print(findStats);

 keep_window_open();

 return 0;
}


I really wanted to separate all the different operations into their own functions however Bjarne said to create just one. I also decided to return a struct of all the values to save having four separate variables in main().

Saturday, 28 April 2018

Chapter 8 // Exercise 10 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

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


Chapter 8 // Exercise 10



10. Write a function maxv() that returns the largest element of a vector argument.


#include "stdafx.h"
#include "std_lib_facilities.h"

double maxv(const vector<double>& v)
{
 //if vector only has 1 value return that
 if (v.size() == 1)
  return v[0];

 //make first value in vector max value
 double largest = v[0];

 //go through every value, if the next value is bigger
 //than the last, make that the new max value
 for (int i = 0; i < v.size(); ++i)
 {
  if (largest < v[i])
   largest = v[i];
 }

 return largest;
}

int main()
{
 vector<double> numbers = { 1000, 6, -12, 700, 56, 89, -900, 1 };

 double max = maxv(numbers);

 cout << max << endl;

 keep_window_open();

 return 0;
}

At first I tried to use the max_element() function however it didn't seem to like working with vectors, so I used the template code to draft this function. It was a lot simpler than I initially thought. Since Bjarne didn't specify a data type I went with double however you can easily change the data type yourself.