Why am I getting zero in the output? - c++

So I'm trying to swap two numbers without using a third variable. I pass the two numbers I'm trying to swap by reference. When the same number is to be swapped (like 1 is to be swapped with 1), I get an output of zero. I know how to fix this, but I'm unable to understand as to why I keep getting 0 when a and b are the same.
Can anyone explain why I'm getting zero instead of the swapped numbers?
void swap(int *a,int *b)
{
//if(a==b)
// return;
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
int main()
{
int n=3,x=0,y=0;
int a[n][n];
for(int i=0;i<n;i++)
swap(&a[x][i],&a[i][y]);
return 0;
}

It seems you are trying to swap elements of the first row with elements of the first column.
For starters variable length arrays is not a standard C++ feature. Though some compilers have their own language extensions you should avoid their using.
Also the swap function can have undefined behavior because when there is an overflow of a signed integer then the result is undefined. It is better to use the standard C++ function std::swap.
And in your program you are using an uninitialized array.
Here is a demonstrative program that shows how you could write the code
#include <iostream>
#include <utility>
int main()
{
const size_t N = 3;
int a[N][N];
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
a[i][j] = i * N + j;
}
}
for ( const auto &row : a )
{
for ( const auto &item : row )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
for ( size_t i = 0; i < N; i++ )
{
std::swap( a[0][i], a[i][0] );
}
for ( const auto &row : a )
{
for ( const auto &item : row )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
return 0;
}
Its output is
0 1 2
3 4 5
6 7 8
0 3 6
1 4 5
2 7 8
If you want to write your own swap function then write it like
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
and use it in the program like
::swap( &a[0][i], &a[i][0] );

As far as i understood your code. You are trying to swap first row elements with its corresponding elements in the first column..
You are getting 0 at position a[0][0] in the matrix.
The reason is simple..
Look at this steps in your code
*b=*a-*b;
*a=*a-*b;
You are substracting same from that value..
Obviously result will be 0.
And yeh the idea of swapping row with column is really creative 👍👍👍

Related

Why doesn't push_back keep working in a loop?

Completely new to C++. Programmed selection sort on 1D array of arbitrary length. Want to allow user to keep inputting integers into console to make an array of desired length, to be subsequently sorted.
Can only seem to make arrays of length 2 using a while loop for adding elements. Code and example of erroneous result when inputting 6, 2, 3, and 9 shown below.
Script:
// Preprocessor directives and namespace declaration
#include <iostream>
#include <vector>
using namespace std;
// Function
void SelectionSort(int *arr, int len)
{
// Loop through index j in arr
for (int j = 0; j < len; j++) {
// Assume element j is minimum, and initialise minIndex
int min = arr[j];
int minIndex = j;
// Loop through comparisons to determine actual minimum
// (of elements after and including j)
for (int i = j; i < len; i++)
{
if (min > arr[i])
{
min = arr[i];
minIndex = i;
}
}
// Swap minimum with element j
int temp = arr[j];
arr[j] = min;
arr[minIndex] = temp;
}
// Display resulting array
for (int i = 0; i + 1 < len; i++)
{
cout << arr[i] << ", ";
}
cout << arr[len - 1] << endl;
}
// Main
int main()
{
// Explain program to user
cout << "Sort 1D array of user-inputted length/contents" << endl;
cout << "To finish array, enter -999" << endl;
// Initialise dynamic array
vector<int> vDyn (1);
vDyn[0] = 0;
cout << "Enter first element of array: ";
int firstElement = 0;
cin >> firstElement;
vDyn[0] = firstElement;
// Loop to define elements until desired length reached
bool keepGoing = true;
while (keepGoing == true)
{
cout << "Enter another element: ";
int newElement = 0;
cin >> newElement;
if (newElement != -999)
{
vDyn.push_back(newElement);
} else
{
keepGoing = false;
}
}
// Convert vector to array (dynamic to static)
int* v = &vDyn[0];
// Get array length
int len = sizeof(v) / sizeof(v[0]);
// Run SelectionSort function
SelectionSort(v, len);
return 0;
}
Terminal:
Sort 1D array of user-inputted length/contents
To finish array, enter -999
Enter first element of array: 6
Enter another element: 2
Enter another element: 3
Enter another element: 9
Enter another element: -999
2, 6
This declaration
int len = sizeof(v) / sizeof(v[0]);
is equivalent to the declaration
int len = sizeof( int * ) / sizeof( int );
because the variable v is declared like
int* v = &vDyn[0];
The size of a pointer is equal usually to 4 or 8 bytes. So the variable length will have the value either 1 or 2 and does not depend on the number of elements stored in the vector..
Instead you should use for example
size_t len = vDyn.size();
You could declare the function like
void SelectionSort(int *arr, size_t len);
and call it like
SelectionSort( vDyn.data(), vDyn.size() );
Also as in C++ there is standard function std::swap declared in the header <utility> then instead of this code snippet
// Swap minimum with element j
int temp = arr[j];
arr[j] = min;
arr[minIndex] = temp;
you could just write
if ( j != minIndex ) std::swap( arr[j], arr[minIndex] );
And the inner for loop could look like
for ( size_t i = j + 1; i < len; i++)
^^^^^
In fact your function SelectionSort is a C function. A C++ function should be more general and use iterators. In this case it could sort arrays along with other containers.
Here is a demonstration program that shows a more general function called for an array based on a vector.
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
template <typename ForwardIterator>
void SelectionSort( ForwardIterator first, ForwardIterator last )
{
for ( ; first != last; ++first )
{
auto current_min = first;
for ( auto next = std::next( first ); next != last; ++next )
{
if ( *next < *current_min ) current_min = next;
}
if ( current_min != first )
{
std::iter_swap( current_min, first );
}
}
}
int main()
{
std::vector<int> v = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << '\n';
SelectionSort( v.data(), v.data() + v.size() );
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
In general you need also to write an overloaded function that accepts also a comparison function.
// Convert vector to array (dynamic to static)
int* v = &vDyn[0];
This line doesn't convert the array to anything. You merely take address of the first element in the vector.
If you want to take an underlying c-array from std::vector you are supposed to use data property of it.
Also, since the array is decayed into a pointer, it no longer contains data of its size. You should rely on std::vector properties (i.e. std::vector::size) to pass this information forward

Vector - value with k-occurences first

This is my first post and hope I'm not doing anything wrong.
I am trying to write a program that find the first value of the vector that reach k-occurrences in it.
For example, given this vector and k=3:
1 1 2 3 4 4 2 2 1 3
I would see 2 as output, because 2 is the first number reaching the 3rd occurrence.
The following code is what I tried to run, but somehow output is not correct.
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> vettore;
int k;
int a,b,i;
int occ_a;
int occ_b;
cout<< "Write values of vector (number 0 ends the input of values)\n";
int ins;
cin>>ins;
while(ins)
{
vettore.push_back(ins); //Elements insertion
cin>>ins;
}
cout<<"how many occurrences?\n"<<endl;;
cin>>k;
if(k>0)
{
int i=0;
b = vettore[0];
occ_b=0;
while(i< vettore.size())
{
int j=i;
occ_a = 0;
a = vettore[i];
while(occ_a < k && j<vettore.size())
{
if(vettore[j]== a)
{
occ_a++;
vettore.erase(vettore.begin() + j);
}
else
j++;
}
if(b!=a && occ_b < occ_a)
b = a;
i++;
}
cout << b; //b is the value that reached k-occurrences first
}
return 0;
}
Hours have passed but I have not been able to solve it.
Thank you for your help!
Your code is difficult to read because you are declaring variables where they are not used. So their meanings is difficult to understand.
Also there is no need to remove elements from the vector. To find a value that is the first that occurs k-times is not equivalent to to change the vector. They are two different tasks.
I can suggest the following solution shown in the demonstrative program below.
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = { 1, 1, 2, 3, 4, 4, 2, 2, 1, 3 };
size_t least_last = v.size();
size_t k = 3;
for ( size_t i = 0; i + k <= least_last; i++ )
{
size_t count = 1;
size_t j = i;
while ( count < k && ++j < least_last )
{
if ( v[j] == v[i] ) ++count;
}
if ( count == k )
{
least_last = j;
}
}
if ( least_last != v.size() ) std::cout << v[least_last] << '\n';
return 0;
}.
The program output is
2
The idea is to find the last position of the first element that occurs k-times. As soon as it is found the upper limit of the traversed sequence is set to this value. So if there is another element that occurs k-times before this limit then it means that it occurs the first compared with already found element.

