Vectors and Arrays

Document Sample
Vectors and Arrays Powered By Docstoc
					     Chapter 9: Vectors and Arrays
   Chapter Goals
    • To become familiar with using vectors to
      collect objects
    • To be able to access vector elements
      and resize vectors
    • To be able to pass vectors to functions
    • To learn about common array
      algorithms
    • To learn how to use one-dimensional
      and two-dimensional arrays
                                             1
      Using Vectors to Collect Data Items
   Suppose you write a program that read in a list of salary
    figures and prints the list, marking the highest value, like
    this:
                         32000
                         54000
                         67500
                         29000
                         35000
                         80000
        highest value => 115000
                         44500
                         100000
                         65000
   All the values need to be read to find the highest one.
   If you know there are ten inputs, you could use 10
    variables salary1, salary2, ... , salary10.
    But you would have to write a lot of code ten times to
    handle each variable.
   This technique becomes prohibitive as the list gets larger
    (e.g., 100 salaries …).
                                                                   2
Using Vectors to Collect Data Items
   A vector is a collection of data items of the same
    type.
       vector<double> salaries(10);
   This vector holds 10 values, each of which are
    double.




                                                         3
      Using Vectors to Collect Data Items
     (Syntax 9.1 Vector Variable Definition)

   Syntax
    vector<type_name> variable_name
    vector<type_name> var_name(initial_size);

   Example:
    vector<int> scores;
    vector<Employee> staff(20);
   Purpose:
      Define a new variable of vector type, and
      optionally supply an initial size.
                                                  4
Using Vectors to Collect Data Items
   You must specify which slot you want to
    use with the [] operator.
    Example:
       salaries[4] = 35000;
   The number inside the brackets is called
    an index.
   Because salaries is a vector of double
    values, a slot such as salaries[4] can be
    used just like any variable of type double.
    Example:
       cout << salaries[4] << "\n";
                                                  5
Using Vectors to Collect Data Items
              (cont.)
   In C++, the slots
    of vectors are
    numbered starting
    at 0.




                                      6
     Syntax 9.2 : Vector Subscripts
   General Syntax
      vector_expression[integer_expression]

   Example:
      salaries[i + 1]
    • refers to the element in position given
      by the value of expression i+1

   Purpose:
     Access and element in a vector.

                                                7
                Vector Subscripts
   Trying to access a slot that does not exist in the vector is
    an error.
    Example:
        vector<double> staff(10);
        cout << staff[10];
        /* legal subscripts are 0 until 9 */
   The C++ standard implementation of vector generates no
    error message.
   If you make an index error, you silently read or overwrite
    another memory location.
   When a vector is defined without a size parameter, it is
    empty and can hold no elements.
    Example:
       vector<double> salaries;       /* no size given */
       salaries[0] = 35000;
                                                                   8
                Vector Subscripts
   You can find the size vector by calling the size
    function.
       for(i = 0; i < v.size(); i++)
              do something with v[i];
   The function push_back allows you to start out
    with an empty vector and grow the vector
    whenever another element is added.
        vector<double> salaries;
        . . .
        double s;
        cin >> s;
        . . .
        salaries.push_back(s);

                                                       9
           Vector Subscripts (cont.)
   The push_back command resizes the vector by
    adding one element to its end.
   If you already know how many elements you
    need in a vector, you should specify that size
    when you define it.
   Another member function, pop_back, removes
    the last element of a vector, shrinking its size by
    one.
        salaries.pop_back();
        /* Now salaries has size 9 */

   The standard defines many more useful functions
    for vectors; in this book, we only use push_back
    and pop_back.
                                                      10
      Vector Subscripts (salvect.cpp)
