Why doesn't this print anything on the screen? - c++

#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.

Related

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 am I getting zero in the output?

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 👍👍👍

Sorting vector (c++)

I have to sort a vector N into M equals parts(M less than N).
But those equal parts have to be in the middle. If I have parts that are not equal i need to put them in the first and/or last element.Difference between first and last has to be minimal. I have managed to make a sort of that function. Function is making new vector(sizeof(M)) and inside stores number of parts from vector N.
ex. 10/7 vector M [1 1 2 2 2 1 1] 1+1+2+2+2+1+1=10 into 7 parts. Meaning I am taking n or n+1 objects for vector N and storing index in vector M. Values inside do not have to be equal.
Now I am having trouble because my deviations can only be first and last element.
And also i am having problems whit for
ex. 12/9 because i get M[1 1 1 2 2 2 1 1 1 ]
but if I can only have first and last as different
then it should be like M[3 1 1 1 1 1 1 1 2]
So my question : Is there any better way of making this?
#include "stdafx.h"
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int N = 12; // size of vector
int M = 9; // numbers of divisions
static void subsizes(int vecSize, int subCount, vector<int> &v)
{
int baseSize = vecSize / subCount;
int bumps = vecSize % subCount;
int i,n=0,nPlus,counterPlus=0,counterN,counterLeft;
vector<int> temp(subCount); // for new results
vector<int> proba(subCount);
for (i = 0; i < subCount; i++) //dividing to n, n+1 and placing them in vector
{
temp[i]= baseSize + (i < bumps);
}
for (i=0; i<subCount; i++) // finding what numbers are n, n+1
{
nPlus=temp[i];
if(n==0 && n<nPlus){
n=nPlus;}
}
for(i=0; i<subCount;i++) //counting n, n+1
{
if(nPlus==temp[i])counterPlus++;
}
counterN=subCount-counterPlus;
counterLeft=counterPlus-2;
for(i=0; i<counterPlus/2; i++) //placing them in right order
temp[i]=nPlus;
for(i=counterPlus/2; i<counterPlus/2+counterN; i++)
temp[i]=n;
for(i=counterPlus/2+counterN; i<subCount; i++)
temp[i]=nPlus;
cout<<endl<<"Divided vector is :"<<endl; //printing results
for(i=0; i<subCount;i++)
{
int part = temp[i];
cout<<"At : vector["<<i<<"] nubmer of objects is --- "<<part<<endl;
}
putchar('\n');
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vec(N);
int vecSize = vec.size(); //length of original vector
int subCount=M; //number of sub-vectors parts
generate(vec.begin(), vec.end(), rand); // filling vector with C function rand()
cout<<"Vector is [ ";
for (auto i : vec) // printing out a vector
{
cout<<i<<" ";
}
cout<<"]"<<endl;
subsizes(vecSize,subCount,vec); // calling funciton that divideds and print results
system("PAUSE");
return 0;
}
You are complicating this, a lot.
If I understand you correctly
you want to take a vector of size N and divide it into M parts
Each of the M parts should have the same length
If there is remaining elements in N, you want to distribute the remainder to extra sub-parts at the beginning and end
Your output is a vector of the sizes of sub-parts
edit: it seems my assumption of "you want to distribute the remainder to extra sub-parts at the beginning and end" was wrong
If that is indeed what you want then you can just do this
void subsizes(int vecSize, int subCount, vector<int> &v)
{
int regular_size = (vecSize+2) / subCount;
int remainder = vecSize - regular_size * subCount;
vector<int> sizes(subCount, regular_size);
int front_remainder = remainder - (remainder / 2);
int back_remainder = remainder / 2;
sizes.front() += front_remainder;
sizes.back() += back_remainder;
for (int i = 0; i<sizes.size(); i++)
{
int part = sizes[i];
cout << "At : vector[" << i << "] nubmer of objects is --- " << part << endl;
}
putchar('\n');
}
I'm not sure I have a complete grip on your problem, but it appears that you are allowed to change the elements contained in vec. In which case, this is probably what you are looking for:
void subsizes(vector<int>& vec)
{
if(vec.size() > 1) // Don't do anything if there aren't at least 2 elements
{
// Get the sum of all the elements,
// but we're going to be adding back in 1s in every element but the last
// so subtract (vec.size() - 1) from this total.
// This is done by initializing accumulate to 1 - vec.size()
int last = accumulate(vec.begin(), vec.end(), 1 - vec.size());
// Now put 1s in all the elements
fill(vec.begin(), vec.end(), 1);
// Change the last element to the value accumulated in last
vec.back() = last;
}
}

How to change the order of elements in an array using a pointer?

