I have a function template that is suppose to take a vector and produce random numbers inside it.
However, when I print entire vector, its all zeros. This method works for arrays however.
code:
#include <vector>
template<class T>
class RandomGenerator
{
public:
// function template for generating random numbers
void genRand(T data[], int size)
{
for (int i = 0; i < size; i++)
{
data[i] = (1 + rand() % size);
}
}
void genRand(std::vector<T> data, int size)
{
genRand(&data[0], size);
}
};
You take the vector by value, thus the argument won't be changed. Take it by reference:
void genRand(std::vector<T>& data, int size)
// ^
Related
I have passed an array of size 10 to a funtion to sort the array reversely, but it's going wrong after rightly sorting first five elements of the array.
I want to sort the array 'std' reversely here,
# include <iostream>
using namespace std;
int reverse(int a[]); //funtion prototype
int main()
{
int std[10] = {0,1,2,3,4,5,6,7,8,9};
reverse(std);
}
int reverse(int a[]) //funtion defination
{
int index = 0;
for (int i = 9; i >= 0; i--)
{
a[index] = a[i]; //swaping values of the array
cout << a[index] << " ";
index++;
}
}
There's basically three things wrong with your code.
You aren't swapping anything
You have to swap the first half of the array with the second half, not swap the whole array. If you do that then everything gets swapped twice, so that nothing changes
You should print the reversed array after you have finished the reverse, not while you are doing the reverse.
Here's some code that fixes all these problems
# include <iostream>
# include <utility>
void reverse(int a[]);
int main()
{
int std[10] = {0,1,2,3,4,5,6,7,8,9};
reverse(std);
// print the array after reversing it
for (int i = 0; i < 10; ++i)
std::cout << std[i] << ' ';
std::cout << '\n';
}
void reverse(int a[])
{
for (int i = 0; i < 5; ++i) // swap the first half of the array with the second half
{
std::swap(a[i], a[9 - i]); // real swap
}
}
Yes you can.
I usually don't use "C" style arrays anymore (they can still be useful, but the don't behave like objects). When passing "C" style arrays to functions you kind of always have to manuall pass the size of the array as well (or make assumptions). Those can lead to bugs. (not to mention pointer decay)
Here is an example :
#include <array>
#include <iostream>
// using namespace std; NO unlearn trhis
template<std::size_t N>
void reverse(std::array<int, N>& values)
{
int index = 0;
// you only should run until the middle of the array (size/2)
// or you start swapping back values.
for (int i = values.size() / 2; i >= 0; i--, index++)
{
// for swapping objects/values C++ has std::swap
// using functions like this shows WHAT you are doing by giving it a name
std::swap(values[index], values[i]);
}
}
int main()
{
std::array<int,10> values{ 0,1,2,3,4,5,6,7,8,9 };
reverse(values);
for (const int value : values)
{
std::cout << value << " ";
}
return 0;
}
I want to do something like:
int a[][]; // I know this code won't work, its to demonstrate what I want to do
void func(int n, int m){
a = int[n][m];
}
that is, initialise a global array whose size depends on function input. If this array was local, it would be a trivial case, but I don't know how to do this in the case shown above. Any help would be very useful!
You can create a matrix with std::vector:
std::vector<std::vector<int>> a;
void func(int n, int m) {
a.resize(n);
for(int i = 0; i < n; i++) {
a[i].resize(m);
}
}
Then you can access elements in the same way you do with int a[][]:
a[i][j] = number;
One way to achieve this is to encapsulate a flat std::vector in a Matrix class and use math to get an element with row and column as in this example:
template<typename T>
class Matrix {
private:
vector<T> vec;
//...
public:
T& get_value(size_t const row, size_t const col) {
return vec[row * col_count + col];
}
};
you can try this
int ** a; // is a pointer of two dimension
void func(int n, int m){
a = new int*[n]; //dynamic allocation global pointer a
for(int i = 0; i < n; i++)
a[i] = new int[m]();
}
I'm trying to use clear functions to do a matrix multiplication with random generated values. Therefore I'm hoping to use a function(mat_def) to generate the matrices and another function(mat_mul) to multiply them when the matrices are sent as parameters.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
double mat_def(int n) //how to return the matrix
{
double a[n][n];
double f;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
f= rand();
cout<<f ;
a[i][j]=f;
}
}
return 0;
}
double mat_mul( int n, double a[n][n], double b[n][n]) //how to send matrix as parameter
{
return 0;
}
int main()
{
/* initialize random seed: */
srand (time(NULL));
mat_def(10);
}
Here's a nice, standard C++ Matrix template for you.
Matrix.h
#include <vector>
class Matrix
{
class InnerM
{
private:
int ydim;
double* values;
public:
InnerM(int y) : ydim(y)
{
values = new double[y];
}
double& operator[](int y)
{
return values[y];
}
};
private:
int xdim;
int ydim;
std::vector<InnerM> inner;
public:
Matrix(int x, int y) : xdim(x), ydim(y), inner(xdim, InnerM(ydim))
{
}
InnerM& operator[](int x)
{
return inner[x];
}
};
All the memory leaks are there for you but you get the idea. From here you can handle the multiplication by overiding ::operator*() in the Matrix class.
I assume your problem is to define 2-D array and then pass it to mat_mul function to multiply the matrices. And the rest will be quite simple.
Defining the 2-D array(considering memory needs are known at run time):
int rows,cols;
cin >> rows;
cin >> cols;
int **arr = new int*[rows]; // rows X cols 2D-array
for(int i = 0; i < rows; ++i) {
arr[i] = new int[cols];
}
You can define another 2-D array exactly the same way with required rows and column.
now, Passing the 2-D array to function:
void mat_mul(int **arr1, int **arr2, int m, int n, int p, int q){
//define a 2-D array to store the result
//do the multiplication operation
//you could store the result in one of the two arrays
//so that you don't have to return it
//or else the return type should be modified to return the 2-D array
}
example:
void display(int **arr, int row, int col){
for (int i=0; i<row; i++){
for(int j=0;j<col; j++){
cout << arr[i][j] << '\t';
}
cout << endl;
}
}
Delete the memory if not required anymore with the following syntax:
for(int i=0; i<rows; i++){
delete[] array[i];
}
delete[] array;
hope this will be sufficient to get your work done!
there is already an answer on how to return a 2-D array on SO. Check the link below.
https://stackoverflow.com/a/8618617/8038009
Returning the raw allocation is a sucker bet. You need to manage all of the memory allocated yourself and pass it around with the matrix size parameters.
Why suffer? Use a matrix class
template<class Type>
class Matrix{
int rows;
int cols;
std::vector<type> data;
public:
Matrix(int row, int col):rows(row), cols(col), data(rows*cols)
{
// does nothing. All of the heavy lifting was in the initializer
}
// std::vector eliminates the need for destructor, assignment operators, and copy
//and move constructors.
//add a convenience method for easy access to the vector
type & operator()(size_t row, size_t col)
{
return data[row*cols+col];
}
type operator()(size_t row, size_t col) const
{
return data[row*cols+col];
}
};
Usage would be
Matrix<double> mat_mul(const Matrix<double> &a, const Matrix<double> &b)
{
Matrix<double> result;
// do multiplication
return result;
}
int main()
{
/* initialize random seed: */
srand (time(NULL));
Matrix<double> matA(10, 10);
matA(0,0) = 3.14; // sample assignment
matA(9,9) = 2.78;
double x = matA(0,0) * matA(9,9)
Matrix<double> matB(10, 10);
Matrix<double> matC = mat_mul(matA, matB) ;
}
More functionality, such as construction from an initializer list, can be added to the class to make your life easier. You can also specify an operator * overload for Matrix and use that in place of mat_mul if you chose. Read Operator overloading for more on that option.
This is one the methods that I have to make for my assignment
int*mode(int &) – returns an integer array containing the modal value(s) of the
population, the reference parameter should be set to the size of the result
But from searching, you cannot return array's from a function? I can calculate modal value from a given array, put it in an array, but return an integer array? maybe the professor meant something else? I know how to do all other methods except that one. I don't even know what that method means (Coming from java)
Header File
#include <string>
using namespace std;
class population
{
public:
//Default Constructor
population(void);
//Constructor that accepts an integer array object, and the size for that array object
population(int[], int);
//Constructor for creating a deep copy
population (const population &);
//For overloading purposes
population & operator = (const population &);
//Destructor that frees dynamic memory associated with the underlying array
~population(void);
//Method for loading new content into an array
void load(string);
//Method for adding new content into existing array
void add(string);
//Accessors
//Returns the size of the population (The number of values stored in the array)
int size();
//Returns the sum of the popluation (The sum of the contents in the array)
int sum();
//Returns the mean of the population
float mean();
//Returns the median of the population
float median();
//Returns the standard deviation of the population
float stddev();
//Returns an integer array containing the modal values of the popluation
int*mode(int &);
private:
int arraySize;
bool sorted;
int * popArray;
};
CPP
#include "population.h"
//Default Constructor
population::population(void)
{
}
//Constructor to intialize the population object
population::population(int arr[], int s)
{
//Store s into a variable
arraySize = s;
//Declare popArray as a Dynamic array
popArray = new int[arraySize];
//Copy the passed array into the popArray
for ( int i=0; i < s; i++)
{
popArray[i] = arr[i];
};
}
//Constructor for deep copying purposes
population::population (const population & p)
{
}
population::~population(void)
{
}
int population::size(void)
{
//Return size of the array, which is the amount of population in the array.
return arraySize;
}
int population::sum(void)
{
//Variable to hold sum of the array
int sumArray = 0;
//Add all the contents of the array into one variable
for ( int i = 0; i < arraySize; i++)
{
sumArray += popArray[i];
}
//Return the sum of the array
return sumArray;
}
float population::mean(void)
{
//Variable to hold sum and the mean of the array
int sumArray = 0;
float meanArray;
//Add all the contents of the array into one variable
for ( int i=0; i < arraySize; i++)
{
sumArray += popArray[i];
}
//Sum of the array divided by number of contents in the array (Average)
meanArray = (sumArray / arraySize);
//Returns mean value in type float
return meanArray;
}
float population::median ()
{
return 1;
}
float population::stddev()
{
return 1;
}
int population::*mode(int & i)
{
return
}
With a prototype like that, I'm guessing that he wants you to new an array to be returned:
int *population::mode(int & i)
{
// compute the number of modal values you need to return
i = /* whatever the size of the return array will be */;
int * ret = new int[i];
// fill in ret
return ret;
}
Try:
int foo(int arrayBar[])
or
int foo(int* arrayBar)
or
int* foo(int arrayBar[])
If those don't work, make sure your pointer is at the beginning of the array.
Source: Return array in a function
I'm writing a function that has a 2D array of strings as input parameter. I initialized the string, passed it to the function but when I tried to print the array nothing happened. It says that the length of the array is 0. All my functions are stored in a header file. Here's my code:
#include<iostream>
#include<string>
#include<iomanip>
using namespace std;
int c,i,j,fx,fy;
int color,fields,rows,anim,speed;
string opt[5][50];
string popt[5][50]={
{"caption","asdf","safd","asf"},
{"caption1","dsafa","asdf","asdf"},
{"caption2","asdf","asdf","asdfas"},
{"caption3","sadfa","asdfs","fasdfa"}};
void ini(int focus_text_color, int n_fields,int n_rows, string options[][50], bool animation=false, int animation_speed=10)
{
color=focus_text_color;
fields=n_fields;
for(i=1;i<fields+1;i++)
{
for(j=1;j<rows+1;j++)
{
opt[i][j]=options[i][j];
}
}
}
int drawh()
{
system("cls");
for(i=0;i<fields;i++)
{
for(j=0;j<rows;j++)
{
cout<<opt[i][j]<<setw(opt[i+1][j].length()+5);
}
}
return 0;
}
void main()
{
ini(LIGHTRED,4,4,popt);
drawh();
}
NOTE: This is a part of the code so I haven't tested it, and sorry for my bad English :D
Apart from #Oli's comments. To make it simpler, you can pass an array by reference. See below example:
template<unsigned int ROW, unsigned int COL>
void ini (string (&s)[ROW][COL]) // psuedo code for 'ini'; put extra params to enhance
{
ini(s, ROW, COL);
}
Now, template ini() provides a wrapper to actual ini() which calculates the row/column of an array at compile time. Usage is very simple:
string s[10][5];
ini(s); // calls ini(s,10,5);
Your loop should start from dimension 0 and not 1 for copying. Check my approach and modify your code.
for(int i = 0; i < ROW; i++)
for(int j = 0; j < COL; j++)
s1[i][j] = s2[i][j];
Also there are many problems in your code due to passing wrong dimensions (e.g. passing 4 as dimension while calling ini(), when it should be 5).
The reason why you don't get any output is that you don't initialize the global variable rows, so it stays at 0. Your init function should be:
void ini(int focus_text_color, int n_fields,int n_rows, string options[][50], bool animation=false, int animation_speed=10)
{
color=focus_text_color;
fields=n_fields;
rows = n_rows; //-- ADDED LINE
....