defining function using a struct - c++

I'm a newbie to programming, especially to C++. I've got a task, and its part is to write a function using a struct.
struct S {
float m; //how many
int h; //where
float mx;
};
int main() {
S s;
s.m=0.5;
s.h=1;
vector<float> v(10);
for (int i=0;i<10;i++)
v[i]=sin(i);
S mx = max_search(v);
The function is ok, if (mx.m>0.98935 && mx.m<0.9894 && mx.h==8).
I came out with this code of function, but I know, it's quite defective.
float max_search(vector<float> v) {
int max=0;
for (int i=0; i<v.size(); i++) {
if (v[i]>max) {
max=v[i];
}
return max;
}
}
I don't know, what should I do with the type of function, and maybe the return value in also wrong.

Not sure I capture your main question correctly or not. You want to convert return value of max_search function which is float to struct S? I'll massage on KarithikT's answer and add more details:
To enable implicit conversion (from float to struct S), need to add conversion functions to S
struct S {
S():m(0.0), h(0), mx(0.0){ } //
S(float x):m(0.0), h(0), mx(x){ } // to enalbe convert float to S
float m; //how many
int h; //where
float mx;
};
float max_search(const vector<float>& v) { // pass by const reference
float max=0.0f;
for (int i=0; i<v.size(); i++) {
if (v[i]>max) {
max=v[i];
}
}
return max;
}
You could also use std::max_element to find max element from a container:
vector<float> v(10);
for (int i=0;i<10;i++) {
v[i]=sin(i);
}
S mx = *std::max_element(v.begin(), v.end());

You want your return max; In the outer most level. Right now it returns every iteration of the for loop, which means you get only 1 iteration.
float max_search(vector<float> v) {
float max=0.0f; <------------
for (int i=0; i<v.size(); i++) {
if (v[i]>max) {
max=v[i];
}
--------------
}
return max; <------------
}
And i think you want to call it like this s.mx = max_search(v);
You can also use std::max_element
s.mx = std::max_element(v.begin(),v.end()); // (begin(v),end(v)) in c++11

If you declare a function as float, why are you returning an int?
float max_search(vector<float> v) {
float max = v[0]; //this way you avoid an iteration
for (int i = 1; i < v.size() - 1; i++)
if (v[i] > max) max = v[i];
return max;
}
You can also use an iterator to do that:
float max_search(vector<float> v) {
float max = .0;
for (vector<float>::iterator it = v.begin(); it != v.end(); ++it)
if (*it > max) max = *it;
return max;
}
In the first code block it's important to substract 1 to v.size, other way you will try to access to an element that does not exists. If your code isn't returning you a segmentation fault, that's because std::vector is access safe. That means that std::vector try to access to the element, but anyway, you are doing one last innecesary iteration. That's why it's better to use iterators.
It's also true what #KarthikT says: you are trying to return max in each iteration, so, after first iteration, function return the value and stop the execution, always retrieving you the first value of the vector (if this value is greater than 0).
I hope this help.

Related

Merge Sorted array Error in c++: reference binding to null pointer of type 'int' (stl_vector.h)

https://leetcode.com/problems/merge-sorted-array/
In this leetcode question, this is the logic, I used
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int i = 0;
int j = 0;
int k = 0;
vector<int> ans;
while (i<m && j<n) {
if (nums1[i] < nums2[j]){
ans[k++] = nums1[i++];
}
else {
ans[k++] = nums2[j++];
}
}
while (i<m) {
ans[k++] = nums1[i++];
}
while (j<n) {
ans[k++] = nums2[j++];
}
for (int h = 0; h<(m+n); h++) {
nums1[h] = ans[h];
}
}
};
while running the code, I get this runtime error.
Error Image
How do I solve this
This is a vector of size zero
vector<int> ans;
This code attempts to change an element of the size zero vector.
ans[k++] = nums1[i++];
That's the cause of your error.
If you want to add an element to the end of a vector use push_back
ans.push_back(nums1[i++]);
C++ vectors don't change size automatically, you have to use push_back or resize or insert or something similar.
Alternatively make the vector the correct size to begin with
vector<int> ans(m + n);
though I prefer the push_back method myself.

Why does powerNumber() add a new number to the vector when I am inside the function but the number disappears once the function is executed?

