I am trying write C++ programs that compute the dot product of two given vectors. In vectors a and b only nonzero elements will be stored into array of structures. Each time I am getting irrelevant results. The corrrect result is 50. I think i am not able to read the vectors properly into array of structures. Please advice. Thank you in advance
#include <iostream>
#include <vector>
using namespace std;
const int n=10; /* vector size limit */
struct element {
int x; /* original index of non-zero array element */
int val ; /* integer non-zero value at index x */
};
element row[n];
element col[n];
int i;
vector<int> a={0,0,7,0,5,0,0,8,0,4,-1};
vector<int> b={0,0,0,5,6,0,0,0,0,5,-1};
void generate_row_and_col()
{
for (i=0; i<=n; i++)
{
if(a[i]=!0)
{
row[i].x=i;
row[i].val=a[i];
}
}
for (i=0; i<=n; i++)
{
if(b[i]!=0)
{
col[i].x=i;
col[i].val=b[i];
}
}
}
int dotproduct()
{
/* calculate the dot product of row and col output the result*/
int i=0;
int j=0;
int product=0;
while(row[i].x!=-1 && col[j].x!=-1)
{
if(row[i].x == col[j].x)
{
product=product+row[i].val*col[j].val;
i++;
j++;
}
else if(row[i].x<col[j].x)
{
i++;
}
else
{
j++;
}
}
return product;
}
int main()
{
generate_row_and_col() ;
int r;
r=dotproduct();
cout<<"result="<<r<<endl;
return 0;
}
The standard library has std::inner_product for exactly this purpose. Using it reduces your code to something like this:
#include <numeric>
#include <iostream>
#include <vector>
int main() {
std::vector<int> a = { 0,0,7,0,5,0,0,8,0,4 };
std::vector<int> b = { 0,0,0,5,6,0,0,0,0,5 };
std::cout << std::inner_product(a.begin(), a.end(), b.begin(), 0);
}
Using = !0 is a bug. That was supposed to be != 0.
I'm still guessing at the goal, but perhaps another cleaned version helps:
Live On Coliru
#include <iostream>
#include <vector>
#include <map>
using namespace std;
using Ints = vector<int>;
using Vec = map<int, int>;
Vec row, col;
Vec to_sparse_vec(Ints const& a) {
Vec v;
for (size_t i = 0; i < a.size(); ++i) {
if (a[i] != 0) v[i] = a[i];
}
return v;
}
int dotproduct(Vec row, Vec col) {
size_t n = max(row.rbegin()->first, col.rbegin()->first);
int product = 0;
for (size_t i = 0; i <= n; ++i) {
if (row[i] && col[i])
product += row[i] * col[i];
}
return product;
}
int main() {
auto row = to_sparse_vec({ 0, 0, 7, 0, 5, 0, 0, 8, 0, 4 });
auto col = to_sparse_vec({ 0, 0, 0, 5, 6, 0, 0, 0, 0, 5 });
cout << "result=" << dotproduct(row, col) << endl;
}
This assumes the Vec representation is intended as a "sparse vector".
Result is 50 (dropped the -1 elements)
You can simplify your code
#include <iostream>
#include <vector>
using namespace std;
template<class InputIt1, class InputIt2, class T>
T dot_product(InputIt1 first1, InputIt1 last1,
InputIt2 first2, T value)
{
while ((first1 != last1)&&(*first1!=-1) && (*first2 !=-1)) {
value = value + *first1 * *first2;
++first1;
++first2;
}
return value;
}
const int n=10; /* vector size limit */
struct element {
int x; /* original index of non-zero array element */
int val ; /* integer non-zero value at index x */
};
element row[n];
element col[n];
int i;
vector<int> a={0,0,7,0,5,0,0,8,0,4,-1};
vector<int> b={0,0,0,5,6,0,0,0,0,5,-1};
int main()
{
int r;
r=dot_product(a.begin(), a.end(), b.begin(), 0);
cout<<"result="<<r<<endl;
return 0;
}
Output
50
Demo
I have done some changes on the code, it works fine now. But, during initialization row and col arrays on generate_row_and_col function , I only initialize indexes with non zero elements, rest of them are not initialized. This is not causing any error in this program, but in terms of good programming practice,those indexes with 0 values are not initiated and the arrays will look like(garbage, garbage,7, garbage, 5, garbage, garbage....). Can we just limit the generate_row_and_col function, so We can only store non zero value indexes.
Thank you
#include <iostream>
#include <vector>
using namespace std;
const int n=11; /* vector size */
struct element {
int index; /* original index of non-zero array element */
int value ; /* integer non-zero value at index x */
};
element row[n];
element col[n];
vector<int> a={0,0,7,0,5,0,0,8,0,4,-1};
vector<int> b={0,0,0,5,6,0,0,0,0,5,-1};
void generate_row_and_col()
{
for (int i=0; i<n; i++)
{
if(a[i]!=0)
{
row[i].index=i;
row[i].value=a[i];
}
}
for (int j=0; j<n; j++)
{
if(b[j]!=0)
{
col[j].index=j;
col[j].value=b[j];
}
}
}
int dotproduct()
{
/* calculate the dot product of row and col output the result*/
int i=0;
int j=0;
int product=0;
while(row[i].value!=-1 && col[j].value!=-1)
{
if(row[i].index == col[j].index)
{
product=product+row[i].value*col[j].value;
i++;
j++;
}
else if(row[i].index<col[j].index)
{
i++;
}
else
{
j++;
}
}
return product;
}
int main()
{
generate_row_and_col() ;
int r;
r=dotproduct();
cout<<"Dot Product = "<<r<<endl;
return 0;
}
I've neglected to work on this code (or any other coding projects) for a while, so while I know what is basically wrong with the code, I've been having a hard time finding exactly where the vector is going out of range. I've been running gdb on it all morning to no avail. I'm trying to make a min-heap out of a vector "theData" in C++.
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::cin;
using std::cout;
using std::swap;
using std::pair;
using std::make_pair;
class HeapBuilder {
private:
vector<int> data_;
vector< pair<int, int> > swaps_;
void WriteResponse() const {
cout << swaps_.size() << "\n";
for (int i = 0; i < swaps_.size(); ++i) {
cout << swaps_[i].first << " " << swaps_[i].second << "\n";
}
}
void ReadData() {
int n;
cin >> n;
data_.resize(n);
for(int i = 0; i < n; ++i)
cin >> data_[i];
}
void makeMinHeap(vector<int> &theData, int i, int n) {
int minIndex;
int left = 2*i;
int right = 2*i + 1;
if (left < n && theData.at(left) < theData.at(i)) {
minIndex = left;
}
else if (right < n && theData.at(right) < theData.at(i)) {
minIndex = right;
}
if (minIndex != i) {
swap(theData.at(i), theData.at(minIndex));
swaps_.push_back(make_pair(i, minIndex));
makeMinHeap(theData, minIndex, n);
}
}
void GenerateSwaps() {
swaps_.clear();
int size = data_.size();
for (int i = (size/2); i >= 0; i--) {
makeMinHeap(data_, i, size);
}
}
public:
void Solve() {
ReadData();
GenerateSwaps();
WriteResponse();
}
};
int main() {
std::ios_base::sync_with_stdio(false);
HeapBuilder heap_builder;
heap_builder.Solve();
return 0;
}
You are not putting in a check for minIndex.
Look what happens when your left<=n and right <=n both fails, most likely when the whole recursion is about to stop, since you just check
minIndex != i
// ^-- default each time is garbage which in case last>n && right>n leaves it garbage
// hence when it comes to
if(minIndex!=i){
// It's actually true where it was suppose to break out n thus throws out_of_range
}
Quick n easy solution would be to add a flagcheck
bool flagcheck = false;
if(){ flagcheck = true; }
else if(){ flagcheck = true; }
if(minIndex!=i && flagcheck){}
#include <stdio.h>
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int max(int a, int b) {
return a < b ? b : a;
}
bool comp(const string &l, const string &r) {
for (int i = 0; i < max(l.length(), r.length()); i++) {
if (i >= l.length()) return false;
if (i >= r.length()) return true;
if (l[i] < r[i]) return l[i] < r[i];
}
return true;
}
int main(void) {
int N; scanf("%d", &N);
vector<string> v;
for (int i = 0; i < N; i++) {
string s; cin >> s;
v.push_back(s);
}
sort(v.begin(), v.end(), comp);
for (const string& s : v) {
cout << s;
}
cout << endl;
}
In Educational Codeforces Round 9 held on yesterday, I couldn't solve the problem http://codeforces.com/contest/632/problem/C using sort with user-defined function.
I used stl vector containing string and it seems to work on some test cases, but it occurs runtime-error on following testcase.
100
abccaacaacacabbbcbbabcccccacabbaccbcacabcbbbaca
bbbaccbbccbbbcacaabbcccaabcbbcbbbacaacabc
cccabccaaabcaccabccbcccbbaacaaccbb
cccabccaaabcaccabccbcccbbaacaaccbbcb
cccabccaaabcaccabccbcccbbaacaaccbb
cccabccaaabcaccabccbcccbbaacaaccbbbcca
abbbcbbbbbbcccccbcbbb
bbbaccbbccbbbcacaabbcccaabcbbcbbbacaacabcb
abbcacbcabacccbcbabaabcaabcabacbbbbbca
cccabccaaabcaccabccbcccbbaacaaccbbcaa
cbcbbaccacbcababbccaacabacbcabbaccbcbcbcabbc
acbbbbbbbcabbcbcaccccbcbaacccaccabcbaac
bacccabacbbaaa
I can't view the full test input due to codeforces' policy. How do I defeat this situation?
Your comp() predicate doesn't handle the case where l[i] > r[i]. So it returns 1 when comparing "foo" and "boo", and also returns 1 when comparing "boo" and "foo". Therefore, it fails to implement a strict weak ordering (i.e., fails to behave like <=) , and the results of passing it to std::sort() are undefined.
Try to use standard comparison method (not your own bool comp(const string &l, const string &r)), e.g.:
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
#include <functional>
using namespace std;
int main(void) {
int N;
cin >> N;
vector<string> v;
for (int i = 0; i < N; i++) {
string s;
cin >> s;
v.push_back(s);
}
std::sort (v.begin(), v.end(), std::greater<string>());
// or std::less<string>()
for (const string& s : v) {
cout << s << endl;
}
cout << endl;
}
Or change your function to simple one, like:
bool comp(const string &l, const string &r) {
return l < r;
}
Update:
But if you really want to use your own comp function, you should understand that reason why exception invalid operator < occurs because your comparison function (comp) returns true when both relevant fields are equal (this not correct behavior for "less than" required for sort).
And at the end, small tip (it is hardly a solution) - try this for your code:
bool comp(const string &l, const string &r) {
for (int i = 0; i < max(l.length(), r.length()); i++) {
if (i >= l.length()) return false;
if (i >= r.length()) return true;
if (l[i] != r[i]) return l[i] < r[i];
}
return true;
}
Problem is from the Elements of Programming Interviews Book (2012).
Problem 6.1 pg 53: "Write a functions that take an array A (I used vector) and an index i into A, and rearranges the elements such that all elements less than A[i] appear first, followed by elements equal to A[i], followed by elements greater than A[i]. Your algorithm should have O(1) space complexity and O(|A|) time complexity.
My code doesn't do anything to the vector.
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
void swapit(vector<T> v, int i, int j)
{
T temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
template <typename T>
void dutch_flag_partition(vector<T> &v, int pivotindex)
{
T pivot = v[pivotindex];
int lower = 0;
int equals = 0;
int larger = v.size() - 1;
while(equals <= larger)
{
cout << equals << " " << larger<< endl;
if(v[equals] < pivot)
{
swapit(v, lower++, equals++);
}
else if(v[equals] == pivot)
{
++equals;
}
else
{
swapit(v, equals, larger--);
}
}
}
int main()
{
int arr[] = {1,11,3,5,3,10,0,22,50,33,4,22,23,100,9};
vector<int> v (arr, arr + sizeof(arr)/sizeof(arr[0]));
dutch_flag_partition(v, 5);
for(int i = 0; i < v.size(); ++i)
{
cout << v[i] << " ";
}
cout << endl;
return 0;
}
void swapit(vector<T> v, int i, int j) { ... }
This does not modify the vector you passed in. Instead, it creates a copy for this function. You probably want to use a reference:
void swapit(vector<T> & v, int i, int j) { ... }
My code is in
#include <iostream>
#include <string>
#include <algorithm>
#include <climits>
#include <vector>
#include <cmath>
using namespace std;
struct State {
int v;
const State *rest;
void dump() const {
if(rest) {
cout << ' ' << v;
rest->dump();
} else {
cout << endl;
}
}
State() : v(0), rest(0) {}
State(int _v, const State &_rest) : v(_v), rest(&_rest) {}
};
void ss(int *ip, int *end, int target, const State &state) {
if(target < 0) return; // assuming we don't allow any negatives
if(ip==end && target==0) {
state.dump();
return;
}
if(ip==end)
return;
{ // without the first one
ss(ip+1, end, target, state);
}
{ // with the first one
int first = *ip;
ss(ip+1, end, target-first, State(first, state));
}
}
vector<int> get_primes(int N) {
int size = floor(0.5 * (N - 3)) + 1;
vector<int> primes;
primes.push_back(2);
vector<bool> is_prime(size, true);
for(long i = 0; i < size; ++i) {
if(is_prime[i]) {
int p = (i << 1) + 3;
primes.push_back(p);
// sieving from p^2, whose index is 2i^2 + 6i + 3
for (long j = ((i * i) << 1) + 6 * i + 3; j < size; j += p) {
is_prime[j] = false;
}
}
}
}
int main() {
int N;
cin >> N;
vector<int> primes = get_primes(N);
int a[primes.size()];
for (int i = 0; i < primes.size(); ++i) {
a[i] = primes[i];
}
int * start = &a[0];
int * end = start + sizeof(a) / sizeof(a[0]);
ss(start, end, N, State());
}
It takes one input N (int), and gets the vector of all prime numbers smaller than N.
Then, it finds the number of unique sets from the vector that adds up to N.
The get_primes(N) works, but the other one doesn't.
I borrowed the other code from
How to find all matching numbers, that sums to 'N' in a given array
Please help me.. I just want the number of unique sets.
You've forgotten to return primes; at the end of your get_primes() function.
I'm guessing the problem is:
vector<int> get_primes(int N) {
// ...
return primes; // missing this line
}
As-is, you're just writing some junk here:
vector<int> primes = get_primes(N);
it's undefined behavior - which in this case manifests itself as crashing.