Find the elements of an array based on minimum sum - c++

I've written a loop in C++ to give me 6 random numbers and store them in an array.
What I would like to do is to sum the elements of the array until I get a value larger than a number, "x", but I would like to do this without necessarily adding all the elements. The objective is to find the first elements which sum to the value of x.
For example, array is [1,2,3,4,5,6], and x = 6, so what I would be looking for are the elements [1,2,3].
I've looked at the standard library and have tried using the sum function from "valarray" but this just gives the sum of all the elements. Any ideas on how to code this successfully would be greatly appreciated.

Write a functor that does the addition.
#include <algorithm>
struct SumToo
{
SumToo(int val):m_val(val),m_sum(0) {}
int m_val;
int m_sum;
bool operator()(int next)
{
m_sum += next;
return m_sum >= m_val;
}
};
int main()
{
int data[] = {1,2,3,4,5,6};
int* find = std::find_if(data,data+6,SumToo(6));
}

I'm assuming you just want the first X elements in the array, up until their sum meets or exceeds a threshold (the question was a little vague there).
If so, I don't know how to do that without your own loop:
int sum = 0;
int i = 0;
for( ; i < len; ++i ) {
sum += array[i];
if( sum >= 6 ) {
break;
}
}
Now "i" contains the index at which the sum met or exceeded your threshold.

Avoid the answers that suggest using find_if with a stateful predicate. Stateful predicates are dangerous as the STL algorithms assume it is safe to copy predicates. In this case, if copies are made of the predicate then each will have a different 'running total' and will not necessarily act on all values, or in the correct order.
Especially avoid the solution that implements its predicate's operator() member as a const member function but labels its members as mutable as this is fooling you into thinking it is not a stateful predicate, which is bad.
I'd suggest using either one of the answers that simply loops to find the answer, or the answer that uses an accumulator, as that is the most correct way to do it (even if the code looks a little unwieldy.
Note that the warnings may well not apply to C arrays and find_if; I just don't want you to learn that stateful predicates are the right way to solve your problem since you may end up using that incorrect solution in a situation where it is dangerous in future.
Reference: C++ Coding Standards: 101 Rules, Guidelines, and Best Practices, Item 87

Here's a slightly more generic version:
#include <iostream>
#include <algorithm>
// return an iterator _Last such that sum
// of all elements in the range [_First, _Last)
// satisfies the predicate Func
template<class InIt,
class Ty,
class Fn> inline
InIt accumulate_if(InIt First, InIt Last, Ty Val, Fn Func)
{
for (; Func(Val) && First != Last; ++First)
Val = Val + *First;
return (First);
}
int main() {
int num[] = {1, 2, 3, 4, 5, 6};
int *last = accumulate_if(num, num + sizeof num / sizeof num[ 0 ],
0, std::bind2nd(std::less<int>(), 6));
std::copy(num, last, std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}

Substract the numbers from x one by one, until you reach 0 or lower.
No additions, as you wished :)

Here's hoping this works:
/* Returns an index i, given array valarray[0,1..n] and number x where i is an index to valarry such that sum over j of valarray[j] for j = 0 to i > x */
int getFirstSum(int *valarray, int n, int x)
{
int i = 0;
int sum = x;
while(sum > x && i < n)
{
i++;
sum -= valarray[i];
}
return i;
}

would be something like:
struct StopAtValue{
StopAtValue(int sum) : m_sum(sum), m_accumulated(0){}
bool operator()(int val){
m_accumulated += val;
return m_accumulated >= sum;
}
int m_sum;
int m_accumulated;
}
int* pos = std::find_if(&array[0], &array[n], StopAtValue(6));

Well, i would use a vector
T addUntil(T array[],size_t len,T thres){
vector<T> vec = vector_from_array(array,len)
T sum;
for (size_t i=0;i< vec.size(),sum<thresh;i++){
sum+= vec[i];
}
return sum;
}
T would need operator+ and operator< to be defined.

