overload operator & to produce sum of int[][] - c++

it's a test from some company.
overload & to return sum of int[][]
main()
{
int arr[5][5];
// initialization
cout << &arr; // output the sum of arr
}
I try this code but returns compile error:
long operator &(int** arr)
{
// return the sum of arr
}
error: the argument should contains class type or enumeration
currently I understand this error, but how to overload operator for buildin types?

Example of overloading operator &, only for educational use!
I would NOT recommend overloading operator& in any serious code.
#include <iostream>
struct my_array
{
my_array()
{
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
values[i][j] = 1 + i + j;
}
}
}
int operator&()
{
int sum = 0;
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 5; ++j)
{
sum += values[i][j];
}
}
return sum;
}
private:
int values[5][5]{};
};
int main()
{
my_array m;
int sum = &m;
std::cout << sum;
}

I think interviewer may want you to overload operator<< actually, not & and the solution could then be like below. See it live here.
#include <iostream>
using int5x5_t = int[5][5];
std::ostream& operator<<(std::ostream& os, const int5x5_t* parr) {
long sum = 0;
for (auto& vec : *parr) {
for (auto val : vec) {
sum += val;
}
}
return os << sum;
}
int main() {
int arr[5][5] = {
{0, 1, 2, 3, 4},
{0, 1, 2, 3, 4},
{0, 1, 2, 3, 4},
{0, 1, 2, 3, 4},
{0, 1, 2, 3, 4}
};
std::cout << &arr << std::endl;
}

Related

Check if two arrays are equal or not

