I'm trying to printing out sum of each pair of adjacent elements in a vector. But the code shown below is not giving me the correct result. Anyone can help me with this?
int main()
{
vector <int> num(10);
vector <int> res(5);
int get = 0;
int range = 0;
for (int i = 0; i != 10; ++i) {
cin >> get;
num.push_back(get);
}
while (range != num.size()) {
int c = 0;
int c1 = c + 1;
res.push_back(num[c] + num[c1]);
if (c == 0)
c = 1;
c *= 2;
++range;
}
cout << res[7];
for (int u = 0; u != res.size(); ++u) {
cout << res[u] << " ";
}
return 0;
}
Update: -
I've changed this code as you mentioned in the comment section, but when I compile it showing me a debug error.
I able to read 1-10 integers into the 'num' vector. But when I hit enter after read all the integers into the vector, this debug error happens.
int main()
{
vector <int> num;
vector <int> res;
int get = 0;
int range = 0;
int c = 0, c1 = 0;
for (int i = 0; i != 10; ++i) {
cin >> get;
num.push_back(get);
}
while (range != num.size()) {
c1 = c + 1;
res.push_back(num[c] + num[c1]);
if (c == 0)
c = 1;
c *= 2;
++range;
}
for (int u = 0; u != res.size(); ++u) {
cout << res[u] << " ";
}
keep_window_open();
return 0;
}
Why are you doing this:
if (c == 0)
c = 1;
c *= 2;
What it does on first iteration is that c = 1 then it multiplies it by 2, so c=2 for 2nd iteration and c1 becomes 3.
So first your code will do num[0] + num[1] and in next iteration it will do num[2] + num[3] and third will do num[4] + num[5] and fourth will do num[8]+num[9] and so on.
I can see two approaches to this:
1) If you want to do adjacent addition like 0+1, 1+2, 2+3 then simply do c++ instead of those three lines of code.
2) If you want to do adjacent addition like 0+1, 2+3, 4+5 you can simply do c = c1+1 instead of those three lines of code.
I think the issue is in the loop increment.
Try this
while (range < num.size())
{
int c = 0;
int c1 = c + 1;
res.push_back(num[c] + num[c1]);
c += 2;
++range;
}
I had to change your code to make it compile and to make it reproducible (a good MCVE doesn't require user input):
#include <iostream>
#include <vector>
int main()
{
const std::vector<int> num =
{ 0, 0,
5, 10,
-5, 5,
3, -20};
std::vector<int> res;
unsigned int range = 0;
int c = 0, c1 = 0;
while (range != num.size()) {
c1 = c + 1;
res.push_back(num[c] + num[c1]);
if (c == 0)
c = 1;
c *= 2;
++range;
}
for (unsigned int u = 0; u != res.size(); ++u) {
std::cout << res[u] << " ";
}
}
Your problem is that you are multiplying c by two, instead of adding two, each iteration.
Here's a more idiomatic version:
#include <iostream>
#include <vector>
int main()
{
const std::vector<int> num
= { 0, 0,
5, 10,
-5, 5,
3, -20, };
std::vector<int> res;
const auto last = num.end();
for (auto it = num.begin(); it != last; ) {
auto v = *it++;
res.push_back(v + (it == last ? 0 : *it++));
}
for (auto v: res)
std::cout << v << " ";
std::cout << std::endl;
}
If this is homework, I suggest you make sure you understand it fully before you hand it in.
One solution using STL iterators:
#include <iostream>
#include <vector>
#include <numeric>
int main()
{
std::vector<int> v
{ 0, 0,
5, 10,
-5, 5,
3, -20};
for(auto& r : v) std::cout << r << "\t"; std::cout << std::endl; // print
//Calculate now the adjacent sum (sum of consecutive elements)
std::adjacent_difference(v.begin(), v.end(), v.begin(), [](const int x, const int y) { return x+y; });//here, set execution policy to parallel if wanted
v.erase(v.begin()); // pop_front
// print now every second element. Change i+=2 to i++ if you want every consecutive sum
for(size_t i = 0; i<v.size(); i+=2) std::cout << v[i] << "\t"; std::cout << std::endl;
return 0;
}
which results in:
0 0 5 10 -5 5 3 -20
0 15 0 -17
The biggest issue I see here, in addition to what was mentioned in the comments, is that you're only incrementing range by 1 instead of 2. This causes your code to overshoot the end of the vector, which means your sum is being corrupted by garbage data.
Related
the requirement is a little bit complicated
let's say we have an unsorted array, for example: {12, 72, 93, 0, 24, 56, 102}
if we have an odd position, we have to look for the next greater element in his right, let's say we take v[1] = 12, the nge for '12' is 24;
but if we have an even position, we have to look for the next greater element in his left, let's say we take v[2] = 72, there s no number who s greater than '72', so we will print '-1'; let's take another example, v[4] = 0, the nge for '0' is 12;
the output should be: 24 -1 102 12 56 72 -1
i tried to solve this in c++:
#include <iostream>
using namespace std;
int main() {
const int CONST = 10000;
int n, v[CONST];
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> v[i];
}
for (int i = 1; i <= n; i++) {
int next = -1;
if (i % 2 != 0) {
for (int j = i + 1; j <= n; j++) {
if (v[j] > v[i]) {
next = v[j];
break;
}
}
cout << next << " ";
}
else {
for (int k = 1; k <= i - 1; k++) {
if (v[k] > v[i]) {
next = v[k];
break;
}
}
cout << next << " ";
}
}
return 0;
}
firstly, i think that i have to sort the array and after that to use binary search for finding the next greater element
For starters instead of the array it is much better to declare an object of the type std::vector<int>.
Pay attention to that indices in C++ start from 0.
In this if statement
if (v[j] > v[i]) {
next = v[j];
break;
}
you are exiting the loop as soon as the first element greater than the current is found. It is evident that this approach is wrong.
I can suggest the following solution.
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
size_t n = 0;
std::cin >> n;
v.resize( n );
for (auto &item : v)
{
std::cin >> item;
}
for (size_t i = 0, n = v.size(); i < n; i++)
{
size_t next = i;
if (i % 2 == 0)
{
for (size_t j = i + 1; j != n; ++j)
{
if (v[i] < v[j] && ( next == i || v[j] < v[next] ))
{
next = j;
}
}
}
else
{
for (size_t j = i; j-- != 0; )
{
if (v[i] < v[j] && ( next == i || v[j] < v[next] ))
{
next = j;
}
}
}
std::cout << ( next != i ? v[next] : -1 ) << ' ';
}
}
The program output might look like
7
12 72 93 0 24 56 102
24 -1 102 12 56 72 -1
If you are looking for something simple yet not very efficient (e.g. O(n) space complexity -vector copy- and O(nlogn) time complexity -sort plus search- instead of an O(n) for a linear search), this is an option:
next_greater checks if pos is even or odd, creates a couple of iterators first and last, and calls a templated next_greater with those iterators and the value to compare against, n.
a templated next_greater sorts [first, last) and then uses upper_bound to return the first element that is greater than n.
[Demo]
#include <algorithm> // upper_bound
#include <iostream> // cout
#include <utility> // pair
#include <vector>
template <typename InputIt, typename T>
T next_greater(InputIt first, InputIt last, T n)
{
std::sort(first, last);
auto it{ std::upper_bound(first, last, n) };
if (it == last) { return -1; }
return *it;
}
int next_greater(std::vector<int> v, size_t pos)
{
using it = std::vector<int>::iterator;
using pair_it = std::pair<it, it>;
auto [first, last] { (pos % 2 == 1)
? pair_it{ std::begin(v), std::begin(v) + pos } // [begin, pos)
: pair_it{ std::begin(v) + pos + 1, std::end(v) } // [pos + 1, end)
};
return next_greater(first, last, v[pos]);
}
int main()
{
const std::vector<int> v{12, 72, 93, 0, 24, 56, 102};
std::cout << "Next greater for i(n):\n";
for (size_t i{0}; i < v.size(); ++i)
{
std::cout << "\t" << i << "(" << v[i] << "): " << next_greater(v, i) << "\n";
}
}
// Outputs:
//
// Next greater for i(n):
// 0(12): 24
// 1(72): -1
// 2(93): 102
// 3(0): 12
// 4(24): 56
// 5(56): 72
// 6(102): -1
I was working on a problem in codeforces and I have no problems in the functionality of the code but the code exceeds the memory usage. Can someone explain how to improve this? How to learn about memory management in general while programming because I didn't find anything related to that. Here's my code :
Summary of the problem: You are given 6 input numbers, the first 5 numbers should be multiplied each by another integer and the summation of them after multiplication is the sixth integer in the input. You should find all the combinations of the numbers the can be multiplied by each value in the input to seek the summation. the output is basically the sum of the integers chosen for each number in the input to be multiplied by.
#include <iostream>
#include <vector>
#ifndef MAX
#define MAX 100
#endif
using namespace std;
void storeAndFilter(vector <int> &arr,int chosenNumConst, int mypasha);
void print(vector<int> &v);
int printsum(vector<int> &v);
int main(int argc, char const *argv[])
{
//array of input options
int a1, a2, a3, a4, a5, pasha;
cin >> a1 >> a2 >> a3 >> a4 >> a5 >> pasha;
//declarations of vectors
vector<int> arrStrA1;
vector<int> arrStrA2;
vector<int> arrStrA3;
vector<int> arrStrA4;
vector<int> arrStrA5;
//sorting and filtering the vectors
storeAndFilter(arrStrA1,a1,pasha);
storeAndFilter(arrStrA2,a2,pasha);
storeAndFilter(arrStrA3,a3,pasha);
storeAndFilter(arrStrA4,a4,pasha);
storeAndFilter(arrStrA5,a5,pasha);
//cout<<"All Posibilities valid (Minimized by removing values < pasha) : "<<endl;
// print (arrStrA1);
// print (arrStrA2);
// print (arrStrA3);
// print (arrStrA4);
// print (arrStrA5);
//scores vectors
vector<int> resultsA1;
vector<int> resultsA2;
vector<int> resultsA3;
vector<int> resultsA4;
vector<int> resultsA5;
int i,j,k,l,m;
for (i=0; i < (int)arrStrA1.size(); ++i)
{
for (j=0; j < (int)arrStrA2.size(); ++j)
{
for (k=0; k < (int)arrStrA3.size(); ++k)
{
for (l=0; l < (int)arrStrA4.size(); ++l)
{
for (m=0; m < (int)arrStrA5.size(); ++m)
{
if(arrStrA1.at(i)+arrStrA2.at(j)+arrStrA3.at(k)+arrStrA4.at(l)+arrStrA5.at(m)==pasha)
{
resultsA1.push_back(arrStrA1.at(i));
resultsA2.push_back(arrStrA2.at(j));
resultsA3.push_back(arrStrA3.at(k));
resultsA4.push_back(arrStrA4.at(l));
resultsA5.push_back(arrStrA5.at(m));
}
}
}
}
}
}
//divise each term by the card value
for (int i = 0; i < (int)resultsA1.size(); ++i)
{
if (a1==0)
resultsA1.at(i) /= 1;
else
resultsA1.at(i) /= a1;
}
for (int i = 0; i < (int)resultsA2.size(); ++i)
{
if (a2==0)
resultsA2.at(i) /= 1;
else
resultsA2.at(i) /= a2;
}
for (int i = 0; i < (int)resultsA3.size(); ++i)
{
if(a3==0)
resultsA3.at(i) /= 1;
else
resultsA3.at(i) /= a3;
}
for (int i = 0; i < (int)resultsA4.size(); ++i)
{
if (a4==0)
resultsA4.at(i) /= 1;
else
resultsA4.at(i) /= a4;
}
for (int i = 0; i < (int)resultsA5.size(); ++i)
{
if(a5==0)
resultsA5.at(i) /= 1;
else
resultsA5.at(i) /= a5;
}
//Uncomment to show the table list after division
// print(resultsA1);
// print(resultsA2);
// print(resultsA3);
// print(resultsA4);
// print(resultsA5);
int scra1=printsum(resultsA1);
int scra2=printsum(resultsA2);
int scra3=printsum(resultsA3);
int scra4=printsum(resultsA4);
int scra5=printsum(resultsA5);
cout << scra1 <<" "<< scra2 <<" "<< scra3 <<" "<<scra4 <<" "<< scra5 <<endl;
return 0;
}
void print(vector<int> &v)
{
int size = v.size();
cout<<"========================"<<endl;
for (int i = 0; i < size; ++i)
cout<<v.at(i)<<endl;
cout<<"========================"<<endl;
}
int printsum(vector<int> &v)
{
int sum =0;
for (int i = 0; i < (int)v.size(); ++i)
sum += v.at(i);
return sum;
}
void storeAndFilter(vector <int> &arr,int chosenNumConst, int mypasha)
{
arr.reserve(10);
int i=0;
for (; i <= MAX; ++i)
{
arr.push_back(i*chosenNumConst);
if (arr.at(i)>mypasha)
break;
}
arr.resize(i);
}
Some stuff that I thought about:
Arrays instead of Vectors maybe better
The nested for loops may be the one that is taking too much memory
But to be clear, the nested for loops doesn't make too much calculations, they find all the combinations of 5 numbers '5 loops' to sum to a specific value. Filtering before entering the loop is applied so maybe the nested loop isn't the issue.
Max memory constrain in the problem is: 256 MB
You can use much less memory by not using all those vectors. You can just write your code like this:
// make sure we handle zero properly
auto end = [&](int num){
return num == 0 ? num : pasha/num;
};
for (auto i=0, end_i = end(a1); i <= end_i; ++i)
{
for (auto j=0, end_j = end(a2); j <= end_j; ++j)
{
for (auto k=0, end_k = end(a3); k <= end_k; ++k)
{
for (auto l=0, end_l = end(a4); l <= end_l; ++l)
{
for (auto m=0, end_m = end(a5); m <= end_m; ++m)
{
if(a1*i+a2*j+a3*k+a4*l+a5*m==pasha)
{
std::cout << i << " " << j << " " << k << " " << l << " " << m << "\n";
}
}
}
}
}
}
and it outputs all the valid results. For Example for the input 0 2 3 4 5 6 it produces
0 0 2 0 0
0 1 0 1 0
0 3 0 0 0
See working example here
I'm trying to get the longest(largest) sequence of consecutive prime numbers from an array..
On first test with 10 elements in the array works , but when i tried with 15 elements like: 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 it spit out 4, which is incorrect.
#include <iostream>
using namespace std;
int main()
{
int bar[100];
int x, j = 0;
int maxseq = 0;
int longestseqstart = 0;
cout << "How big is the array? =";
cin >> x;
for (int i = 0; i < x; i++) {
cout << "bar[" << i << "]=";
cin >> bar[i];
}
for (int i = 1; i < x - 1; i = j) {
int startseq = i;
int seq = 0;
j = i + 1;
bool prim = true;
int a = bar[i];
for (int d = 2; d <= a / 2; d++) {
if (a % d == 0) {
prim = false;
}
}
while (j < x && prim) {
seq++;
if (seq > maxseq) {
maxseq = seq;
longestseqstart = i;
}
int a = bar[j];
for (int d = 2; d <= a / 2; d++) {
if (a % d == 0) {
prim = false;
}
}
j++;
}
}
cout << "The longest sequence is: ";
cout << maxseq;
return 0;
}
I would write the program the following way
#include <iostream>
#include <iterator>
#include <algorithm>
bool is_prime( unsigned int n )
{
bool prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
int main()
{
unsigned int a[] = { 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t maxseq = 0;
for ( auto current = std::find_if( a, a + N, is_prime );
current != a + N;
current = std::find_if( current, a + N, is_prime ) )
{
auto first = current;
current = std::find_if_not( current, a + N, is_prime );
size_t n = std::distance( first, current );
if ( maxseq < n ) maxseq = n;
}
std::cout << "The longest sequence is: " << maxseq << '\n';
return 0;
}
The program output is
The longest sequence is: 5
I did not use generic functions std::begin( a ) and std::end( a ) because in your program the array can contain less actual elements than the array dimension.
If you do not know yet standard C++ algorithms then the program can be defined the following way
#include <iostream>
bool is_prime( unsigned int n )
{
bool prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
int main()
{
unsigned int a[] = { 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t maxseq = 0;
size_t n = 0;
for ( size_t i = 0; i < N; i++ )
{
bool prime = a[i] % 2 == 0 ? a[i] == 2 : a[i] != 1;
for ( unsigned int j = 3; prime && j <= a[i] / j; j += 2 )
{
prime = a[i] % j != 0;
}
if ( prime )
{
if ( maxseq < ++n ) maxseq = n;
}
else
{
n = 0;
}
}
std::cout << "The longest sequence is: " << maxseq << '\n';
return 0;
}
The program output is the same as above
The longest sequence is: 5
As for your program then this loop
for (int i = 1; i < x - 1; i = j) {
skips the first element of the array that is bar[0].
And due to this statement
j = i + 1;
the calculated value of seq one less than it should be because you do not take into account that bar[i] is already prime.
Set initially seq equal to 1.
int seq = 1;
Moreover you incorrectly are determining prime numbers. For example according to your algorithm 1 is prime.
You are checking twice for prime numbers and you are using a nested loop. That's not necessary. It's enough to read all numbers, check each number, increment the count if it's a prime number and store the maximum sequence length.
#include <iostream>
#include <vector>
using namespace std;
bool isPrime(int a) {
bool prim = true;
for (int d = 2; d*d <= a; ++d) {
if (a % d == 0) {
prim = false;
}
}
return prim;
}
int main()
{
int x;
int longestseqstart = 0;
cout << "How big is the array? =";
cin >> x;
std::vector<int> bar(x);
for (int i = 0; i < x; i++) {
cout << "bar[" << i << "]=";
cin >> bar[i];
}
unsigned int count = 0;
unsigned int maxseq = 0;
for (const auto &el : bar) {
if (isPrime(el)) {
++count;
if (count > maxseq) maxseq = count;
} else count = 0;
}
cout << "The longest sequence is: ";
cout << maxseq;
return 0;
}
Of course you can avoid the usage of std::vector and functions with
#include <iostream>
using namespace std;
int main()
{
int x;
int longestseqstart = 0;
cout << "How big is the array? =";
cin >> x;
int bar[100];
for (int i = 0; i < x; i++) {
cout << "bar[" << i << "]=";
cin >> bar[i];
}
unsigned int count = 0;
unsigned int maxseq = 0;
for (unsigned int i = 0; i < x; ++i) {
int a = bar[i];
bool prim = true;
for (int d = 2; d*d <= a; ++d) {
if (a % d == 0) {
prim = false;
}
}
if (prim) {
++count;
if (count > maxseq) maxseq = count;
} else count = 0;
}
cout << "The longest sequence is: ";
cout << maxseq;
return 0;
}
The algorithm looks basically OK. The issue is mostly one of organization: the way the inner loop block is set up means that a run of primes will be short by 1 because the longest sequence is only updated at the beginning of the inner loop, missing the final prime.
A couple of minimal failing examples are:
How big is the array? =1
bar[0]=13
The longest sequence is: 0
How big is the array? =2
bar[0]=5
bar[1]=6
The longest sequence is: 0
Note that there's a repeated prime check in two places. This should not be. If we move all of the prime logic into the loop and test for a new longest sequence only after finishing the entire run, we'll have a clear, accurate algorithm:
#include <iostream>
int is_prime(int n) {
for (int i = 2; i <= n / 2; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
int nums[100];
int n;
std::cout << "How big is the array? =";
std::cin >> n;
for (int i = 0; i < n; i++) {
std::cout << "nums[" << i << "]=";
std::cin >> nums[i];
}
int longest = 0;
for (int i = 0, start = 0; i < n; i++) {
for (start = i; i < n && is_prime(nums[i]); i++);
longest = std::max(longest, i - start);
}
std::cout << "The longest sequence is: " << longest;
return 0;
}
In this rewrite I...
avoided using namespace std;.
removed unnecessary/confusing variables.
used clear variable names (bar should only be used in example code when the name doesn't matter).
moved is_prime to its own function.
But there are outstanding issues with this code. It should...
use a vector instead of an array. As it stands, it's vulnerable to a buffer overflow attack should the user specify an array length > 100.
use a faster method of finding primes. We only need to check up to the square root of the number and can skip a lot of numbers such as even numbers after 2. I suspect this is incidental to this exercise but it's worth mentioning.
move the longest_prime_sequence to a separate function (and possibly user input gathering as well).
Convert the array to a Boolean array and find longest length. Try this snippet(not optimized):
bool is_prime(int n) {
for (int i = 2; i < n; i++) {
if (n%i == 0) return false;
}
return true;
}
int main() {
//Input
unsigned int bar[15] = { 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 };
// Convert input to boolean array
bool boo[15];
for (int i = 0; i < 15; i++) {
boo[i] = is_prime(bar[i]);
}
//Check the longest boolean array
int longest = 0;
for (int i = 0; i < 15; i++) {
int count = 0;
while (boo[i + count] && (i+ count) <15) {
count++;
}
if (longest < count) longest = count;
}
//Output
cout << longest;
return 0;
}
I have a row of ten numbers for example:
5 5 6 7 5 9 4 2 2 7
Now I want a program that finds all duplicates and gives them out in the console like 3 times 5, 2 times 2, 2 times 7.
While I did code an algorithm that finds duplicates in a row of numbers I can't give them out in the console as described. My program will output:
3 times 5
2 times 5
2 times 7
2 times 2
How can I solve this problem?
#include <iostream>
using namespace std;
int main()
{
int arr[10];
int i,j;
int z = 1;
for(i = 0; i < 10; i++) {
cin >> arr[i];
}
for(i = 0; i < 10; i++){
for(j = i+1; j < 10; j++){
if(arr[i] == arr[j]){
z++;
}
}
if(z >= 2){
cout << z << " times " << arr[i] << endl;
z = 1;
}
}
return 0;
}
You can use the STL here (C++11):
int arr[10];
std::map<int, int> counters;
for (auto item : arr)
{
cin >> item;
++counters[item];
}
std::for_each(counters.begin(), counters.end(), [](const std::pair<int,int>& item)
{
if(item.second > 1) std::cout << item.second << " times " << item.first << std::endl;
});
You need to check that arr[i] is not already found before, like this for example:
if(z >= 2) {
int found_before = 0;
for(j = 0; j < i; ++j)
if(arr[i] == arr[j])
found_before = 1;
if(!found_before)
cout << z << " times " << arr[i] << endl;
z = 1;
}
which will print:
3 times 5
2 times 7
2 times 2
That way you don't print 5 again.
With your code it would print that it found 5 three times (for the first 5 in your array), and then when it would move to he second 5 in your array, it would forgot about the first 5 in your array, and report that it found 5 twice (itself and the 5th number of the array).
Why not use STL?
std::map<int, int> counter;
for (i = 0; i < 10; i++)
counter[arr[i]] ++;
for (i = 0; i < 10; i++) {
if (counter.count(arr[i]) > 0){
std::cout << counter[arr[i]] << " times "<< arr[i] << std::endl;
counter.erase(arr[i]);
}
}
std::map is a convenient tool for this job. You can easily count up occurrences of a specific number. After counting, you can print the count of each array element. With counter.erase, it's guaranteed that you won't print the same element for multiple times.
Why keeping your algorithm idea, I suggest to create sub method:
std::size_t count(const int* arr, std::size_t start, std::size_t end, int value)
{
std::size_t res = 0;
for (std::size_t i = start; i != end; ++i) {
if (arr[i] == value) {
++res;
}
}
return res;
}
then your fixed algorithm would be:
for (std::size_t i = 0; i != 10; ++i) {
if (count(arr, 0, i, arr[i]) != 0) {
continue; // Already visited
}
auto total = count(arr, i, 10, arr[i]);
if(total >= 2){
std::cout << z << " times " << arr[i] << std::endl;
}
}
An easy way is to make another array for it, especially if the numbers are not that big.
Lets say you have initialized your array like so: int nums[10] = { 5, 5, 6, 7, 5, 9, 4, 2, 2, 7 }
int result[max(nums)]; //Fill with zeroes, max(nums) is the highest number in the array
for(int i = 0; i < 10; i++) {
result[nums[i]]++;
}
for(int i = 0; i < max(nums); i++) {
if (result[i] > 1) cout << result[i];
}
Mind you this isn't optimized for memory. For larger number contents you might want to consider hashmaps.
If you don't need performance but rather compact code, then std::multiset with std::upper_bound is an alternative:
#include<set>
#include<iostream>
#include<algorithm>
int main(int a, char** b)
{
int array[] = {5, 5, 6, 7, 5, 9, 4, 2, 2, 7};
std::multiset<int> a(std::begin(array), std::end(array));
for(auto it = a.begin(); it != a.end(); it = std::upper_bound(a.begin(), a.end(), *it))
{
if(a.count(*it) > 1)
std::cout << *it << " times " << a.count(*it) << std::endl;
}
return 0;
}
I came across this question and I am stuck on this. It says,
Given a set N of integers and an integer y, determine if there exit
two elements in N whose absolute difference is equal to y and also
print those numbers. The algorithm should take O(n lg n) time.
Justify why your algorithm runs in O(n lg n) time. e.g. Let N= 3 , 7,
2, 1, 4, 10 y = 1 there are three pairs of elements in N whose
absolute difference is 1 Pair 1 = |3 - 2| = |-1| = 1 Pair 2 = |3 - 4|=
|-1| = 1 Pair 3 = |2 -1| = 1
I tried this in C++ as follows, but it does not handle all boundary cases like if y=8 for above example, it does not print anything however it should print (2,10).
vector<int> printPairs(vector<int> N1, vector<int> N2, int y){
int a = 0, b = 0;
vector<int> result;
while (a < N1.size() && b < N2.size()){
if (N1[a] < N2[b]){
result.push_back(N1[a]);
if (abs(N1[a] - N2[b]) == y)
cout << "(" << N1[a] << "," << N2[b] << ")" << endl;
a++;
}
else {
result.push_back(N2[b]);
if (abs(N1[a] - N2[b]) == y)
cout << "(" << N1[a] << "," << N2[b] << ")" << endl;
b++;
}
}
while (a < N1.size())
result.push_back(N1[a++]);
while (b < N2.size()){
result.push_back(N2[b++]);
}
return result;
}
vector <int> getPairs(vector<int> N, int y){
if (N.size() == 1)
return N;
vector <int> firstHalf = getPairs(vector<int>(N.begin(), N.begin() + N.size() / 2), y);
vector <int> secondHalf = getPairs(vector<int>(N.begin() + ceil(N.size() / 2), N.end()), y);
return printPairs(firstHalf, secondHalf, y);
}
Use std::set container.
Time complexity of std::set::find() is O(logN).
Calling N times find() costs you O(NlogN).
Code example:
#include <iostream>
#include <set>
int main() {
std::set<int> values = {3, 7, 2, 1, 4, 10};
int y = 1;
for (int elem : values) {
if (values.find(elem + y) != values.end()) {
std::cout << elem << " " << elem + y << std::endl;
}
}
return 0;
}
Output:
1 2
2 3
3 4
Another algorithm:
sort elements (NlogN)
for each element use binary search (logN per search query).
Example:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> values = {3, 7, 2, 1, 4, 10};
int y = 1;
std::sort(values.begin(), values.end());
for (int i = 0; i + 1 < values.size(); ++i) {
if (std::binary_search(
values.begin() + i + 1, values.end(), values[i] + y)) {
std::cout << values[i] << " " << values[i] + y << std::endl;
}
}
return 0;
}
Output:
1 2
2 3
3 4
Or you can simplify step 2 to O(N), by using two pointers idea:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> values = {3, 7, 2, 1, 4, 10};
int y = 1;
std::sort(values.begin(), values.end());
int l = 0, r = 0;
for (int i = 0; i + 2 < 2 * values.size(); ++i) {
if (r + 1 < values.size() &&
values[r] - values[l] <= y) {
++r;
} else {
++l;
}
if (values[l] + y == values[r]) {
std::cout << values[l] << " " << values[r] << std::endl;
}
}
return 0;
}
Total complexity will be the same (but the algorithm will be a little bit faster): O(NlogN) + O(N) = O(NlogN)