01:   #include <iostream>
02:   #include <vector>
03:
04:   using namespace std;
05:
06:   int main() {
08:      vector<double> salaries;
09:      bool more = true;
10:      while (more) {
12:         double s;
13:         cout << "Please enter a salary, 0 to quit: ";
14:         cin >> s;
15:         if (s == 0)
16:            more = false;
17:         else
18:            salaries.push_back(s);
19:      }
20:
21:       double highest = salaries[0];
22:       int i;
23:       for (i = 1; i < salaries.size(); i++)
24:          if (salaries[i] > highest)
25:              highest = salaries[i];
26:
27:       for (i = 0; i < salaries.size(); i++) {
29:          if (salaries[i] == highest)
30:               cout << "highest value => ";
31:               cout << salaries[i] << "\n";
32:       }
34:       return 0;
35:   }



                                                            11
    Vector Parameters and Return Values
            (Vector Parameters)
   Functions and procedures often have vector parameters.
    Example:
        double average(vector<double> v) {
           if (v.size() == 0) return 0;
           double sum = 0;
           for (int i = 0; i < v.size(); i++)
                sum = sum + v[i];
           return sum / v.size();
        }
   A vector can be passed by value or by reference.
   Pass by reference is used for modifying individual elements of the
    vector.
    Example:
        void raise_by_percent(vector<double>& v, double p){
             for (int i = 0; i < v.size(); i++)
                  v[i] =v[i] * (1 + p / 100);
        }
                                                                     12
     Vector Parameters and Return
        Values (Return Values)
   A function can return a vector.
   Here is a function that collects all values
    that fall within a certain range.
    vector<double> between(vector<double> v,
                           double low, double high){
        vector<double> result;
        for (int i = 0; i < v.size(); i++)
           if (low <= v[i] && v[i] <= high)
              result.push_back(v[i]);
        return result;
    }


                                                       13
Vector Parameters and Return Values
       (Return Values) (cont.)
   Here is a function that collects the
    positions of all matching values in a vector
    of integers.
    vector<int> find_all_between(vector<double> v,
                    double low, double high){
        vector<int> pos;
        for (int i = 0; i < v.size(); i++) {
           if (low <= v[i] && v[i] <= high)
              pos.push_back(i);
        }
        return pos;
    }


                                                     14
 Vector Parameters and Return
     Values (matches.cpp)
25: int main() {
27:    vector<double> salaries(5);
28:    salaries[0] = 35000.0;
29:    salaries[1] = 63000.0;
30:    salaries[2] = 48000.0;
31:    salaries[3] = 78000.0;
32:    salaries[4] = 51500.0;
33:
34:    vector<int> matches =
         find_all_between(salaries, 45000.0,
                          65000.0);
36:
37:    for (int j = 0; j < matches.size(); j++)
38:       cout << salaries[matches[j]] << "\n";
39:    return 0;
40: }



                                                  15
    Removing and Inserting Elements
 How do you remove an element from
  a vector?
 If the order is not important,
  overwrite the element to be removed
  with the last element of the vector,
  then shrink the size of the vector.
 Example:

    void erase(vector<string>& v, int pos){
        int last_pos = v.size() - 1;
        v[pos] = v[last_pos];
        v.pop_back();
    }
                                              16
Example of Element Removal




                             17
    Removing and Inserting Elements
   If the order matters, you must move all
    elements down by one slot, then shrink
    the size of the vector.

    void erase(vector<string>& v, int pos) {
        for (int i=pos; i<v.size()-1; i++)
           v[i] = v[i+1];

        v.pop_back();
    }



                                               18
Removing and Inserting Elements




                                  19
    Removing and Inserting Elements
   To insert an insert an element in the middle of a
    vector, you must add a new element at the end
    of the vector and move all elements above the
    insertion location up by one slot.

    void insert(vector<string>& v,
                  int pos, string s) {
       int last = v.size() - 1;
       v.push_back(v[last]);
       for (int i = last; i > pos; i--)
            v[i] = v[i - 1];
            v[pos] = s;
    }

                                                        20
 Removing and Inserting Elements
• Note that when you insert an element you start at the end of the
   vector, move that element up, then go to the one before that.




                                                                     21
                   Parallel Vectors
   Suppose you want to process a series of product
    data, and then display the product information,
    making the best value (with the best price/score
    ratio).
                   ACMA P600 Price: 995 Score75
                   ALaris Nx686 Price 798 Score 57
                   AMAX Powerstation 600 Price: 999 Score 75
                   AMS Infogold P600 Price: 795 Score: 69
                   AST PRemmia Price: 2080 Score: 80
                   Austin 600 Price: 1499 Score: 95
     best value => Blackship NX-600 Price 598 Score: 60
                   Kompac 690 Price: 695 Score: 60


   One possibility is to create three vectors (names,
    price, scores) of the same length. (See
    bestval1.cpp)
   These vectors are called parallel vectors because
    they must be processed together.                 22
         Parallel Vectors (cont.)
