C++ Element access is failing to work? - c++

this is a super simple question but I cannot seem to see what has gone wrong. What this code does is it counts the number of elements in the pixID vector and returns that sum to a diagonal element in the square matrix PtP. However even though 'i' in the first loop reads: 0,5,10,15 for the elements the output looks like this:
1,0,0,0,
0,0,3,0,
0,0,0,0,
0,3,0,0,
instead of the desired:
1,0,0,0,
0,3,0,0,
0,0,2,0,
0,0,0,2,
Any idea what is going on here?
double where(std::vector<double> &vec,unsigned int &v){
double count = 0;
int val;
for(std::vector<double>::iterator it = vec.begin();
it != vec.end();
++it){
if(*it == val){
count++;
}
}
return count;
}
int main(){
unsigned int pixSide = 2;
int id;
std::vector<double> pixID {1,1,2,3,0,2,1,3};
std::vector<double> PtP (pixSide*pixSide);
for(unsigned int i=0;i<pixSide*pixSide;i++){
id = i*pixSide*pixSide + i;
std::cout << id << std::endl;
PtP[id] = where(pixID,i);
}
for(int i=0;i<pixSide*pixSide;i++){
for(int j=0;j<pixSide*pixSide;j++){
std::cout << int(PtP[i*pixSide + j]) << ',';
if(j==pixSide*pixSide-1){
std::cout << std::endl;
}
}
}
}

First, you're not using the parameter "v" in where(). Instead, you're using the uninitialized local variable "val".
Second, I think you may be confusing the dimensions of your objects at a few points. I think you're getting confused about whether you're keeping just the diagonal or the whole matrix.
This way you will consistently be keeping the whole matrix:
std::vector<double> PtP (pixSide*pixSide);
should be
std::vector<double> PtP (pixSide*pixSide*pixSide*pixSide);
and
std::cout << int(PtP[i*pixSide + j]) << ',';
should be
std::cout << int(PtP[i*pixSide*pixSide + j]) << ',';
Of course, this is wasteful for such a sparse matrix -- I don't know whether that matters in your application (are your real numbers larger than pixSide=2?).

Related

Confusion on push_back interaction with pair<float,int>

I have no error message instead I only have unexpected behavior.
double get_optimal_value(int capacity, vector<int> weights, vector<int> values) {
int n = weights.size();
vector<pair<double, int>> valuePerWeight(n);
pair<double,int> x;
for(int i = 0; i < n; i++){
double v = values[i]/weights[i];
x = make_pair(values[i]/weights[i], weights[i]);
valuePerWeight.push_back(x);
}
for(int i = 0; i < n && capacity > 0; i++){
int amount = min(capacity, valuePerWeight[i].second);
value += valuePerWeight[i].first * amount;
capacity -= amount;
}
double value = 0.0;
return value;
}
I am creating a vector with values of type pair<double,int>. I create the pair using make_pair(some_double, some_int), then I call push_back with the pair.
Later in the function I index into the vector and do stuff using the pairs.
However an issue arises, when I index into my valuePerWeight vector and retrieve the attributes of the different pairs. They all end up being zero regardless of index and regardless of .first or .second.
Through printing a bunch of variables I have asserted the created pair is not {0,0} but as soon as I push_back into the vector and index the pair and look at it's .first and .second attributes both are equal to 0.
I can't seem to understand why this is, originally I was using push_back seen as below
valuePerWeight.push_back(make_pair(values[i]/weights[i], weights[i]));
instead of creating into a temporary variable x . However the same issue still stands.
Any help in the right direction would be greatly appreciated.
If there is any further clarification that I can give please ask me.
If you'd like to see for some values below is a snippet which can be compiled
I use input
3 50
60 20
100 50
120 30
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
double get_optimal_value(int capacity, vector<int> weights, vector<int> values) {
double value = 0.0;
int n = weights.size();
vector<pair<double, int>> valuePerWeight(n);
pair<double,int> x;
for(int i = 0; i < n; i++){
double v = values[i]/weights[i];
cout << v << ' '<< weights[i] << '\n';
x = make_pair(values[i]/weights[i], weights[i]);
cout << x.first << ' ' << x.second << '\n';
valuePerWeight.push_back(x);
cout << valuePerWeight[i].first << ' ' << valuePerWeight[i].second << '\n';
}
for(int i = 0; i < n; i++){
cout << valuePerWeight[i].first;
cout << valuePerWeight[i].second;
cout << '\n';
}
sort(valuePerWeight.begin(), valuePerWeight.end());
for(int i = 0; i < n && capacity > 0; i++){
int amount = min(capacity, valuePerWeight[i].second);
value += valuePerWeight[i].first * amount;
capacity -= amount;
}
// for(auto vp: valuePerWeight){
// cout << vp.first << vp.second;
// cout << '\n';
// }
return value;
}
int main() {
int n;
int capacity;
std::cin >> n >> capacity;
vector<int> values(n);
vector<int> weights(n);
for (int i = 0; i < n; i++) {
std::cin >> values[i] >> weights[i];
}
double optimal_value = get_optimal_value(capacity, weights, values);
std::cout.precision(10);
std::cout << optimal_value << std::endl;
return 0;
}
The confusion here is due to the behavior of the constructor you use
vector<pair<double, int>> valuePerWeight(n);
This actually fills the vector with n default constructed pairs, which as you may surmise, are (0, 0). When you push_back, you push to the end of these, so you a totally get 2n pairs.
.reserve does something close to what you expected, not actually filling the vector, but is likely not needed for something not bottle-necking on vector resizing.
Short story, omit the (n) to just construct an empty vector.
Three more suggestions: accept the vectors as const& to save a copy, and look at emplace_back instead of making a pair yourself and pushing it. That's what it's meant for. Also, note the comment by churill - dividing two integers will result in integer division regardless of where you are assigning the result. Static cast one of them to a float or double (or multiply by 1.0 at the start) to ensure floating point division.

