Im trying to rotate a set of values of template class
these are the instructions
Implement a function to rotate values forward among 3 variables. Rotations greater than 3 wrap around. This function must support multiple types and uses the following prototype:
template <class T>
void rotate (T & a, T & b, T & c, int r);
#include <iostream>
#include <string>
using std::string;
using std::endl;
using std::cin;
using std::cout;
template <class T>
void rotate (T & a, T & b, T & c);
int main ()
{
int x = 1;
int y = 2;
int z = 3;
cout << rotate(x, y, z) << endl;
return 0;
}
template <class T>
void rotate (T&a, T&b, T&c)
{
T & d = b;
while (a != d)
{
swap(&a++, &d++);
if (d == c)
d = b;
else if (a == b)
b == d;
}
}
If I guessd right what you want is the values to rotate among a, b, c. In your original funcion you have int r but in your final implementation r is missing. First of all take the r%3 and rotate by that amount. The rotate is pretty simple you had the initial idea just need to flesh it out properly.
Your best best would be to use a for loop like this:
template <class T>
void rotate(T &a, T &b, T&c, int r)
{
T temp = 0;
for (int i = 0; i < r; i++)
{
temp = c;
c = b;
b = a;
a = temp;
}
}
Then the call in the main function would be:
rotate(x, y, z, 4); //4 is the number of rotations
Related
I've written some code to calculate LCM for 3 numbers. My question is:
why with line:
std::cout << "";
code does work, and without this line code doesn't work?
How it is possible that printing some text on screen, can affect on how program works? It is a matter of some buffering or smth. like this?
#include <iostream>
int NWD(int a, int b){
int r;
while (r != 0){
if (a>b)
r = a-b;
else
r = b-a;
a = b;
b = r;
}
return a;
}
int NWW(int a, int b){
std::cout << ""; // without this code doesn't work
return a*b/ (NWD(a,b));
}
int NWW3(int a, int b, int c){
return NWW(c, NWW(a,b));
}
int main()
{
cout << NWW3(1,7,9);
}
In your NWD() function:
int NWD(int a, int b){
int r; // <-- notice this
while (r != 0){
if (a>b)
r = a-b;
else
r = b-a;
a = b;
b = r;
}
return a;
}
You declare r, but you didn't assign any value to r, so r is now uninitialized.
Then, you compare r with 0 in r != 0. Because r is uninitialized, this cause undefined behaviour. Undefined behaviour can do anything, from still running normally to crashing the program.
A quick fix to this problem is to initialize r with a non-zero value:
int r {-1};
Another issue is in main():
int main()
{
cout << NWW3(1,7,9);
}
It should be:
int main()
{
std::cout << NWW3(1,7,9);
}
In your main function, you have cout declared, but have not included the standard namespace along with it, like you have done on in your NWW function.
So it should look like
int main()
{
std::cout << NWW3(1,7,9);
}
You could also include " using namespace std; " under the header files.
This fills in the std:: for you as it pulls cout from its list of predefined features.
the statement below the function calling is not executed. i am at a loss, why this is so? could someone please clarify. Please consider the code below :
#include<iostream>
#include<cmath>
using namespace std;
class Matrix
{
private:
int row,col;
double *values;
public:
Matrix();
Matrix(int r, int c, double* x);
void setdim(int m, int n){row=m;col=n;}
int getrowdim() const {return row;}
int getcoldim() const {return col;}
void set_values(int i, double x);
double get_value(int i) const;
friend Matrix operator+(const Matrix &A, const Matrix &B);
};
Matrix::Matrix()
{
this->row = 0;
this->col = 0;
this->values = NULL;
}
Matrix::Matrix(int r, int c, double* x)
{
this->row = r;
this->col = c;
this->values = new double[r*c];
for (int i =0;i<r*c;i++)
{
cout<<"Enter value ["<<i<<"] ";
cin>>this->values[i];
}
}
void Matrix::set_values(int k, double x)
{
this->values[k] = x;
}
Matrix operator+(const Matrix &A, const Matrix &B)
{
int rowa = A.getrowdim();
int cola = A.getcoldim();
int rowb = B.getrowdim();
int colb = B.getcoldim();
if(rowa == rowb && cola == colb)
{
Matrix C;
C.setdim(rowa, colb);
for(int i =0; i< rowa*cola ; i++)
{
cout<<"i = "<<i<<", A.get_value = "<<A.get_value(i)<<", B.get_value = "<<B.get_value(i)<<endl;
double m = A.get_value(i) + B.get_value(i);
cout<<m<<endl;
C.set_values(i, m );
cout<<"Returned from C.set_values()"<<endl;
// THIS STATEMENT DOES NOT GET PRINTED. PLEASE TELL THE REASON // WHY. I SUSPECT THE ERROR IS HERE
}
return C;
}
else
{
cout<<"Invalid Operation";
return A;
}
}
double Matrix::get_value(int i) const
{
return this->values[i];
}
int main()
{
Matrix A(2,2,NULL);
Matrix B(2,2,NULL);
Matrix C;
C = A+B;
return 0;
}
The statement - Returned from C.set_values() does not get printed at all .
Could someone help clarify why this is the case? Thanks a lot for the help!
Here:
Matrix C; // (1)
C.setdim(rowa, colb); // (2)
for(int i =0; i< rowa*cola ; i++)
{
cout<<"i = "<<i<<", A.get_value = "<<A.get_value(i)<<", B.get_value = "<<B.get_value(i)<<endl;
double m = A.get_value(i) + B.get_value(i);
cout<<m<<endl;
C.set_values(i, m ); // (3)
You default construct a Matrix (1). The default constructor just sets the member values to NULL. Then you adjust the size members in (2), but values is still NULL. Then, in (3) you call set_values which tries to access array elements, but there is no array.
The problem is that your Matrix has a raw owning pointer as member. When a class manages a resource you must follow the rule of 3/5. If you don't, the class is broken. Managing a resource is not trivial, and following the rule of 3/5 is just the bare minimum.
The simpler alternative that you should strive for is the rule of 0. For a class that does not manage a resource, the compiler generated special members are just right. If you replace the raw pointer member with a std::vector<double> then you do not need to worry about copying, assignment or destruction, because the compiler will generate the required methods for you.
I am trying to write a merge sort algorithm in C++.
If i try to compile the following code, i get the error:
mergeSort.cpp:9:19: error: no matching function for call to 'merge(std::vector&, int&, int&, int&)'
I tried everything in my knowledge to fix this problem and find similar ones online, but I can't figure it out on my own. Please help!
#include <bits/stdc++.h>
void sort(std::vector<int> v, int a, int b) {
//if a == b the length of the subarray is one
if (a != b) {
int k = (a + b) / 2;
sort(v, a, k);
sort(v, k+1, b);
merge(v, a, k, b); //this line gives out the error
}
}
void merge(std::vector<int> &v, int &a, int &k, int &b) {
std::vector<int> tempv;
int tmpa = a;
int tmpk = k;
for (int i = 0; i < b-a; i++) {
if (tmpa >= k-1) {
tempv.push_back(v[tmpk]);
tmpk++;
}
else if (tmpk >= b) {
tempv.push_back(v[tmpk]);
tmpk++;
}
else if (v[tmpa] < v[tmpk]) {
tempv.push_back(v[tmpk]);
tmpk++;
}
else {
tempv.push_back(v[tmpk]);
tmpk++;
}
}
for (int i = a; i < b; i++) {
v[i] = tempv[i-a];
}
}
int main() {
std::vector<int> v = {2, 7, 1, 3, 4, 4};
sort(v, 0, v.size()-1);
for (int i: v) {
std::cout << i << " ";
}
std::cout << std::endl;
}
You are calling the merge() function before the definition of that, so just shift your merge() function before the sort() function.
Put this line before the sort function:
void merge(std::vector<int> &v, int &a, int &k, int &b);
The declaration of merge is not visible at the point of usage. Declare the function before using it.
// Declare the function.
void merge(std::vector<int> &v, int &a, int &k, int &b);
void sort(std::vector<int> v, int a, int b) {
//if a == b the length of the subarray is one
if (a != b) {
int k = (a + b) / 2;
sort(v, a, k);
sort(v, k+1, b);
// Now you can use it.
merge(v, a, k, b); //this line gives out the error
}
}
On a more imporant note...
sort needs to accepts the vector by reference, not by value. Otherwise, the sorted object won't be visible in the calling function.
void sort(std::vector<int>& v, int a, int b) { ... }
// ^^^
As a matter of good coding practice, I recommend declaring all functions before defining and using them.
// Declare the functions.
void sort(std::vector<int>& v, int a, int b);
void merge(std::vector<int> &v, int &a, int &k, int &b);
// Define the functions.
void sort(std::vector<int>& v, int a, int b)
{
...
}
void merge(std::vector<int> &v, int &a, int &k, int &b)
{
...
}
In C++ you need to make sure the function declaration before it's used.
In your case, you used merge before any declaration and so the error.
To fix that, put this declaration at the front, before it is used in your sort function:
void merge(std::vector<int> &v, int &a, int &k, int &b);
Alternatively, you could move the whole merge function definition up front.
Btw, this code could overflow with the intermediate calculation (a + b)
int k = (a + b) / 2; // could overflow
which could be improved by:
int k = a - (a - b) / 2; // fine
void createArray(int a, int b, int c, int d, int array[3][3]){
int state[3][3];
for(int x=0;x<3;x++){
for(int y=0;y<3;y++){
if(x == a && y == b){
state[x][y] = array[c][d];
}
else if(x == c && y == d){
state[x][y] = array[a][b];
}
else{
state[x][y] = array[x][y];
}
}
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cout << state[i][j] << " ";
}
cout << endl;
}
}
I have basically got this function which clones the multidimensional array that is inputed but swaps the values of the two co-ordinates (a,b) and (c,d) around. This is then outputted out to the console.
However what I would really like is for this to be returned as a multidimensional array, but I don't think this can be done?
I have looked at vectors and pointers but don't really understand them and if I use them, I will then have to change all the previous code I have written.
There are multiple options.
Option 1 - pass the array to the function
void createArray(int a, int b, int c, int d, const int array[3][3], int outArray[3][3]){
...
}
Option 2 - return a reference to an array - just make sure the array does not live on the stack of the function it's returned from.
typedef int My3Times3Array[3][3];
const My3Times3Array& createArray(int a, int b, int c, int d, const int array[3][3]){
...
}
Option 3 - return a class that contains an array
struct Array
{
int array[3][3];
};
...
Array createArray(int a, int b, int c, int d, const int array[3][3]){
...
}
There's also std::vector, std::array, or boost::matrix, but since you mentioned you aren't comfortable with pointers yet, I'd save template classes for later.
When you want to return a non conventional data type (int, char etc), the best way of doing it is by making your very own one.
struct mat3
{
int myArray[3][3];
};
mat3 createArray(int a, int b, int c, int d, int array[3][3]){
mat3 state;
for(int x=0;x<3;x++){
for(int y=0;y<3;y++){
if(x == a && y == b){
state.myArray[x][y] = array[c][d];
}
else if(x == c && y == d){
state.myArray[x][y] = array[a][b];
}
else{
state.myArray[x][y] = array[x][y];
}
}
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cout << state.myArray[i][j] << " ";
}
cout << endl;
return state;
}
}
I have looked at vectors and pointers but don't really understand them and if I use them, I will then have to change all the previous code I have written
I suggest you study pointers further, they are so essential that you are already using them without knowing it.
You can dynamically allocate a two-dimensional array and return pointer to it. For example
typedef int ( *STATE )[3];
STATE createArray(int a, int b, int c, int d, int array[3][3]){
STATE state = new int[3][3];
//...
return state;
}
Or
int ( *createArray(int a, int b, int c, int d, int array[3][3] ) )[3]{
int ( * state )[3] = new int[3][3];
//...
return state;
}
In fact the same result you can get if you will use vectors. For example
#include <vector>
#include <array>
//...
std::vector<std::array<int, 3>> createArray(int a, int b, int c, int d, int array[3][3]){
std::vector<std::array<int, 3>> state( 3 );
//...
return state;
}
The following is how I was taught to use constructors, and it seems to work for one variable, but when I use a few it seems to act odd.
I'm not too sure what to do to fix this, but I would like some direction. Thanks in advance!
#include <iostream>
#include <string>
using namespace std;
class Numbers
{
public:
Numbers (int a, int b, int c)
{
setNum (a);
setNum (b);
setNum (c);
}
void setNum (int x, int y, int z)
{
numbers = x;
digits = y;
numerals = z;
}
int getNum ()
{
return numbers;
return digits;
return numerals;
}
int add (int x, int y, int z)
{
int answer = x + y + z;
return answer;
}
private:
int numbers;
int digits;
int numerals;
};
int main ()
{
Numbers numbersobject (12,13,14);
cout << numbersobject.getNum () << endl;
return 0;
}
Odd meaning compile error?!
In the constructor, look at your setNum, it must take 3 parameters. You probably need
setNum(a,b,c);
And you CANNOT return 3 elements in getNum, using 3 return statements. If you need to return more than 2 elements, use std::tuple, or std::pair for 2 elements.
You could change your constructor to use a member initialization list
Numbers (int a, int b, int c)
: numbers {a}, digits {b}, numerals {c} {}
Or the older version
Numbers (int a, int b, int c)
{
numbers = a;
digits = b;
numerals = c;
}
I suggest you simplify your constructor
class Numbers
{
public:
Numbers(int a, int b, int c)
: numbers(a), digits(b), numerals(c) // Initialization list
{ ; }
//...
};
In your simple class, there is no need for the constructor to call a setter function.