For example, I have an array:
int Arr[10]={1,2,3,4,5,6,7,8,9,10};
How to change its order of elements using a pointer to receive the following array:
Arr={10,9,8,7,6,5,4,3,2,1}
to change the order odd and even using a pointer I've found this:
But I need only to reverse an array (without replacing odd and even)
#include <iostream>
using namespace std;
int main (const int& Argc, const char* Argv[]){
const int Nelem=10;
int Arr[]={1,2,3,4,5,6,7,8,9,10};
int *begAr=&Arr[0];
int *endAr=&Arr[Nelem];
int *itrAr=begAr;
int *tmpValAr=new int(0);
cout<<"Before\t1 2 3 4 5 6 7 8 9 10"<<endl;
while(itrAr<endAr){
*tmpValAr=*itrAr;
*itrAr=*(itrAr+1);
*(itrAr+1)=*tmpValAr;
itrAr+=2;
}
cout<<"After\t";
for(int i=0; i<Nelem; ++i)cout<<Arr[i]<<" ";
cout<<endl;
system("pause");
return 0;
}
Ok, a C-style approach using pointers to reverse an array? That shouldn't be too hard to figure out. Here's one approach:
int main ( void )
{
int i,//temp var
arr[10]= {1,2,3,4,5,6,7,8,9,10};//the array
int *start = &arr[0],//pointer to the start of the array
*end = &arr[9];//pointer to the last elem in array
//print out current arr values
for (i=0;i<10;++i)
printf("arr[%d] = %d\n", i, arr[i]);
do
{//simple loop
i = *start;//assign whatever start points to to i
*start = *end;//assign value of *end to *start
*end = i;//assign initial value of *start (stored in i) to *end
} while ( ++start < --end);//make sure start is < end, increment start and decrement end
//check output:
for (i=0;i<10;++i)
printf("arr[%d] = %d\n", i, arr[i]);
return 0;
}
As you can see here, this reverses the array just fine.
Use reverse found in <algorithm>:
std::reverse(Arr, Arr+10);
It will reverse a set of data like you are requesting.
This is the approximate implementation of the function, which you could adapt if necessary to your needs if you would like to write the loop yourself:
template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
while ((first!=last)&&(first!=--last)) {
std::iter_swap (first,last);
++first;
}
}
If you are in C or would like a less general solution, do something like this:
int i = 0; j = 9;
for(;i<j;++i;--j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = arr[i];
}
Take two pointers begAr pointing at arr[0] and endAr pointing at arr[9]. Traverse the array from both sides and swap *begAr with *endAr until begAr > endAr.
int tempValAr;
while(endAr >= begAr )
{
tempValAr = *begAr;
*begAr++ = *endAr;
*endAr-- = tempValAr;
}
See the test program.

Segregating an array for even and odd numbers

I have implemented an algorithm to change an array so that all the even numbers are moved to the beginning of the array and the old numbers to the end of the array. Here is my program :-
#include <iostream>
using namespace std;
void print(int arr[], int size) {
for(int i=0;i<size;i++) {
cout<<arr[i]<<" ";
}
cout<<endl;
}
void segregate(int arr[], int size) {
int l=0, h=size-1;
while(l<h) {
while(!(arr[l]%2) && l<size) {
l++;
}
while((arr[h]%2) && h >=0) {
h--;
}
swap(arr[l], arr[h]);
}
}
int main() {
int arr[] = {1,2,3,4,5,6,7,8,9};
int size = 9;
print(arr,size);
segregate(arr,size);
print(arr,size);
return 0;
}
I don't get the expected result
1 2 3 4 5 6 7 8 9
8 2 6 5 4 3 7 1 9
What am I missing?
What you're trying to do is also called partitioning. The standard library provides two algorithms to do just that: std::partition and std::stable_partition.
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9};
auto split = std::partition( std::begin(arr), std::end( arr ),
[]( int a ) { return ! a%2; } );
// [ begin, split ) are all even
// [ split, end ) are all odd
}
http://ideone.com/kZI5Zh
If you're still interesting in writing your own, cppreference's description of std::partition includes the equivalent code.
Your version is missing an if statement right before the swap. You should only swap when there is an odd on the left.
Problem 1:
You need to call the swap only if l has not crossed h, you are calling it always.
Consider the array {2,1}, which is already sgeregated.
Now after the two inner while loops l will be 1 and h will be 0. In your case you'll go ahead and swap, but a swap is not really needed since l has crossed h.
And when that happens the array is already segregated.
So change
swap(arr[l], arr[h]);
to
if(l<h) {
swap(arr[l], arr[h]);
}
Problem 2:
Also the order of conditions in your inner while loops must be reversed. You are checking
while(number at index l is even AND l is a valid index) {
l++;
}
which is incorrect. Consider an array {2,4}, now at some point in the above while loop l will be 2 and you go ahead and access arr[2], which does not exist.
What you need is:
while(l is a valid index AND number at index l is even) {
l++;
}
As simple as it gets:
void partitionEvenOdd(int array[], int arrayLength, int &firstOdd)
{
firstOdd = 0;
for (int i = 0; i < arrayLength; i++) {
if (array[i]%2 == 0) {
swap(array[firstOdd], array[i]);
firstOdd++;
}
}
}
Can't you just use standard sort?
Something like:
#include <stdio.h>
#include <stdlib.h>
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare (const void * a, const void * b)
{
// return -1 a-even and b-odd
// 0 both even or both odd
// 1 b-even and a-odd
}
qsort (values, 6, sizeof(int), compare);