Why doesn't this print anything on the screen?

#include <iostream>
using namespace std;
class A
{
public:
int index;
int t;
int d;
int sum;
};
A arr[1000];
bool comp (const A &a, const A &b)
{
if (a.sum < b.sum)
return true;
else if (a.sum == b.sum && a.index < b.index)
return true;
return false;
}
int main (void)
{
int n,foo,bar,i;
i = 0;
cin>>n;
while ( n != 0 )
{
cin>>foo>>bar;
arr[i].index = i+1;
arr[i].t = foo;
arr[i].d = bar;
arr[i].sum = arr[i].t+arr[i].d;
n--;
i++;
}
sort(arr,arr+n,comp);
for ( int j = 0; j < n; j++ )
cout<<arr[j].index;
cout<<"\n";
return 0;
}
So, I made this program which accepts values from users, and then sorts them on the basis of a specific condition. However, when I try to print the values of the array, it doesn't print it. I don't know why. Please help. Thanks!
PS: I even tried to print the value of the array without use of comparator function, but still it doesn't print.
Edit: Got my error, as mentioned by some amazing people in the comments. However, on inputting the values as,
5
8 1
4 2
5 6
3 1
4 3
It should return the answer as 4 2 5 1 3 but instead it returns 1 2 3 4 5. Basically, it sorts according to the sum of the 2 elements in each row and prints the index. What might be the problem?
It is not sorting because you are modifying the value of n in the while loop.
So, when n = 0 after the loop ends, there is nothing to sort (or to print later for that matter):
sort( arr, arr + n, comp);
is equivalent to
sort( arr, arr + 0, comp);
Easiest approach would be to use a for loop:
for( int i=0; i<n; ++i )
{
....
}
This way, n remains unchanged.

