简体   繁体   中英

Function that takes a vector and returns an array

so I have a mini assignment and 1 of the question is as such: In a 100-floor building, a lift starts from the 1st floor and along the way, it stops at different floors to pick up people. This are the floors the lift stops at: 1(the start), 5, 14, 29, 80, 99. Find the difference between each floor the lift stops at.

I have to use as many concepts we learn in class as possible in this mini assignment. So I plan to use a vector (as a container to contain the different number of floors), a function (to calculate the difference between each floor) and returning back an array to print the difference.

How do I write a function which takes a vector, perform some calculations (adjacent_difference in my case) and then return an array.

This is how I would've done it if I were to return another vector, but I do not know how to tweak it to make it return an array instead:

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

std::vector<int> calculateDiff (std::vector<int> v);

int main() 
{
  std::vector<int> vec {1, 5, 14, 29, 80, 99};

  for(auto iterator = vec.begin(); iterator != vec.end(); ++iterator)
  {
    std::cout << "Floors the lift stop at: ";
    std::cout << *iterator << std::endl;
  }

  std::vector<int> diff = calculateDiff(vec);

  for(auto iterator = diff.begin(); iterator != diff.end(); ++iterator)
  {
    std::cout << "Floor Difference: ";
    std::cout << *iterator << std::endl;
  }
}

std::vector<int> calculateDiff (std::vector<int> v)
{
  std::vector <int> floorDiff;

  floorDiff.resize(v.size());
  std::adjacent_difference(v.begin(), v.end(), floorDiff.begin());
  floorDiff.erase(floorDiff.begin()); //First element does not give the difference

  return floorDiff;
}

Using a std::vector as the return type is the best strategy, IMO. However, you'll have to tweak your function a little bit. You have to make sure that floorDiff is as large as v .

std::vector <int> floorDiff(v.size());

That is necessary since std::adjacent_difference does not allocate memory.

If you must return an array for whatever reason, you can simply expand your function a bit.

// Pass the input by const& to avoid the cost of a copy
// and to indicate that it won't be modified in the function.
int* calculateDiff (std::vector<int> const& v)
{
    std::vector <int> floorDiff(v.size());

    floorDiff.resize(v.size());
    std::adjacent_difference(v.begin(), v.end(), floorDiff.begin());

    int* arr = new int[floorDiff.size()-1];
    std::copy(floorDiff.begin()+1, floorDiff.end(), arr);
    return arr;
}

Make sure to deallocate the memory in the calling function.

If you feel a need to use both an array and a vector, it's "more C++" to do it the other way around - passing an "array" (ie a pointer and a size) and returning a vector.
You also get to do some pointer arithmetic and illustrate the generality of <algorithm> in calculateDiff .

std::vector<int> calculateDiff (const int* v, size_t size)
{
  std::vector<int> floorDiff{size};
  std::adjacent_difference(v, v + size, floorDiff.begin());
  floorDiff.erase(floorDiff.begin())
  return floorDiff;
}

Using std::vector throughout is the correct choice, but there are some style issues that you can improve

int main() 
{
  // vec is undescriptive of what it represents
  std::vector<int> floors {1, 5, 14, 29, 80, 99};

  for(auto iterator = floors.begin(); iterator != floors.end(); ++iterator)
  {
    // << can be chained
    std::cout << "Floors the lift stop at: " << *iterator << std::endl;
  }

  // Note that you repeat the "Floors the lift stop at: " 
  // If you only want one line, you can instead:      
  /* 
  std::cout << std::cout << "Floors the lift stop at: ";
  std::copy(floors.begin(), floors.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;
  */

  std::vector<int> diffs = calculateDiffs(vec);

  for(auto iterator = diffs.begin(); iterator != diffs.end(); ++iterator)
  {
    std::cout << "Floor Difference: " << *iterator << std::endl;
  }
  // and again, can std::copy into a std::ostream_iterator
}

std::vector<int> calculateDiffs (std::vector<int> values)
{
  // values is already a copy, as you passed by value
  std::adjacent_difference(values.begin(), values.end(), values.begin());
  values.erase(values.begin()); //First element does not give the difference

  return values;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM