Multiply vector elements correspondingly in C++ - c++

So I have two vectors:
vector<int> v1(size);
vector<int> v2(size);
and what I want is to calculate A[0]*B[0] - A[1]*B[1] - A[2]*B[2] - ... - A[n-1]*B[n-1]. I've tried the following
#include <iostream>
#include <vector>
using namespace std;
int main()
{
size_t size = 4;
vector<int> product; int i;
vector<int> v1(size);
vector<int> v2(size);
v1[0] = 2; v2[0] = 4;
v1[1] = 5; v2[1] = 1;
v1[2] = 9; v2[2] = 6;
v1[3] = 3; v2[3] = 7;
for(i=1;i < v1.size();++i){
product.push_back(v1[i]*v2[i]);
}
for(vector<int>::const_iterator i = product.begin(); i != product.end(); ++i)
std::cout << *i << ' ';
return 0;
}
However, this would return 5 54 21 as of v1[1]*v2[1], v1[2]*v2[2] and v1[3]*v2[3] and I want to subtract them from each other: 5-54-21.

Firstly, in your formula, the first product must be added (IOW is positive), while the remaining are subtracted. So you must treat the two cases differently.
Secondly, you can perform the calculation easily by computing an ongoing result, starting from zero:
int result = 0;
if (size >= 1) {
result += v1[0]*v2[0];
for (int i = 1; i < size; ++i)
result -= v1[i]*v2[i];
}
std::cout << result << std::endl;

What about
vector<int> v1{2,5,9,3};
vector<int> v2{4,1,6,7};
int result = std::inner_product(++v1.beginn(),v1.end(),++v2.begin(),v1[0]*v2[0],std::minus<>,std::multiplies<>);
(with C++14)
int result = std::inner_product(++v1.beginn(),v1.end(),++v2.begin(),v1[0]*v2[0],std::minus<int>,std::multiplies<int>);
(with C++98)

Related

Need to add elements of two array together