You could use std::find_if() along with a functor that maintains a running total, and only returtn true from the functor when you have found the element that puts you at or over the top.
For example:
#include <cstdlib>
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
using namespace std;
// functor returns true when the running total >= findVal
struct running_total : public unary_function<int, bool>
{
running_total(int findVal) : findVal_(findVal), runningTtl_(0) {};
bool operator()(int rhs) const
{
runningTtl_ += rhs;
if( runningTtl_ >= findVal_ )
return true;
else
return false;
}
private:
mutable int runningTtl_;
const int findVal_;
};
int main()
{
int nums[] = {1, 2, 3, 4, 5, 6};
size_t count = sizeof(nums)/sizeof(nums[0]);
const int scanTtl = 6; // running total to scan to
int * pos = find_if(&nums[0], &nums[0]+count, running_total(scanTtl));
cout << "Elements Totaling " << scanTtl << " : ";
copy(&nums[0], pos+1, ostream_iterator<int>(cout, ", "));
return 0;
}

Related

Why make_heap() is not making minimum heap?

I am trying to make_heap() a vector of integers with a comparator function for minimum integer ordering, but when I am trying to check front value of the vector (which should be the lowest among the heap values), it is not 1. Even after debugging my code, I can't figure out why. Basically, I want to extract lowest integer data for n no. of times from the heap where n = no. of data in the vector. Thank you.
The final data of result variable must be {1,2}.
This is my code
#include <vector>
#include <algorithm>
#include <iostream>
std::vector<int> targetIndices(std::vector<int>& nums, int target) {
int i = 0, j = nums.size() - 1;
std::vector<int> result;
std::make_heap(nums.begin(),nums.end(),std::greater<int>());
while(nums.size()) {
std::pop_heap(nums.begin(), nums.end(),std::greater<int>());
int data = nums.front();
nums.pop_back();
if(data > target) return result;
if(data == target) result.push_back(i);
i++;
}
return result;
}
int main() {
std::vector<int> nums = {2,5,2,3,1};
std::vector<int> result = targetIndices(nums, 2);
for(int i : result)
std::cout << i <<std::endl;
}

Finding the second smallest sum of contiguous sub arrays