• Each slice - names[i], prices[i], scores[i] - contains data
  that needs to be processed together.




                                                            23
Parallel Vectors (bestval1.cpp)
01:   #include <iostream>
02:   #include <string>
03:   #include <vector>
04:
05:   using namespace std;
06:
07:   int main() {
09:      vector<string> names;
10:      vector<double> prices;
11:      vector<int> scores;
12:
13:      double best_price = 1;
14:      int best_score = 0;
15:      int best_index = -1;
16:
17:      bool more = true;
47:



                                  24
               bestval1.cpp (cont.)
18:   while (more) {
20:      string next_name;
21:      cout << "Please enter the model name: ";
22:      getline(cin, next_name); 23:       names.push_back(next_name);
24:      double next_price;
25:      cout << "Please enter the price: ";
26:      cin >> next_price;
27:      prices.push_back(next_price);
28:      int next_score;
29:      cout << "Please enter the score: ";
30:      cin >> next_score;
31:      scores.push_back(next_score);
32:      string remainder; /* read remainder of line */
33:      getline(cin, remainder);
34:
35:       if (next_score / next_price > best_score / best_price) {
37:          best_index = names.size() - 1;
38:          best_score = next_score;
39:          best_price = next_price;
40:       }
41:
42:       cout << "More data? (y/n) ";
43:       string answer;
44:       getline(cin, answer);
45:       if (answer != "y") more = false;
46:   }                                                                   25
           bestval1.cpp (cont.)
48:     for (int i = 0; i < names.size(); i++) {
50:        if (i == best_index)
             cout << "best value => ";
51:        cout << names[i]
52:             << " Price: " << prices[i]
53:           << " Score: " << scores[i] << "\n";
54:     }
55:
56:     return 0;
57: }




                                                    26
              Parallel Vectors
   Parallel vectors become a headache in
    larger programs.
    • Each vector must be the same length.
    • Each slice is filled with values that belong
      together.
    • Any function that operates on a slice must get
      several vectors as parameters.
   To remove parallel vectors, look at the
    slice and find the concept it represents.
    Make the concept into a class.
   Eliminate parallel vectors and replace
    them with a single vector.

                                                   27
       Parallel Vectors Elimination
   Use a class to represent the type of element
    represented in the parallel vectors and use an
    array or vector of that type of element.




                                                     28
       Example : Class Product
012:   class Product {
014:   public:
015:     /**
016:       Constructs a product with zero price and score.
017:     */
018:     Product();
019:
020:     /**
021:       Reads in this product object.
022:     */
023:     void read();
024:
025:     /**
026:       Compares two product objects.
027:       @param b the object to compare with this object
028:       @retur true if this object is better than b
029:     */
030:     bool is_better_than(Product b) const;
031:
032:     /**
033:       Print this product object
034:     */
035:     void print() const;
036:   private:
037:     string name;
038:     double price;
039:     int score;
040:   };
                                                             29
          Class Product (cont.)
042:   Product::Product()
043:   {
044:     price = 0;
045:     score = 0;
046:   }
047:
048:   void Product::read() {
050:     cout << "Please enter the model name: ";
051:     getline(cin, name);
052:     cout << "Please enter the price: ";
053:     cin >> price;
054:     cout << "Please enter the score: ";
055:     cin >> score;
056:     string remainder; /* read remainder of line */
057:     getline(cin, remainder);
058:   }
059:
060:   bool Product::is_better_than(Product b) const {
062:     if (price == 0) return false;
063:     if (b.price == 0) return true;
064:     return score / price > b.score / b.price;
065:   }
066:
067:   void Product::print() const {
069:     cout << name
070:          << " Price: " << price
071:          << " Score: " << score << "\n";
072:   }
073:
                                                          30
     New Version of bestval.cpp