How can we swap 2 arrays in constant complexity or O(1)?

How can we swap 2 arrays in constant complexity or O(1)? Is there a way that we can do this? I have tried using pointers but it is giving an error
Moreover, this won't help because it is just interchanging the pointers but not the arrays:
#include <algorithm>
int AA[100], *A=AA, BB[100], *B=BB;
swap(A, B);
I have tried using vectors assignment operator as well but they have LINEAR complexity i.e. O(N) not constant. So, is there any way we can swap two arrays in O(1)? (by using pointers or something else)
I have tried searching on the internet and found a link to codeforces ( http://codeforces.com/blog/entry/11971 ) but this is not helping.
Using std::swap (that uses member function swap) for vectors (std::vector) has a complexity of O(1).
From the C++ Standard:
void swap(vector& x);
10 Effects: Exchanges the contents and capacity() of *this with that of x.
11 Complexity: Constant time.
You could "swap arrays" with a constant time if they were allocated dynamically with operator new. In this case, you indeed could swap only pointers that point to the first elements of the arrays.
For example:
#include <iostream>
#include <algorithm>
int main() {
int **a = new int *[2];
a[0] = new int[5] { 0, 1, 2, 3, 4 };
a[1] = new int[5] { 5, 6, 7, 8, 9 };
for ( size_t i = 0; i < 2; i++ ) {
for ( size_t j = 0; j < 5; j++ ) {
std::cout << a[i][j] << ' ';
}
std::cout << std::endl;
}
std::cout << std::endl;
std::swap( a[0], a[1] );
for ( size_t i = 0; i < 2; i++ ) {
for ( size_t j = 0; j < 5; j++ ) {
std::cout << a[i][j] << ' ';
}
std::cout << std::endl;
}
std::cout << std::endl;
delete [] a[0];
delete [] a[1];
delete [] a;
return 0;
}
The output is:
0 1 2 3 4
5 6 7 8 9
5 6 7 8 9
0 1 2 3 4
In fact, the same operation is done in std::vector.

Build a string using recursion in c++

I have a matrix of values (stored as an array of values) and a vector with the matrix dimensions( dims[d0, d1, d2]).
I need to build a string like that:
"matA(j, k, l) = x;"
where j, k, l are the indices of the matrix and x the value of the element. I need to write this for each value of the matrix and for matrices with 2 to n dimensions.
I have a problem isolating the base case and replicating it in a useful way. I did a version in a switch case with a case for each dimension and a number of for cycles equal to the number of dimensions:
for (unsigned int k=1; k<=(dims[2]); k++)
{
for (unsigned int j=1; j<=(dims[1]); j++)
{
for (unsigned int i=1; i<=(dims[0]); i++)
{
strs << matName << "(" << i << "," << j << ","<< k << ")="<< tmp[t]<< "; ";
....
but is not what I wanted.. Any idea for a more general case with a variable number of dimensions?
You need a separate worker function to recursively generate the series of indices and main function which operates on it.
For example something like
void worker(stringstream& strs, int[] dims, int dims_size, int step) {
if (step < dims_size) {
... // Add dims[step] to stringstream. Another if may be necessary for
... // whether include `,` or not
worker(strs, dims, dims_size, step + 1);
} else {
... // Add cell value to stringstream.
}
}
string create_matrix_string(int[] dims, int dims_size, int* matrix) {
... // Create stringstream, etc.
strs << ... // Add matrix name etc.
worker(strs, dims, dims_size, 0);
strs << ... // Add ending `;` etc.
}
The main problem here is the value, since the dimension is not known during compilation. You can avoid that by encoding matrix in single-dimensional table (well, that's what C++ is doing anyway for static multidimensional tables) and call it using manually computed index, eg. i + i * j (for two-dimensional table). You can do it, again, by passing an accumulated value recursively and using it in final step (which I omitted in example above). And you probably have to pass two of them (running sum of polynomial components, and the i * j * k * ... * x product for indices from steps done so far.
So, the code above is far from completion (and cleanliness), but I hope the idea is clear.
You can solve this, by doing i, j and k in a container of the size of dim[] - sample:
#include <iostream>
#include <vector>
template< typename Itr >
bool increment( std::vector< int >& ijk, Itr idim, int start )
{
for( auto i = begin(ijk); i != end(ijk); ++i, ++idim )
{
if( ++*i <= *idim )
return true;
*i = start;
}
return false;
}
int main()
{
using namespace std;
int dim[] = { 5, 7, 2, 3 };
const int start = 1;
vector< int > ijk( sizeof(dim)/sizeof(*dim), start );
for( bool inc_done = true; inc_done
; inc_done = increment( ijk, begin(dim), start ) )
{
// .. here make what you want to make with ijk
cout << "(";
bool first = true;
for( auto j = begin(ijk); j != end(ijk); ++j )
{
if( !first )
cout << ",";
else
first = false;
cout << *j;
}
cout << ")= tmp[t] " << endl;
}
return 0;
}