Solution is probably pretty easy but I can't figure it out. How do I make a permanent change to the vector and not only a change that takes effect inside the function? I debugged it and I can see that "numbers" is updated with the value I want it to have but it disappears as soon as it is executed.
using namespace std;
bool checkVal();
vector<int> getNumbers();
void setPowerball(vector<int> numbers);
int main()
{
srand(time(0));
vector<int> numbers = getNumbers();
setPowerball(numbers);
for (int i = 0; i < 5; i++)
{
cout << numbers[i];
cout << " ";
}
}
bool checkVal(vector<int> numbers, int size, int value)
{
for (int i = 0; i < size; ++i)
{
if (numbers[i] == value)
{
return true;
}
}
return false;
}
void setPowerball(vector<int> numbers)
{
for (int i = 4; i < 5; i++)
{
int last = rand() % 26 + 1;
if (checkVal(numbers, i, last))
{
i--;
}
else
{
numbers.push_back(last);
}
}
}
vector<int> getNumbers()
{
vector<int> numbers;
for (int i = 0; i < 4; i++)
{
int num = rand() % 69 + 1;
if (checkVal(numbers, i, num))
{
i--;
}
else
{
numbers.push_back(num);
}
}
sort(numbers.begin(), numbers.end());
return numbers;
}
You are passing arguments to setPowerBall function by value. So whenever it's called, it gets its private copy of the vector, which gets destructed at the end of function scope.
Instead you should be passing the arguments by reference in this case.
void setPowerball(vector<int>& numbers)
{
// do stuff
}
MAIN POINTS :-
Notice the & in function declaration. It implies taking a lvalue reference.
References allow you to modify the original variable without making a copy.
References are also cheaper to pass in case of objects like std::string or std::vector. But for primitive types like int or float, pass by value is faster.
Note : You could also have used pointers to do the same but using References is recommended and safer way. Rule of the thumb is Use references when you can, and pointers when you must

Segmentation fault when trying to access data stored in vector

I am trying to learn c++. I have created a vector class vec and I am trying to implement a method to compute the dot product.
It compiles fine but I get a segmentation error when running it. I have pinned the x(i) reference in the dot product method down as the cause, but I have no idea why. I gather it is something about accessing memory incorrectly, but I have no idea what I am doing incorrectly nor what the correct way would be.
My vector class:
class vec{
private:
vector<double> data;
int n; // size
public:
vec (int s) { n = s; data.reserve(n); }
double get(int i) { return data[i]; }
void set(int i, double val) { data[i] = val; }
int size() { return n; }
double operator[] (int i) { return get(i); }
double operator() (int i) { return get(i); }
double dot (vec x) {
assert(n == x.size());
int z = 0;
for (int i = 0; i < n; i++){
z += data[i] * x(i);
}
return z;
}
};
I am trying to use it like so:
int main(int argc, char *argv[]) {
vec x = vec(3);
x.set(0, 1);
x.set(1, 1);
x.set(2, 2);
vec y = vec(3);
y.set(0, 2);
y.set(1, 2);
y.set(2, 3);
double z = x.dot(y);
}
Change this:
data.reserve(n);
To this:
data.resize(n);
The reserve does not create the items in a vector. All it does is increase the capacity. To actually create n objects up front, you use resize.
Also on a side note, I highly suggest you not use extraneous variables such as n to keep track of a vector's size. Use the vector::size() function instead. The reason is that you're risking bugs if for some reason n is not updated correctly.
Thus this should be your constructor:
vec (int s) : data(s) {}
and dump the n member variable.
In this clause:
vec y = vec(3);
y.set(0, 2);
y.set(1, 2);
y.set(2, 3);
You're setting index 3, which is out of bounds of this vector. To fix it, either initialize vec to be of length 4, or index somewhere else. :)
You should also be resizing instead of reserving, but getting this wrong shouldn't cause a segfault. It should just confuse people.

Sort 2dim vector and keep indices