074: int main() {
076: vector<Product> products;
077:
078: Product best_product;
079: int best_index = -1;
080:
081: bool more = true;
082: while (more) {
084:     Product next_product;
085:     next_product.read();
086:     products.push_back(next_product);
087:
088:     if (next_product.is_better_than(best_product))
089:     {
090:        best_index = products.size() - 1;
091:        best_product = next_product;
092:     }
093:
094:     cout << "More data? (y/n) ";
095:     string answer;
096:     getline(cin, answer);
097:     if (answer != "y") more = false;
098: }
099:
100: for (int i = 0; i < products.size(); i++) {
102:     if (i == best_index) cout << "best value => ";
103:     products[i].print();
104: }
105:
106: return 0;
107: }
                                                          31
                     Arrays
   A second mechanism for collecting
    elements of the same type is using arrays.
   Arrays are a lower-level abstraction than
    vectors, so they are less convenient.
    • Example: Arrays cannot be resized.

   Vectors are a recent addition to C++, so
    many older programs use arrays instead.

   Arrays are faster and more efficient than
    vectors.

                                                32
                           Arrays
   Declaring an array is very similar to declaring a
    vector.
    • Array declaration : double salaries[10];
    • Vector declaration : vector<double> salaries(10);

   Arrays can never change size
    • size is fixed in declaration

   The array size must be set when the program is
    compiled. (You can't ask the user how many
    elements and then allocate a sufficient number).
   When defining an array, you must guess on the
    maximum number of elements you need to store.
       const int SALARIES_CAPACITY = 100;
       double salaries[SALARIES_CAPACITY];
                                                          33
                          Arrays
   You must keep a constant to hold the capacity of the array.
   You must keep a companion variable that counts how many
    elements are actually used.
   Example:
    int salaries_size = 0;
    while (more && salaries_size < SALARIES_CAPACITY){
        cout << "Enter salary or 0 to quit: ";
        double x;
        cin >> x;
        if (cin.fail() || x == 0)
           more = false;
        else {
           salaries[salaries_size] = x;
           salaries_size++;
        }
     }



                                                              34
    Arrays (Syntax 9.3: Array Variable Definition)

   Array Variable Definition
       type_name variable_name[size];

   Example:
       int scores[20];

   Purpose:
       Define a new variable of an array
       type.

                                                     35
                  Array Parameters
   When writing a function with an array parameter, you place an
    empty[] behind the parameter name:
     • Example:   double maximum(double a[], int a_size);

   You need to pass the size of the array into the function, because the
    function has no other way of querying the size of the array (there is
    no size() member function)
   Unlike all other parameters, array parameters are always passed by
    reference.
    Example: … alter each of the first s_size elements of s
     void raise_by_percent(double s[],double s_size,double p) {
         int i;
         for (i = 0; i < s_size; i++)
             s[i] = s[i] * (1 + p / 100);
     }

   Never use an & when defining an array parameter.
   Use the const keyword whenever a function does not actually modify
    an array.
    Example: double maximum(const double a[], int a_size)
                                                                     36
                Array Parameters
   If a function adds elements to an array, you need to pass
    the array, the maximum size, and the current size.
   The current size must be passed as a reference parameter.

    • Example:
      void read_data(double a[], int a_capacity,
                     int& a_size) {
        a_size = 0;
        while (a_size < a_capacity) {
              double x;
              cin >> x;
              if (cin.fail()) return;
              a[a_size] = x;
              a_size++;
        }
      }

   Arrays cannot be function return types.
   To "return" an array, the caller of the function must provide
    an array parameter to hold the result.                      37
    Example: reads data into an array
/**
      Reads data into an array.
      @param a the array to fill
      @param a_capacity the maximum size of a
      @param a_size filled with the size of a after reading
*/
      void read_data(double a[], int a_capacity, int& a_size) {
           a_size = 0;
           double x;
           while (a_size < a_capacity && (cin >> x)) {
                  a[a_size] = x;
                  a_size++;
           }
      }

    It assumes the number of values read is <= capacity…


                                                                  38
    Example: max value in an array