I am trying to know if the two given arrays are equal or not, irrespective of permutation of elements but contains the same elements and frequency of all the elements must be same.
int SameArray(int arr1[], int arr2[], int N, int M)
{
unordered_map<int, int> ump;
if(N == M)
{
for(int i = 0; i < N; i++)
{
ump[arr1[i]]++;
}
for(int i = 0; i< M; i++)
{
if(ump.find(arr2[i]) != ump.end())
ump[arr2[i]]--;
}
if(ump.empty())
return 1;
}
return 0;
}
it's not showing any errors but output is always 0.
You're looking for std::is_permutation:
bool SameArray(const std::vector<int>& arr1, const std::vector<int>& arr2) {
return std::is_permutation(arr1.begin(), arr1.end(), arr2.begin(), arr2.end());
}
I took the liberty of changing your function return to bool and taking std::vectors as function parameters since this is C++ and not C.
If you're curious about how std::permutation's comparasion works, look at its example implementation.
The condition in the if statement
if(ump.empty())
is not correct. The map can not be empty provided that the passed arrays do not have zero sizes.
Instead of the condition you could use the standard algorithm std::all_of. Also there is no sense to pass the two sizes of the arrays because if they are not equal to each other then it is evident that the arrays are not equal each other.
Also the array parameters shall be specified with the qualifier const because they are not changed in the function.
Here is a demonstrative program that shows how the function can be defined.
#include <iostream>
#include <iomanip>
#include <unordered_map>
#include <iterator>
#include <algorithm>
bool SameArray( const int a1[], const int a2[], size_t n )
{
sstd::unordered_map<int, int> m;
for ( const int *p = a1; p != a1 + n; ++p ) ++m[*p];
for ( const int *p = a2; p != a2 + n; ++p ) --m[*p];
return std::all_of( std::begin( m ), std::end( m ),
[]( const auto &p) { return p.second == 0; } );
}
int main()
{
const size_t N = 20;
int a1[N] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int a2[N] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << std::boolalpha << SameArray( a1, a2, N ) << '\n';
return 0;
}
Its output is
true
You need to check if every key in the map has a value of zero. Instead of ump.empty() you can do the below code.
for (auto& it: ump) {
if(it.second != 0) {
return 0;
}
return 1;
ump[arr2[i]]--; is not going to delete the key. You have to check whether the value of each entry is zero or not. I have added below statement before return 1 -
for (auto it = ump.begin(); it != ump.end(); ++it ) if(it->second != 0) return 0;
int SameArray(int arr1[], int arr2[], int N, int M)
{
unordered_map<int, int> ump;
if(N == M)
{
for(int i = 0; i < N; i++)
{
ump[arr1[i]]++;
}
for(int i = 0; i< M; i++)
{
if(ump.find(arr2[i]) != ump.end())
ump[arr2[i]]--;
}
for (auto it = ump.begin(); it != ump.end(); ++it ) if(it->second != 0) return 0;
return 1;
}
return 0;
}

c++ assignment operator overloading

Hello everyone i'm trying to write an assignment operator for this class so i can assign an array like thisint[] = {0, 1, 2, 3} to my Tableau class
originally i wanted to do this
Tableau<T>& operator=(T arr[])
{
return Tableau(tab, sizeofarray);
}
because i already wrote a constructor that takes and array and the size as its argument
and i ran into a problem with the size of the the array i don't know how to find it
how can i find the size of the array or is there a better way to do this
template<typename T>
class Tableau
{
public:
Tableau(int s = 0) : size(s), ptr(new T[size])
{
for (int i = 0; i < size; i++)
{
ptr[i] = 0;
}
}
Tableau(T tab[], int s = 0) : size(s), ptr(new T[size])
{
for (int i = 0; i < size; i++)
{
ptr[i] = tab[i];
}
}
~Tableau()
{
delete[] ptr;
}
Tableau<T>& operator=( T tab[])
{
}
T commule()
{
T com = 0;
for (int i = 0; i < size; i++)
{
com += ptr[i];
}
return com;
}
T& operator[](const int index)
{
return ptr[index];
}
private:
int size;
T* ptr;
};
int main()
{
int k[] = { 8, 12, 5, 9, 55};
Tableau<int> TI(k, 2);
TI = k;
return 0;
}
You can use:
template <std::size_t N>
Tableau<T>& operator=(T (&arr)[N])
{
// This is not right.
// The returned value is a temporary.
// return Tableau(arr, N);
// Update the contents of the object.
// ...
// Then, return a reference to this object.
return *this;
}
With that member function template, when you invoke:
int k[] = { 8, 12, 5, 9, 55};
Tableau<int> TI(k, 2);
TI = k;
The operator= function is instantiated with N = 5 and k as the value of arr. Hence, you get the size of the array as well as the contents of the array.
However, it is worth pointing out that if you use:
int k[] = { 8, 12, 5, 9, 55};
int* k2 = k;
Tableau<int> TI(k, 2);
TI = k2;
it won't work. k2 is not an array. It is a pointer to an int, which happens to point to the first element of k.

Operator overloading template parameter

So I have a little class that implements a matrix. Everything works well, except whatever gave me the reason to post here. I've explained more about the problem in the actual code, using comments. Thanks in advance to anyone that can help! This is not the entire program, but it is big enough so that it can compile on its own.
#include <iostream>
#include <initializer_list>
template<class type_t, unsigned Rows, unsigned Columns>
class matrix
{
private:
std::initializer_list<std::initializer_list<type_t>> elements;
public:
type_t contents[Rows][Columns];
matrix() {}
matrix(const std::initializer_list<std::initializer_list<type_t>> &container)
: elements(container)
{
unsigned i = 0;
for (const auto &el : elements)
{
unsigned j = 0;
for (const auto &num : el)
{
contents[i][j] = num;
j++;
}
i++;
}
}
unsigned rows() { return Rows; }
unsigned columns() { return Columns; }
type_t &operator()(const unsigned &i, const unsigned &j)
{
return contents[i][j];
}
template<unsigned rws, unsigned cls>
auto operator*(matrix<type_t, rws, cls> &mat)
{
matrix<type_t, Rows, 3> ret_mat; //OK, but only in case the return matrix has 3 columns
matrix<type_t, Rows, mat.columns()> ret_mat; //Error. This is the desired result
//The error message tells me it needs to be a compile-time constant
//it's pretty obvious why the first works and what the problem is
//but i still have no idea how to get past this
for (unsigned i = 0; i < this->rows(); ++i)
{
for (unsigned j = 0; j < mat.columns(); ++j)
{
for (unsigned in = 0; in < 2; ++in)
ret_mat.contents[i][j] += this->contents[i][in] * mat.contents[in][j];
}
}
return ret_mat;
}
};
int main()
{
matrix<int, 4, 2> mat = { { 7, 3 },{ 2, 5 },{ 6, 8 },{ 9, 0 } };
matrix<int, 2, 3> mat2 = { { 7, 4, 9 },{ 8, 1, 5 } };
auto mat3 = mat * mat2;
for (unsigned i = 0; i < mat3.rows(); ++i)
{
for (unsigned j = 0; j < mat3.columns(); ++j)
std::cout << mat3(i, j) << " ";
std::cout << std::endl;
}
std::cin.get();
}
template<unsigned rws, unsigned cls>
You already have desired expressions!
matrix<type_t, Rows, cls> ret;
Edit: as mentioned by #juanchopanza, why are you allowing multiplication of N*M on K*L with M != K? Should be
template<unsigned cls>
auto operator*(matrix<type_t, columns, cls> &mat)
{
matrix<type_t, Rows, cls> ret_mat;

Checking the array position

I am doing the program in which i am checking that if the array is balance or not like the array
int a5[] = {2, 1, 4, 3}; // balance array because i got even number on even position so program return 1
int a5[] = {3, 1, 4, 3}; // un balance array because i got odd number on even position so program return 0
This is my program which i am trying
int araay(int arg[], int length);
int main()
{
int a6[] = {3, 3, 4, 4};
int a7[] = {2, 2, 3, 4};
int a8[] = {4, 1, 2, 3};
int a9[] = {1, 1};
araay (a7,sizeof(a7));
}
int araay (int arg[], int length)
{
int sumEven = 0;
int sumOdd = 0;
for (int i=0; i<=length; i=i+2)
{
if (arg[i]%2 == 0)
{
sumEven++;
}
else
sumOdd++;
}
for (int i=1; i<=length; i=i+2)
{
if (arg[i]%2 == 0)
{
sumEven++;
}
else
sumOdd++;
}
return 0;
}
in return it always return me 00000 something like zero everytime
Following may help: (http://ideone.com/NttqbY)
bool is_balanced(const std::vector<std::size_t>& v)
{
for (std::size_t i = 0; i != v.size(); ++i) {
if ((i % 2) != (v[i] % 2)) {
return false;
}
}
return true;
}
Thanks all for your comments and help
This is what i tried
int araay(int arg[], int length);
int main()
{
int a6[] = {3, 3, 4, 4};
int a7[] = {2, 3, 2, 3};
int a8[] = {4, 1, 2, 3};
int a9[] = {1, 1};
araay (a7,3);
}
int araay (int arg[], int length)
{
int sumEven = 0;
int sumOdd = 0;
for (int i=0; i<=length; i+=2)
{
if (arg[i]%2 != 0)
{
cout<<"unbalanced"<<endl;
// return 0;
}
else
{
sumEven++;
}
}
for (int i=1; i<=length; i=i+2)
{
if (arg[i]%2 == 0)
{
cout<<"unbalanced"<<endl;
sumEven++;
}
else
{
sumOdd++;
// return 0;
}
}
return 0;
}
but the answer of #jarod is looking more suitable and easy
This is what you can do
#include <iostream>
int check(int arg[])
{
for (auto i = 0; i < sizeof(arg); ++i)
{
if ((i % 2) != (arg[i] % 2))
{
return 0;
}
}
return 1;
}
void main()
{
int a[] = { 1, 2, 3, 4 };
int b[] = { 2, 3, 4, 5 };
int c[] = { 2, 2, 3, 3 };
std::cout << "a = " << check(a) << std::endl;
std::cout << "b = " << check(b) << std::endl;
std::cout << "c = " << check(c) << std::endl;
getchar();
}

Use of a functor on for_each

Why does the for_each call on functor doesn't update sum::total at the end?
struct sum
{
sum():total(0){};
int total;
void operator()(int element)
{
total+=element;
}
};
int main()
{
sum s;
int arr[] = {0, 1, 2, 3, 4, 5};
std::for_each(arr, arr+6, s);
cout << s.total << endl; // prints total = 0;
}
for_each takes the functor by value - so it is copied. You can e.g. use a functor which is initialized with a pointer to an external int.
struct sum
{
sum(int * t):total(t){};
int * total;
void operator()(int element)
{
*total+=element;
}
};
int main()
{
int total = 0;
sum s(&total);
int arr[] = {0, 1, 2, 3, 4, 5};
std::for_each(arr, arr+6, s);
cout << total << endl; // prints total = 15;
}
Or you can use the return value from for_each
struct sum
{
sum():total(0){};
int total;
void operator()(int element)
{
total+=element;
}
};
int main()
{
sum s;
int arr[] = {0, 1, 2, 3, 4, 5};
s = std::for_each(arr, arr+6, s);
cout << s.total << endl; // prints total = 15;
}
for_each receives a copy of your functor by value. Even after that, it's free to copy it, but does return a copy.
OTOH, you're simply trying to re-invent std::accumulate, which will do the job much more easily:
int total = std::accumulate(arr, arr+6, 0);
cout << total << endl;
Because the s which you pass to the for_each is by value. for_each accepts it by value!
In C++0x, you can solve this problem with for_each as,
int sum = 0;
std::for_each(arr, arr+6, [&](int n){ sum += n; });
std::cout << sum ;
Output:
15
Demo at ideone : http://ideone.com/s7OOn
Or you can simple write in the std::cout itself:
std::cout<<std::for_each(arr,arr+6,[&](int n)->int{sum += n;return sum;})(0);
Run : http://ideone.com/7Hyla
Note such different syntax is okay for learning purpose, as to how std::for_each works, and what it returns, but I would not recommend this syntax in real code. :-)
In C++, you can write user-defined conversion function in the functor as,
struct add
{
int total;
add():total(0){};
void operator()(int element) { total+=element; }
operator int() { return total ; }
};
int main()
{
int arr[] = {0, 1, 2, 3, 4, 5};
int sum = std::for_each(arr, arr+6, add());
std::cout << sum;
}
It's slightly different version from Erik second solution : http://ideone.com/vKnmA
This happens due to std::for_each requires the functor to be passed by value .
A workaround for your solution:
struct sum
{
sum():total(0){};
int total;
sum(sum & temp)
{
total = temp.total;
}
void operator()(int element)
{
total+=element;
}
};
int main()
{
sum s;
int arr[] = {0, 1, 2, 3, 4, 5};
s = std::for_each(arr, arr+6, s); // result of for_each assigned back to s
cout << s.total << endl; // prints total = 0;
}
std::ref() is also another option if you want your object state gets updated after std::for_each
struct Sum
{
int total = 0;
void operator()(int i) { total += i; }
};
int main()
{
int arr[] = { 0, 1, 2, 3, 4, 5 };
Sum obj1;
Sum t1 = std::for_each(arr, arr + 6, obj1); // t1.total = 15
// (Note: obj1.total = 0 bcos it is passed by value)
Sum obj2;
std::for_each(arr, arr + 6, std::ref(obj2)); // obj2.total = 15 (NO copy)
Sum t2 = std::for_each(arr, arr + 6, Sum()); // t2.total = 15
}