I filled a 2dim vector as below:
vector< vector<double>> save;
for ( int i=0;i<5;i++ )
{
for ( int j=0;j<5;j++ )
{
save[i][j]=i*(i+j);
}
}
Now how can I sort it and keep their related indices ?
For example indices of 8 are 4 and 4
I have already used this code to save indices and sort them in two other array which 2dim and 1dim respectively
void sort(int index[5][2],int order[5])
{
int l=0;
while( l<5)
{
float max=-10000;
int c1=0;
int c2=0;
for(int i=0;i<5;i++)
{
for(int j=i+1;j<5;j++)
{
if(save[i][j]>max)
{
max=save[i][j];
c1=i+1;
c2=j+1;
}
}
}
order[l]=max;
index[l][0]=c1;
index[l][1]=c2;
l++;
}
}
I want to know can I save more time in case of computation time if I use vector and sort function instead of current solution when number of data is 100 instead of 5 ?
I would do something like this.
// Create a structure to manage co-ordinates, values, and 1d-indices.
// These are the components you're actually interested in.
struct PointValue
{
PointValue(int x, int y, int value)
: x(x), y(t), value(value), indexOneDimensional(x*(x+y))
{}
int x, y, indexOneDimensional;
int value;
// Sort predicate for sorting these PointValue objects.
static bool SortFunction(const PointValue& left, const PointValue& right)
{
return left.value < right.value;
}
};
typedef std::vector<PointValue> PointValueList;
int sizeX = 100; int sizeY = 100;
PointValueList myValues(sizeX * sizeY);
// Create a 100x100 array with random values for each point.
for (int i = 0; i < sizeX; i++)
{
for (int j = 0; j < sizeY; j++)
{
myValues.push_back(PointValue(i, j, rand()));
}
}
// Sort using our static predicate.
std::sort(myValues.begin(), myValues.end(), PointValue::SortFunction);
// Print 1d-indices.
std::for_each(m_values.begin(), m_values.end(), [](const PointValue& val) {
printf("Index is: %d. Value is: %d", val.indexOneDimensional, val.value);
});
You can use a hash map of numbers to their indices. Something like:
std::map< double, std::list<int> > indices;
Also, take into account the fact that the comparison between two floating point numbers is approximate.

How to pass vectors between multiple functions?

#include <iostream>
#include <vector>
using namespace std;
class PerformSort
{
public:
const vector<int> * p;
vector<int>& getElements(int);
vector<int>& sortArray(vector<int>&);
void printer(vector<int>&);
}firstSort;
vector<int>& PerformSort::getElements (int num)
{
vector<int> elements(num);
for (int i = 0; i < num; i++)
{
cout << "Enter elements into the array: ";
cin >> elements[i];
}
p = &elements;
return p;
}
vector<int>& PerformSort::sortArray (vector<int>& vector)
{
int holder, min;
for (int i = 0; i < (sizeof(vector) - 1); i++)
{
min = i;
for (int j = (i + 1); j < sizeof(vector); j++)
{
if (vector[j] < vector[min])
{
min = j;
}
}
if (min != i)
{
holder = vector[i];
vector[i] = vector[min];
vector[min] = holder;
}
}
return vector;
}
void PerformSort::printer(vector<int>& vector2)
{
for (int i = 0; i < sizeof(vector2); i++)
{
cout << vector2[i] << " ";
}
}
int main ()
{
int numberOfTimes;
cin >> numberOfTimes;
firstSort.printer(firstSort.sortArray(firstSort.getElements(numberOfTimes)));
return 0;
}
This returns the error: "invalid initialization of reference of type from expression of type". My first approach to create a SelectionSort algorithm was to try passing the vector by value (stupidly). After this I started to use pointers instead, after some research. However, this resulted in the aforementioned error. Declaring everything as constant does not seem to resolve the underlying error, despite how, if I understand things correctly, the error lies with temporary references being passed where constant ones are required. Any thoughts on how I might achieve this passing and returning of vectors? (I come from a Java background and am just beginning C++, so forgive me if I have made any obvious errors with regards to the pointers).
Return it by value:
vector<int> PerformSort::getElements (int num)
{
vector<int> elements(num);
for (int i = 0; i < num; i++)
{
cout << "Enter elements into the array: ";
cin >> elements[i];
}
return elements;
}
This will also let you get rid of p, which is a huge can of worms in its own right.
Finally, I notice that you use sizeof(vector) in quite a few places. This won't give you the number of elements in the vector; use vector.size() instead.
Rename the variable vector to something else:
vector<int>& PerformSort::sortArray (vector<int>& wayBetterName)
&
return wayBetterName;
What urged you to name a variable the same as a type?
There's many more other issues with the code.
You don't need pointers, you don't need the references, plus you're better off just using std::sort.