I am writing a function that takes in a pointer that points to an array that is dynamically allocated, in addition to the length of the array. I am trying to find the second smallest sum of it's contiguous sub arrays.
I have been writing code to calculate the second smallest value in an array, and also a piece of code that calculates the sum of all the contiguous sub arrays. I was hoping that I would be able to "merge" these two pieces together to get what my desired end result, but I am getting stuck. I would really appreciate any help.
Thank you.
#include <iostream>
using namespace std;
int secondSmallestSum(int *numbers,int length)
{
//Below shows the sum of all contiguous sub arrays.
for(i = 0; i<= length; ++i)
{
int sum = 0;
for(int j = i; j <= length; ++j)
{
sum+=*(numbers+j);
}
}
//Below calculates the second smallest element in an array
int smallest, secondsmallest;
if (*numbers < *(numbers+1))
{
smallest = *numbers;
secondsmallest = *(numbers+1) ;
}
else {
smallest = *(numbers+1) ;
secondsmallest = *(numbers) ;
}
for (i = 2; i < length; i++) {
if (*(numbers+i) < smallest)
{
secondsmallest = smallest;
smallest = *(numbers+i);
}
else if (*(numbers+i) < secondsmallest)
{
secondsmallest = *(numbers+i);
}
}
}
You can do something like this (of course you need to add range checking).
#include <iostream>
#include <vector>
#include <algorithm>
int main(int argc, char** argv) {
std::vector<int> v{3, 1, 4, 5, 6, 2};
std::nth_element(v.begin(), v.begin() + 1, v.end());
std::cout << "The second smallest element is " << v[1] << "\n";
}
Note: using nth_element will change the order of the elements in the vector.
Correct me if I understand you wrong,
by looking at "find the second smallest sum of it's contiguous sub arrays" and the code you posted, I'm assuming your logic is
calculate all sums of all possible contiguous sub arrays
find the second smallest value in the sums
Actually there is a well known algorithm, Kadane's algorithm, that serves a similar purpose (only Kadane's finds THE smallest, not second smallest). You may want to Google it to find more.
Back to your question, I believe the following code does what you want. The code is a variant of Kadane's algorithm.
#include <climits> // for INT_MAX
int findSecondMinOfContiguousSubarray(int arr[], int n)
{
// to store the minimum value that is ending
// up to the current index
int min_ending_here = INT_MAX;
int min = INT_MAX; // absolute min
int min_second = INT_MAX - 1; // second min <- this is what you want
// traverse the array elements
for (int i = 0; i<n/*it is <, not <=*/; i++)
{
// if min_ending_here > 0, then it could not possibly
// contribute to the minimum sum further
if (min_ending_here > 0)
min_ending_here = arr[i];
// else add the value arr[i] to min_ending_here
else
min_ending_here += arr[i];
// update min and min_second
if (min_second > min_ending_here) {
if (min > min_ending_here) {
min_second = min;
min = min_ending_here;
}
else {
min_second = min_ending_here;
}
}
}
return min_second;
}
BTW, I think your code (the piece under //Below shows the sum of all contiguous sub arrays.) can not find all contiguous sub arrays.
An example, arr={1, 2, 3}, your code only consider {1,2,3}, {2,3} and {3} as contiguous sub arrays, while in fact {1,2} should also be considered.
Brutal force o(n^2) complexity (in C++ style not C style):
template<typename Container, typename Func>
void forEachSubrange(Container &container, Func &&f)
{
for (auto subBegin = container.begin(); subBegin != container.end(); ++subBegin)
{
auto subEnd = subBegin;
do {
++subEnd;
f(subBegin, subEnd);
} while (subEnd != container.end());
}
}
int secondSmallestSubrangeSum(const std::vector<int> &a)
{
int firstSum = 0; // empty sub range has zero sum
int secondSum = 0;
forEachSubrange(a, [&firstSum, &secondSum](auto b, auto e) {
auto sum = std::accumulate(b, e, 0);
if (sum < firstSum) {
secondSum = firstSum;
firstSum = sum;
} else if (sum < secondSum) {
secondSum = sum;
}
});
return secondSum;
}
I'm sure it is possible to achieve o(n).
https://wandbox.org/permlink/9cplKBIpfZBPpZ27
or more talkative https://wandbox.org/permlink/X21TdH6xtbMLpV19

Filling a new vector by sampling without replacement from an old one

Is there a good and efficient algorithm in C++ for sampling without replacement that could easily be applied to the following function?
It takes two vectors, new and old, and fills the latter in a loop by repeatedly sampling from the former (rng.i0 is a random number generator function that I use to return a random integer between 0 and given value).
void diluationexpansionstep(std::vector<long> &oldpopulation,
std::vector<long> &newpopulation,
long newpopsize)
{
for (int i = 1; i <= newpopsize;i++) {
int index_a = rng.i0(oldpopulation.size());
newpopulation.push_back(oldpopulation[index_a]);
}
}
Update::
Thank you for helpful responses. Because i want to use my own RNG rather than the inbuilt one in C++ i ended constructing the following Fisher Yates based function where rng.i0 is a function that returns a random intiger between 0 and integer parameter.
void FisherYatesShuffle(vector<long> &indices){
for (int k = 0; k < indices.size(); k++) {
int r = k + rng.i0(indices.size()-k);
swap(indices[k], indices[r]);
}
}
void diluationexpansionstep(std::vector<long> &oldpopulation,
std::vector<long> &newpopulation,
long newpopsize){
vector<long> indices(oldpopulation.size());
std::iota(std::begin(indices),std::end(indices),0);
FisherYatesShuffle(indices);
for (int i = 0; i <= newpopsize-1;i++){
newpopulation.push_back(oldpopulation[indices[i]]);
}
}
As far as i can tell this work accurately and reasonably quickly.
A "good and efficient" algorithm for minimizing developer time and maximizing correctness, using std::random_shuffle from <algorithm>:
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;
vector<long> random_sample_without_replacement(const vector<long>& source, int newpopsize)
{
assert(newpopsize >= 0 && newpopsize <= source.size());
auto result { source };
std::random_shuffle(result.begin(), result.end());
result.resize(newpopsize);
return result;
}
int main() {
vector<long> test { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
auto result { random_sample_without_replacement(test, 5) };
for (auto& e : result) cout << e << " ";
cout << endl;
return 0;
}
Working example here.

Element at index in a std::set?

I've stumbled upon this problem: I can't seem to select the item at the index' position in a normal std::set. Is this a bug in STD?
Below a simple example:
#include <iostream>
#include <set>
int main()
{
std::set<int> my_set;
my_set.insert(0x4A);
my_set.insert(0x4F);
my_set.insert(0x4B);
my_set.insert(0x45);
for (std::set<int>::iterator it=my_set.begin(); it!=my_set.end(); ++it)
std::cout << ' ' << char(*it); // ups the ordering
//int x = my_set[0]; // this causes a crash!
}
Anything I can do to fix the issue?
It doesn't cause a crash, it just doesn't compile. set doesn't have access by index.
You can get the nth element like this:
std::set<int>::iterator it = my_set.begin();
std::advance(it, n);
int x = *it;
Assuming my_set.size() > n, of course. You should be aware that this operation takes time approximately proportional to n. In C++11 there's a nicer way of writing it:
int x = *std::next(my_set.begin(), n);
Again, you have to know that n is in bounds first.
Try this you will be able to use set in another way namely ordered_set
This is very much used in CP
Hope this is diff from all and will help you/someone!
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>
Now you can use
order_of_key (k) : Number of items strictly smaller than k .
find_by_order(k) : K-th element in a set (counting from zero). //This is what you need
[https://www.geeksforgeeks.org/ordered-set-gnu-c-pbds/][1]
A usual implementation of std::set is to use binary search trees, notably self-balancing binary search trees such as red-black trees
They don't give you constant time access to the n-th element. However, you seems to want the first. So try in C++11:
auto it = my_set.begin();
int first=0;
if (it != my_set.end()) first = *it;
There is no way you can access it in constant time.
But you can reach to any element in O(n) time.
E.g.
std::set<int>::iterator it;
it=my_set.begin();
advance(it,n);
cout<<*it;
I don't think std::set has any methods of doing this in better than O(n) time, but I recently made this data structure using a set and a Binary Index Tree that can do most things the std::set can do, but it can also get the index of an element in O(log n) time, as well as the element at a specific index in O((log n) * (log n)) time:
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <math.h>
#include <vector>
#include <queue>
#include <bitset>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
using namespace std;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef long long ll;
typedef pair<ll, ll> pll;
#define max(n, m) ((n>m)?n:m)
#define min(n, m) ((n<m)?n:m)
#define f first
#define s second
struct ss
{
// binary index tree (to mark elements)
int bit[1000010]; // set this number to the max you will use
// set (to store the numbers in order)
set<int> nums;
// the maximum element in the set (NOTE: this data structure works with marking in the BIT array, but you can make this better by using an unordered set to store all values that could appear inside of the set, but this will increase runtime by a high constant factor)
int mx;
// constructor
ss(int maxEl)
{
mx = maxEl + 5;
}
int sum(int arr[], int idx)
{
int ans = 0;
idx ++;
if(idx > mx + 5) return -1;
while(idx > 0)
{
ans += arr[idx];
idx -= idx & (-idx);
}
return ans;
}
void update(int arr[], int idx, int val, int size)
{
idx ++;
while(idx <= size)
{
arr[idx] += val;
idx += idx & (-idx);
}
}
int bs(int l, int r, int idx)
{
int mid = (l + r) / 2;
if(l == r) return mid + 1;
if(l == r - 1)
{
if(sum(bit, r) == idx) return r + 1;
return r;
}
if(sum(bit, mid) <= idx) return bs(mid, r, idx);
return bs(l, mid - 1, idx);
}
// regular set functions
set<int>::iterator find(int num) { return nums.find(num); }
set<int>::iterator lower_bound(int num) { return nums.lower_bound(num); }
set<int>::iterator upper_bound(int num) { return nums.upper_bound(num); }
int size() { return (int)nums.size(); }
set<int>::iterator begin() { return nums.begin(); }
set<int>::iterator end() { return nums.end(); }
bool empty() { return nums.empty(); }
// slightly modified insert and erase functions to also mark stuff in BIT (still O(log n) though)
void insert(int num)
{
if(nums.find(num) == nums.end())
update(bit, num, 1, mx); // marks the element in the BIT if it doesn't already exist
nums.insert(num);
}
void erase(int num)
{
if(nums.find(num) != nums.end())
update(bit, num, -1, mx); // unmarks the element in the BIT if it exists in the set
nums.erase(num);
}
// gets index (0-indexed) of a specific element in O(log n), returns -1 if element not in set
int idx(int num)
{
if(nums.find(num) == nums.end())
return -1;
return sum(bit, num - 1);
}
// gets the iterator of the element at a specific index (0-indexed) in O((log n) * (log n)), returns end of set if idx is invalid
set<int>::iterator at(int idx)
{
if(idx < 0 || idx >= nums.size())
return nums.end();
return nums.find(bs(0, mx, idx));
}
};
int main()
{
ss test = ss(1000);
test.insert(1);
test.insert(3);
test.insert(5);
test.insert(1);
test.insert(9);
test.insert(1000);
cout << *test.at(1) << "\n";
test.erase(3);
cout << *test.at(1) << "\n";
cout << test.idx(1) << "\n";
cout << *test.at(-1) << "\n";
}
This set does have some flaws since it marks elements in the Binary Indexed Tree, so the elements cannot be negative or really big without some extra modifications, but it can still be helpful in some cases. Also, using an std::map or some other type of map could make the set work with negative numbers, big numbers, as well as other data types, but this would increase the runtime by a factor of O(log n) and I think you would have to know all the elements that could appear in the set beforehand so that you can store them in the correct order inside of the map.
EDIT: I just realized there is already a policy-based data structure called ordered-set that has the same functions as a set but can do the two operations (get element at index and get index of element) in O(log n). Read more here: https://www.geeksforgeeks.org/ordered-set-gnu-c-pbds/. This might not work in all compilers though
This is not a bug in the STD. There is no random access in a std::set. If you need random access by index, you can use std::vector
Sometimes there's a good reason for needing a set you can index into. I had to implement this functionality recently to support a legacy API which has functions to return the number of items, and the item at an index, so that the caller can enumerate the items.
My way of solving the problem is to use std::vector, and use std::equal_range to find and insert or delete items in the set. For example, inserting a new item into the set looks like this:
std:vector<std::string> my_set;
...
std::string new_item("test");
auto range = std::equal_range(my_set.begin(),my_set.end(),new_item);
if (range.first == range.second)
my_set.insert(range.first,new_item);
Deleting is very similar: use equal_range to find the item, and if range.first is not equal to range.second, delete that range.
i believe the most optimal way, especially if this indexing happens in a loop, is to convert to a vector.
auto my_vect = std::vector(my_set.begin(), my_set.end()); // O[n]
int output = my_vect[n]; // O[1]
std::set<int> my_set;
my_set.insert(0x4A);
my_set.insert(0x4F);
my_set.insert(0x4B);
my_set.insert(0x45);
int arr[my_set.size()];
set<int>::iterator it = my_set.begin();
for (int i = 0; i < my_set.size(); i++) {
arr[i] = *it;
it++;
}
cout << arr[0];
Edit: Edited code. You can't access set using index but the above method would provide an "index" i if you want to copy the elements from set into an array, provided you have created an array of sufficient size before hand.

Computing the scalar product of two vectors in C++

I am trying to write a program with a function double_product(vector<double> a, vector<double> b) that computes the scalar product of two vectors. The scalar product is
$a_{0}b_{0}+a_{1}b_{1}+...+a_{n-1}b_{n-1}$.
Here is what I have. It is a mess, but I am trying!
#include <iostream>
#include <vector>
using namespace std;
class Scalar_product
{
public:
Scalar_product(vector<double> a, vector<double> b);
};
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
int main() {
cout << product << endl;
return 0;
}
Unless you need to do this on your own (e.g., writing it is homework), you should really use the standard algorithm that's already written to do exactly what you want:
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<double> a {1, 2, 3};
std::vector<double> b {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(std::begin(a), std::end(a), std::begin(b), 0.0);
return 0;
}
Note that while begin(a) and end(a) are new in C++11, std::inner_product has been available since C++98. If you are using C++ 98 (or 03), it's pretty easy to write your own equivalent of begin and end to work with arrays though:
template <class T, size_t N>
T *begin(T (&array)[N]) {
return array;
}
template <class T, size_t N>
T *end(T (&array)[N]) {
return array + N;
}
Using these, a C++ 98 version of the previous code could look something like this:
int main() {
double a[] = {1, 2, 3};
double b[] = {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(begin(a), end(a), begin(b), 0.0);
return 0;
}
Note that the begin and end above will only work for arrays, where the begin and end in C++11 (and later) will also work for normal collection types that define a .begin() and .end() (though it's trivial to add overloads to handle those as well, of course):
template <class Coll>
typename Coll::iterator begin(Coll const& c) { return c.begin(); }
template <class Coll>
typename Coll::iterator end(Coll const& c) { return c.end(); }
You can delete the class you have defined. You don't need it.
In your scalar_product function:
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
It's almost there. You don't need 2 loops. Just one.
double scalar_product(vector<double> a, vector<double> b)
{
if( a.size() != b.size() ) // error check
{
puts( "Error a's size not equal to b's size" ) ;
return -1 ; // not defined
}
// compute
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
product += (a[i])*(b[i]); // += means add to product
return product;
}
Now to call this function, you need to create 2 vector objects in your main(), fill them with values, (the same number of values of course!) and then call scalar_product( first_vector_that_you_create, second_vector_object );
While you have been presented many solutions that work, let me spin up another variation to introduce a couple of concepts that should help you writing better code:
class are only needed to pack data together
a function should check its preconditions as soon as possible, those should be documented
a function should have postconditions, those should be documented
code reuse is the cornerstone of maintenable programs
With that in mind:
// Takes two vectors of the same size and computes their scalar product
// Returns a positive value
double scalar_product(std::vector<double> const& a, std::vector<double> const& b)
{
if (a.size() != b.size()) { throw std::runtime_error("different sizes"); }
return std::inner_product(a.begin(), a.end(), b.begin(), 0.0);
} // scalar_product
You could decide to use the inner_product algorithm directly but let's face it:
it requires four arguments, not two
it does not check for its arguments being of the same size
so it's better to wrap it.
Note: I used const& to indicate to the compiler not to copy the vectors.
You seem to want to make a class specifically for vectors. The class I made in my example is tailored to 3 dimensional vectors, but you can change it to another if desired. The class holds i,j,k but also can conduct a scalar products based on other MathVectors. The other vector is passed in via a C++ reference. It is hard to deduce what the question was, but I think this might answer it.
#include <iostream>
using namespace std;
class MathVector
{
private:
double i,j,k;
public:
MathVector(double i,double j,double k)
{
this->i=i;
this->j=j;
this->k=k;
}
double getI(){return i;}
double getJ(){return j;}
double getK(){return k;}
double scalar(MathVector &other)
{
return (i*other.getI())+(j*other.getJ())+(k*other.getK());
}
};
int main(int argc, char **argv)
{
MathVector a(1,2,5), b(2,4,1);
cout << a.scalar(b) << endl;
return 0;
}
Here is the code that you should have. I see you have used class in your code, which you do not really need here. Let me know if the question required you to use class.
As you are new and this code might scare you. So, I will try to explain this as I go. Look for comments in the code to understand what is being done and ask if you do not understand.
//Scalar.cpp
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
/**
This function returns the scalar product of two vectors "a" and "b"
*/
double scalar_product(vector<double> a, vector<double> b)
{
//In C++, you should declare every variable before you use it. So, you declare product and initialize it to 0.
double product = 0;
//Here you check whether the two vectors are of equal size. If they are not then the vectors cannot be multiplied for scalar product.
if(a.size()!=b.size()){
cout << "Vectors are not of the same size and hence the scalar product cannot be calculated" << endl;
return -1; //Note: This -1 is not the answer, but just a number indicating that the product is not possible. Some pair of vectors might actually have a -1, but in that case you will not see the error above.
}
//you loop through the vectors. As bobo also pointed you do not need two loops.
for (int i = 0; i < a.size(); i++)
{
product = product + a[i]*b[i];
}
//finally you return the product
return product;
}
//This is your main function that will be executed before anything else.
int main() {
//you declare two vectors "veca" and "vecb" of length 2 each
vector<double> veca(2);
vector<double> vecb(2);
//put some random values into the vectors
veca[0] = 1.5;
veca[1] = .7;
vecb[0] = 1.0;
vecb[1] = .7;
//This is important! You called the function you just defined above with the two parameters as "veca" and "vecb". I hope this cout is simple!
cout << scalar_product(veca,vecb) << endl;
}
If you are using an IDE then just compile and run. If you are using command-line on a Unix-based system with g++ compiler, this is what you will do (where Scalar.cpp is the file containing code):
g++ Scalar.cpp -o scalar
To run it simply type
./scalar
You should get 1.99 as the output of the above program.