How do you print a full array of values in C++

I'm trying to figure out print a full array in C++.
For example, I want the output to be x = [1,2,3,4,5....n]
How would I go about doing this? I already know how to print each element of the array using a simple for loop. For example in python, you could simply say x = [], make a for loop to append elements to the array, and print x.
So let's say I have this code.
int n = 10;
int m = 10;
double x[n];
// Generate vector of random values for x
for (int i = 0; i<n; ++i)
{
x[i] = (double)rand()/(double)RAND_MAX;
// Print each array element
// std::cout << x[i] << std::endl;
}
std::cout << x[n-1] << std::endl;
This obviously only spits out x[10] in this case. Where as I want x = [1...n] etc.
What is the simplest way of achieving this?
I'm using Eclipse on OSX. I use the g++ compiler that the Xcode developer tools has for the command line
You're looking for a range based for loop:
double x[] = { .0, .1, .2, .3, .4 };
// Iterate through all elements
for (auto d : x)
{
std::cout << d << std::endl;
}
Note that the above takes a copy of each element, so if you wanted to modify an element you'd need to use
for (auto& d : x)
instead.
Alternatively you could just use a normal for loop like you did originally:
for (int i = 0; i<n; ++i)
{
std::cout << x[i] << std::endl;
}
The range based for loop is the easiest though.
if you know something about STL , you can try to use iterator
code:
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
int arr[5] = {1,2,3,4,5};
copy(arr, arr + sizeof(arr)/sizeof(int),ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}

Vector equilibrium point(s) function in C++

So I wanted to clean the rust off my C++ skills and thought I'd start with something fairly simple. An equilibrium point in a vector A of size N is a point K, such that: A[0] + A[1] + ... + A[K−1] = A[K+1] + ... + A[N−2] + A[N−1]. The rationale behind the function algorithm is simple: Check each consecutive element of the vector and compare the sum of the elements before said element with the sum of the elements after it and if they are equal, output the index of that element. While it sounds simple (and I imagine that it is) it turned out to be harder to implement in reality. Here's what the code looks like:
#include <iostream>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
void EquilibriumPoint(std::vector<int> &A);
void VectorPrint(std::vector<int> &V);
void main()
{
int input;
std::vector<int> Vect1;
cout << "Input the vector elements" << endl;
while (cin >> input)
Vect1.push_back(input);
VectorPrint(Vect1);
EquilibriumPoint(Vect1);
}
void EquilibriumPoint(std::vector<int> &A)
{
for (int it = 0; it != A.size(); ++it)
{
int lowersum = 0;
int uppersum = 0;
for (int beg = 0; beg != it; ++beg) lowersum += A[beg];
for (int end = it + 1; end != A.size(); ++end) uppersum += A[end];
if (uppersum == lowersum) cout << it;
}
}
void VectorPrint(std::vector<int> &V)
{
for (int i = 0; i != V.size(); ++i)
cout << V[i] << endl;
}
As you can see I threw in a print function also for good measure. The problem is that the program doesn't seem to execute the EquilibriumPoint function. There must be a problem with the logic of the implementation but I can't find it. Do you guys have any suggestions?
cin >> input
always returns true for you - so IMHO you have an endless loop. You need to stop collecting elements at some point, for instance
int input = 1
while (input)
{
cin >> input;
Vect1.push_back(input);
}
Will accept all elements that are not zero, when zero arrives, it will end the vector and run your function.
Or you can first input the number of elements (if you want to include zeros), example:
int count;
cin >> count
for (int i = 0; i < count; ++i)
{
cin >> input;
Vect1.push_back(input);
}
I didn't check the rest of the code, though. One problem at a time.