/**
   Computes the maximum value in an array
   @param a the array
   @param a_size the number of values in a
*/
double maximum(const double a[], int a_size) {
  if (a_size == 0) return 0;

    double highest = a[0];
    for (int i = 1; i < a_size; i++)
        if (a[i] > highest)
            highest = a[i];

    return highest;
}
                                                 39
                    Character Arrays
   There was a time when C++ had no string class.
   All string processing was carried out by manipulating arrays of the type
    char.
   The char type denotes an individual character and is delimited by single
    quotes.
    Example:
         char input = 'y';
         // don't confuse with "y“

   A character array is used to hold a string.
    Example:
         char g[] = "Hello";
         // same as g[6] = "Hello“
   The array occupies size characters - one for each letter and a zero
    terminator.
         g[0]    g[1]   g[2]   g[3]    g[4]       g[5]
         ‘H’     ‘e’    ‘l’     ‘l’    ‘o’    ‘\0’

   You do not need to specify the size of the array variable for a character
    array constant.
                                                                                40
                  Character Arrays
   Many string functions in the standard library depend on zero
    terminators in character arrays.
    Example:
       int strlen(const char s[]) {
           int i = 0;
           while (s[i] != '\0')
               i++;
           return i;
       }
   It's important to not forget the space for the zero
    terminator. (null character)
   It's helpful to declare character arrays with an "extra space"
    for the zero terminator.
    Example:
       const int MYSTRING_MAXLENGTH = 4;
       char mystring[MYSTRING_MAXLENGTH + 1];
                                                                 41
  Example: append 2nd to 1st string
 /**
       Appends as much as possible from a string to another
        string
       @param s the string to which t is appended
       @param s_maxlength the maximum length of s (not
        counting '\0')
       @param t the string to append
 */
 void append(char s[], int s_maxlength, const char t[]) {
      int i = strlen(s);
      int j = 0;
      /* append t to s */
      while (t[j] != '\0' and i < s_maxlength) {
       s[i] = t[j];
       i++;
        j++;
      }
       /* add zero terminator */
       s[i] = '\0';
}
                                                              42
              Character Arrays
   Generally it is best to avoid the use of character
    arrays - the string class is safer and far more
    convenient.
   Occasionally you need to convert a string into a
    character array to call a function that was written
    before the string class was invented.
    Example: to convert a character array containing
    digits into its integer value.
        int atoi(const char s[])
   Use the c_str member function to convert a
    string into a character array.
    Example:
       string year = "1999";
       int y = atoi(year.c_str());
                                                         43
        Two-Dimensional Arrays
   It often happens that we want to store collections
    of numbers that have a two-dimensional layout.
   Such an arrangement, consisting of row and
    columns of values, is called a two-dimensional
    array, or a matrix.
   C++ uses an array with two subscripts to store a
    two-dimensional array:
    Example:
       const int BALANCE_ROWS = 11;
       const int BALANCE_COLS = 6;
       double balances[BALANCE_ROWS][BALANCE_COLS];

   To select a particular element in the two-
    dimensional array, we need to specify two
    subscripts in separate brackets to select the row
    and column.
                                                        44
Accessing an Element in 2-dim array




                                      45
     Two-Dimensional Array Definition
   Syntax Two-Dimensional Array Definition
    type_name variable_name[size1][size2];

   Example:
    double monthly_sales[NREGIONS][12];
   Purpose:
      Define a new variable that is a two-
      dimensional array.



                                              46
        Two-Dimensional Arrays
   When passing a two-dimensional array to
    a function, you must specify the number
    of columns as a constant with the
    parameter type.
   The number of rows can be variable.
void print_table(const double table[][BALANCE_COLS], int table_rows) {
       const int WIDTH = 10;
       cout << fixed << setprecision(2);
       for (int i = 0; i < table_rows; i++) {
           for (int j = 0; j < BALANCES_COLS; j++)
                  cout << setw(WIDTH) << table[i][j];
           cout << "\n";
       }
}

                                                                         47

				
DOCUMENT INFO