Adding two integer array elements
if array1 = {0,0,0,0,9,9,9,9}—————> 00009999
and
array2 = {0,0,0,0,0,0,0,1}————————> 00000001
adding the two arrays together should result in 10000 being in array1, since 9999 + 1 = 10000
therefore, the result should be
array1 = {0,0,0,1,0,0,0,0}
Does anyone know how to write a code for this? I was trying to use a while loop which didn't work effectively within another for loop. Fairly new to coding and stack overflow, any help will be appreciated!
CODE THAT I TRIED
Note: both arrays will have the same number of elements, they were initialized with the same size
int length = sizeof(array1)/sizeof(array1[0]);
for(int i = length; i>0; i--){
if(array1[i-1] + array2[i-1] < 10){
array1[i-1] += array2[i-1];
}else{
array1[i-1] = array1[i-1] + array2[i-1] - 10;
if(array1[i-2]!=9){
array1[i-2]++;
} else{
int j = i-2;
while(j == 9){
array1[j] = 0;
j--;
}
array1[j-1]++;
}
}
}
Code below performs base10 arithmetic: you need to iterate the arrays in reverse, do the addition of i-th digit by modulo 10, then carry over any excess digits to the next array element:
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
int a1[] = { 0,0,0,0,9,9,9,9 };
int a2[] = { 0,0,0,0,0,0,0,1 };
const int b = 10;
int s = 0;
for (int i = size(a1) - 1; i >= 0; --i)
{
a1[i] += a2[i] + s;
s = a1[i] / b;
a1[i] %= b;
}
std::copy(a1, a1 + size(a1), ostream_iterator<int>(cout, " "));
cout << endl;
}
Alternative with C arrays and transform algorithm + make_reverse_iterator looks too heavy. Variant with std::arrays looks better:
#include <algorithm>
#include <array>
#include <iterator>
#include <iostream>
using namespace std;
int main()
{
std::array<int, 8> a1 = { 0,0,0,0,9,9,9,9 };
std::array<int, 8> a2 = { 0,0,0,0,0,0,0,1 };
const int b = 10;
int s = 0;
transform(a1.rbegin(), a1.rend(), a2.rbegin(), a1.rbegin(), [b, &s](int &i, int &j)
{
i += j + s;
s = i / b;
return i % b;
});
copy(a1.begin(), a1.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}
It looks like you've overcomplicated the problem a bit. Your task is to perform base 10 addition on two arrays, carrying excess digits. You can simply iterate both arrays in reverse, perform addition on the individual elements, and ensure you carry over a digit when you exceed 10.
Here is an example based on the requirements you've described. You can further abstract this as needed.
I updated this code such that the result is now in array1.
#include <iostream>
int main(int argc, char *argv[], char *argp[]){
/* Initialize arrays and calculate array size */
int array1[] = {0,0,0,0,9,9,9,9};
int array2[] = {0,0,0,0,0,0,0,1};
int array_size = sizeof(array1) / sizeof(int);
/* Iterate the arrays in reverse */
int carry = 0;
for (int i = array_size - 1; i >= 0; i--) {
/* Perform addition on the current elements, remembering to include the carry digit */
int result = array1[i] + array2[i] + carry;
/* Determine if the addition should result in another carry */
if (result >= 10) {
carry = 1;
} else {
carry = 0;
}
/* Store the non-carried addition result */
array1[i] = result % 10;
}
/* View result */
for (int i = 0; i < array_size; i++) {
std::cout << array1[i];
}
std::cout << std::endl;
return 0;
}
uint32_t decode(int array[8]){
uint32_t multiple_of_ten=10000000;
uint32_t result = 0;
for(int i=0;i<8;i++){
result += (array[i] * multiple_of_ten);
multiple_of_ten = multiple_of_ten / 10;
}
return result;
}
int* encode(uint32_t number){
int result[8]={0,0,0,0,0,0,0,0};
uint32_t multiple_of_ten=10000000;
uint32_t recent = number;
for(int i=0;i<8;i++){
if(recent>0 && recent / multiple_of_ten > 0)
{
result[i] = recent / multiple_of_ten;
recent %= multiple_of_ten;
}
multiple_of_ten /= 10;
}
return result;
}
in your case , use encode(decode(array1) + decode(array2))

double recursion segmentation fault c++

I've recently written this quicksort sorting algorithm. After compiling I get a "segmentation fault (core dumped)". I debugged it and it turned out that line 25 causes the problem:
v2 = quicksort(v2);
However, I do not know why I get a the "core dumped", as I have no idea what's the problem with this line.
Here's my code:
#include <iostream>
#include <vector>
#include <random>
using namespace std;
vector <float> quicksort(vector <float> Vec)
{
if(Vec.size() > 1)
{
float pivot = Vec[(Vec.size())/2-1];
vector <float> v1, v2;
vector <float> V;
for(unsigned int i = 0; i < Vec.size(); i++)
{
if(Vec[i] >= pivot)
v2.push_back(Vec[i]);
else
v1.push_back(Vec[i]);
}
v1 = quicksort(v1);
v2 = quicksort(v2);
//after debuggung, I found out that the line above causes the "segmentation fault (core dumped)" (line 25)
for(unsigned int i = 0; i < v1.size(); i++)
V.push_back(v1[i]);
for(unsigned int i = 0; i < v2.size(); i++)
V.push_back(v2[i]);
return V;
}
else
{
return Vec;
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
vector <float> v;
for(int i = 0; i < 100; i++)
{
v.push_back(rand() % 100);
cout << v[i] << " ";
}
v = quicksort(v);
for(int i = 0; i < 100; i++)
{
cout << v[i] << " ";
}
return 0;
}
Thanks for the help.
First of all, to get a totally random number using rand() you need to seed the number generator. To do this you include the "time.h" library and then write: srand (time(NULL));
Secondly, your quicksort takes two parameters, a vector named Vec and an int f, that isn't used for anything. Take int f of the function's parameters.
Thirdly, the problem is that an infinite loop is happening in this part of the code (lines 17 to 23):
for(unsigned int i = 0; i < Vec.size(); i++){
if(Vec[i] >= pivot)
v2.push_back(Vec[i]);
else
v1.push_back(Vec[i]);
}
Imagine that our Vec vector is {2, 3} (this were the actual values, because we didn't seed the random number generation).
What's happening is that we have our pivot = 2, and then we are saying that if Vec[0], which is 2, is bigger or equal than the pivot, we add Vec[0] to v2, and then the same for Vec[1], which is 3.
Then this loops infinitely, because then you say v2 = quicksort(v2);. That will make Vec = v2. And that means that it will never get smaller, because, again, Vec is {2, 3}, and therefore our pivot = 2.
It goes in stack overflow.
If the pivot is the maximum number of the vector Vec it has to be dragged from Vinf into Vsup.
#include <iostream>
#include <vector>
#include <random>
using namespace std;
vector <float> quicksort(vector <float> Vec) { //the int f was never used un the function
if (Vec.size() > 1){
vector <float> Vinf, Vsup, Vtmp;
Vinf.push_back(Vec[(Vec.size()) / 2 - 1]);
float pivot = Vinf[0];
Vec.erase(Vec.begin() + Vec.size() / 2 - 1);
for (unsigned int i = 0; i < Vec.size(); i++)
Vec[i] > pivot ? Vsup.push_back(Vec[i]) : Vinf.push_back(Vec[i]);
if (Vinf.size() == Vec.size() + 1) {
Vsup.push_back(pivot);
Vinf.erase(Vinf.begin());
}
Vinf = quicksort(Vinf);
Vsup = quicksort(Vsup);
for (unsigned int i = 0; i < Vinf.size(); Vtmp.push_back(Vinf[i++]));
for (unsigned int i = 0; i < Vsup.size(); Vtmp.push_back(Vsup[i++]));
return Vtmp;
}
else
return Vec;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
vector <float> v;
for (int i = 0; i < 100; cout << v[i++] << " ")
v.push_back(rand() % 100);
cout << endl;
v = quicksort(v);
for (int i = 0; i < v.size(); cout << v[i++] << " ");
return 0;
}

returning a vector from function with int input

I am doing an exercise where I'm trying to list Prime Numbers. Instead of simply listing them, I am trying to have them listed in a Vector(dynamic sizing).
I can't understand why I can't get them listed out.
#include "TestFile.h"
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
vector<int> primeCalc(int z)
{
vector<int> myVector;
for (int i = 3; i <= 100; i += 2)
{
float val = i; // Produce float value
int mid = static_cast<int>(sqrt(val));
int j;
for (j = 3; j <= mid; j += 2)
if (i % j == 0)
break;
if (j > mid)
myVector.push_back(i);
}
cout << sizeof(myVector) << endl;
return myVector;
}
int main()
{
int x = 100;
vector<int> myAnswer;
myVector = primeCalc(x);
for (std::vector<char>::const_iterator i = myAnswer.begin(); i != myAnswer.end(); i++)
{
std::cout << *i << ' ';
}
return 0;
}
Edit: Made edits based on suggestions. Got this error: no viable conversion from '__wrap_iter<pointer>' to '__wrap_iter<const_pointer>'. I too don't understand why sizeof() returned a value of 24 when I counted 48 numbers.
You'll need to manually print the contents of an std::vector; you can do this in main() or primeCalc():
for (std::vector<int>::const_iterator i = myVector.begin(); i != myVector.end(); i++) {
std::cout << *i << ' ';
}
If you want primeCalc() to return a vector, you'll need to change its return type from int to std::vector<int>.

Removing zero rows from a Matrix (elegant way)

I have a matrix with some zero rows. I would like to remove the zero rows. The matrix is Nx3. What I've done is simple. I create std::vector in which every three elements represent a row then I convert it to Eigen::MatrixXd. Is there an elegant way to remove the zero rows?
#include <iostream>
#include <vector>
#include <Eigen/Dense>
Eigen::MatrixXd VecToMat(const std::vector<double> vec)
{
int rows(vec.size()/3) , cols(3);
Eigen::MatrixXd temp( rows , cols);
int count(0);
for ( int i(0); i < rows; ++i)
{
temp(i,0) = vec[count];
temp(i,1) = vec[count+1];
temp(i,2) = vec[count+2];
count += 3;
}
return temp;
}
Eigen::MatrixXd getNewMat(Eigen::MatrixXd& Z)
{
std::vector<double> vec;
for ( int i(0); i < Z.rows(); ++i)
{
if ( (Z(i,0) && Z(i,1) && Z(i,2)) != 0 ){
vec.push_back(Z(i,0));
vec.push_back(Z(i,1));
vec.push_back(Z(i,2));
}
}
Eigen::MatrixXd temp = VecToMat(vec);
return temp;
}
int main()
{
Eigen::MatrixXd Z(5,3);
Z.setOnes();
Z(0,0) = 0;
Z(0,1) = 0;
Z(0,2) = 0;
Z(1,0) = 0;
Z(1,1) = 0;
Z(1,2) = 0;
Z(2,0) = 0;
Z(2,1) = 0;
Z(2,2) = 0;
std::cout << Z << std::endl << std::endl;
std::cout << getNewMat(Z) << std::endl;
std::cin.get();
return 0;
}
Here is a full implementation I find quite elegant. Note that this one does not preserve order of non-zero rules, which maybe isn't what you want, but is more efficient both in complexity and lines of code:
void removeZeroRows(Eigen::MatrixXd& mat)
{
Matrix<bool, Dynamic, 1> empty = (mat.array() == 0).rowwise().all();
size_t last = mat.rows() - 1;
for (size_t i = 0; i < last + 1;)
{
if (empty(i))
{
mat.row(i).swap(mat.row(last));
empty.segment<1>(i).swap(empty.segment<1>(last));
--last;
}
else
++i;
}
mat.conservativeResize(last + 1, mat.cols());
}
Basically you can follow a pseudocode like this:
get N = rows, M = columns
iterate by each N
if N[0] = 0 iterate on rows exiting on first non-zero
if N[0] = 0 && .. && N[M] = 0
remove row
For removing single row:
void removeRow(Eigen::MatrixXd& matrix, unsigned int rowToRemove) {
unsigned int numRows = matrix.rows() - 1;
unsigned int numCols = matrix.cols();
unsigned int rowPos = numRows - rowToRemove;
if( rowToRemove < numRows ) {
matrix.block(rowToRemove, 0, rowPos, numCols) = matrix.block(rowToRemove + 1, 0, rowPos,numCols);
}
matrix.conservativeResize(numRows, numCols);
}
Save each nonempty row into a vector, then make a new matrix
vector<block> buffer; //not sure of the type name for the rows
VectorXd zero(3); //or appropriate comparable type
for(int i = 0; i < Z.rows(); i++){ //note: possibly a function call each time
if(Z.row(i) != zero)
//if((Z.row(i) != 0).any()) //broadcasting comparison?
buffer.push_back(Z.row(i));
}
MatrixXd return_value(buffer.size(), 3);
for(int i = buffer.size(); i --> 0;)
return_value.row(i) = buffer[i];
return return_value;
Warning: Resizing the old one instead of making a new one may erase the contents before you can save them.
I can't read the docs from here, so you will have to see for yourself what kind of comparison operations you can do on block objects. As a last result, try row.any() (faster?) or row.squaredNorm() == 0.

Algorithm to compute mode

I'm trying to devise an algorithm in the form of a function that accepts two parameters, an array and the size of the array. I want it to return the mode of the array and if there are multiple modes, return their average. My strategy was to take the array and first sort it. Then count all the occurrences of a number. while that number is occurring, add one to counter and store that count in an array m. So m is holding all the counts and another array q is holding the last value we were comparing.
For example: is my list is {1, 1, 1, 1, 2, 2, 2}
then i would have m[0] = 4 q[0] = 1
and then m[1] = 3 and q[1] = 2.
so the mode is q[0] = 1;
unfortunately i have had no success thus far. hoping someone could help.
float mode(int x[],int n)
{
//Copy array and sort it
int y[n], temp, k = 0, counter = 0, m[n], q[n];
for(int i = 0; i < n; i++)
y[i] = x[i];
for(int pass = 0; pass < n - 1; pass++)
for(int pos = 0; pos < n; pos++)
if(y[pass] > y[pos]) {
temp = y[pass];
y[pass] = y[pos];
y[pos] = temp;
}
for(int i = 0; i < n;){
for(int j = 0; j < n; j++){
while(y[i] == y[j]) {
counter++;
i++;
}
}
m[k] = counter;
q[k] = y[i];
i--; //i should be 1 less since it is referring to an array subscript
k++;
counter = 0;
}
}
Even though you have some good answers already, I decided to post another. I'm not sure it really adds a lot that's new, but I'm not at all sure it doesn't either. If nothing else, I'm pretty sure it uses more standard headers than any of the other answers. :-)
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <map>
#include <iostream>
#include <utility>
#include <functional>
#include <numeric>
int main() {
std::vector<int> inputs{ 1, 1, 1, 1, 2, 2, 2 };
std::unordered_map<int, size_t> counts;
for (int i : inputs)
++counts[i];
std::multimap<size_t, int, std::greater<size_t> > inv;
for (auto p : counts)
inv.insert(std::make_pair(p.second, p.first));
auto e = inv.upper_bound(inv.begin()->first);
double sum = std::accumulate(inv.begin(),
e,
0.0,
[](double a, std::pair<size_t, int> const &b) {return a + b.second; });
std::cout << sum / std::distance(inv.begin(), e);
}
Compared to #Dietmar's answer, this should be faster if you have a lot of repetition in the numbers, but his will probably be faster if the numbers are mostly unique.
Based on the comment, it seems you need to find the values which occur most often and if there are multiple values occurring the same amount of times, you need to produce the average of these. It seems, this can easily be done by std::sort() following by a traversal finding where values change and keeping a few running counts:
template <int Size>
double mode(int const (&x)[Size]) {
std::vector<int> tmp(x, x + Size);
std::sort(tmp.begin(), tmp.end());
int size(0); // size of the largest set so far
int count(0); // number of largest sets
double sum(0); // sum of largest sets
for (auto it(tmp.begin()); it != tmp.end(); ) {
auto end(std::upper_bound(it, tmp.end(), *it));
if (size == std::distance(it, end)) {
sum += *it;
++count;
}
else if (size < std::distance(it, end)) {
size = std::distance(it, end);
sum = *it;
count = 1;
}
it = end;
}
return sum / count;
}
If you simply wish to count the number of occurences then I suggest you use a std::map or std::unordered_map.
If you're mapping a counter to each distinct value then it's an easy task to count occurences using std::map as each key can only be inserted once. To list the distinct numbers in your list simply iterate over the map.
Here's an example of how you could do it:
#include <cstddef>
#include <map>
#include <algorithm>
#include <iostream>
std::map<int, int> getOccurences(const int arr[], const std::size_t len) {
std::map<int, int> m;
for (std::size_t i = 0; i != len; ++i) {
m[arr[i]]++;
}
return m;
}
int main() {
int list[7]{1, 1, 1, 1, 2, 2, 2};
auto occurences = getOccurences(list, 7);
for (auto e : occurences) {
std::cout << "Number " << e.first << " occurs ";
std::cout << e.second << " times" << std::endl;
}
auto average = std::accumulate(std::begin(list), std::end(list), 0.0) / 7;
std::cout << "Average is " << average << std::endl;
}
Output:
Number 1 occurs 4 times
Number 2 occurs 3 times
Average is 1.42857
Here's a working version of your code. m stores the values in the array and q stores their counts. At the end it runs through all the values to get the maximal count, the sum of the modes, and the number of distinct modes.
float mode(int x[],int n)
{
//Copy array and sort it
int y[n], temp, j = 0, k = 0, m[n], q[n];
for(int i = 0; i < n; i++)
y[i] = x[i];
for(int pass = 0; pass < n - 1; pass++)
for(int pos = 0; pos < n; pos++)
if(y[pass] > y[pos]) {
temp = y[pass];
y[pass] = y[pos];
y[pos] = temp;
}
for(int i = 0; i < n;){
j = i;
while (y[j] == y[i]) {
j++;
}
m[k] = y[i];
q[k] = j - i;
k++;
i = j;
}
int max = 0;
int modes_count = 0;
int modes_sum = 0;
for (int i=0; i < k; i++) {
if (q[i] > max) {
max = q[i];
modes_count = 1;
modes_sum = m[i];
} else if (q[i] == max) {
modes_count += 1;
modes_sum += m[i];
}
}
return modes_sum / modes_count;
}