Segmentation fault: 11; range-based for loop

I'm working on a small programming exercise in C++. Goal is to initiate an array with the first 32 exponentations of 2 and to output them afterwards.
Using a normal for loop there's no problem but I tried to use the range-based for loop introduced in the C++11 standard.
During compilation I get the warning "range-based for loop is a C++11 extension [-Wc++11-extensions]".
Running the program I get the error "Segmentation fault: 11" without any further output.
I got already that the elem variable somehow is broken but I don't know how.
Hope you can help a n00b :)
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
const int LAENGE = 32;
long potenzen[LAENGE];
for(int elem : potenzen)
{
potenzen[elem] = pow(2.0, (double) (elem + 1));
}
for(int elem : potenzen)
{
cout << endl;
cout << potenzen[elem];
}
cout << endl;
return 0;
}
elem is assigned the values in potenzen, not indices. cout << elem; is what you want instead to print the elements of the array. And in order to fill the array, simply use integer indices:
for (int i = 0; i < LENGTH; i++) { // ProTip #1: use English identifiers
array[i] = 2 << i; // ProTip #2: don't use `pow()` when working with integers
}
As to the compiler warning: use the -std=c++11 or -std=c++0x flag when compiling to tell the compiler you are intending to use C++11 features (assuming you use GCC or clang -- I'm not sure about other compilers.)
Ranged for loop wil give you element values, and not the element indices.
potenzen[elem] = pow(2.0, (double) (elem + 1));
should be
for(int i = 0; i < LAENGE; i++)
potenzen[i] = 2 << i;
(For shifting, refer to the H2CO3's answer and to the his comments below)
Note that you can't use foreach loop here:
for(int& elem : potenzen)
{
elem = pow(2.0, (double) (elem + 1));
}
as you're accessing not-initialized value of elem in the right side of the statement.
Also:
for(int elem : potenzen)
{
cout << endl;
cout << potenzen[elem];
}
Should be
for(int elem : potenzen)
{
cout << endl;
cout << elem;
}
as elem will contain array values.
The above answers rightly point out the issues in your code, however if you want to have array indices as element values you've to set them up, without which they'd be initialized to indeterminate (garbage) values; the following code is also a solution that's somewhat similar to what you tried to do:
#include <iostream>
#include <algorithm>
int main()
{
constexpr auto count = 32;
unsigned long long values[count] = { }; // initialise elements to 0
auto i = 0;
// fill them with their respective index values
std::generate_n(values, count, [&i] { return i++; });
for(auto &x : values)
{
// without casting the literal 2 would be treated as an int
x = static_cast<unsigned long long>(2) << x;
std::cout << x << std::endl;
}
return 0;
}
I've used unsigned long long instead of long, since on many systems the size of a long is 4 bytes, but 2^32 = 4294967296 = 0x100000000 I.e. 33 bits are required. Also since we know that all values are going to be positive, making it unsigned makes more sense.

Getting odd results when trying to solve Collatz p‌r‌o‌b‌l‌e‌m

I'm trying to solving Project Euler Problem 14. It asks to find the number under 1 million that generates the longest sequence. What I did was create a vector, v, and populate its elements with the length of the sequence for a particular number. Thus, the element that resides in position 13 will correspond to the length of the sequence generated by the number 13, and so on. However, some seemingly random elements take very large numbers and I can't figure out what's wrong with the code. Also, when I test it with 1,000,000, I get a completely wrong answer, but I know the program is working for some small numbers after testing them by hand and verifying.
#include <iostream>
#include <vector>
using namespace std;
void find_longest(int n)
{
int count = 1;
int max = 0;
int position;
vector<int> v;
v.push_back(0);
v.push_back(0);
for(int i = 1; i < n; i++)
{
long long int trainer = i;
count = 1;
while(trainer != 1)
{
if(trainer%2 == 0)
{
trainer /= 2;
count++;
}
else
{
trainer = 3*trainer + 1;
count++;
}
}
v.push_back(count);
}
vector<int>::iterator it;
for(it = v.begin(); it < v.end(); it++)
{
cout << v[*it] << endl;
//if(v[*it] > max)
//{
// max = v[*it];
// position = *it;
//}
}
//cout << "The longest sequence is " << max << " terms long and is ";
//cout << "generated by the number " << position << "." << endl;
}
int main()
{
find_longest(100);
//find_longest(1000000);
}
//removing change for type mismatch
You don't need to remember all N numbers in a vector.
All you need is current sequence length. Then you calculate sequence length for the next number and if it is bigger than what you have already, you just keep the biggest one.