Count pairs with given sum - c++

Given an array of integers, and a number ‘sum’, find the number of pairs of integers in the array whose sum is equal to ‘sum’. This is the solution by Geeks for Geeks:
// C++ implementation of simple method to find count of
// pairs with given sum.
#include <bits/stdc++.h>
using namespace std;
// Returns number of pairs in arr[0..n-1] with sum equal
// to 'sum'
int getPairsCount(int arr[], int n, int sum)
{
unordered_map<int, int> m;
// Store counts of all elements in map m
for (int i=0; i<n; i++)
m[arr[i]]++;
int twice_count = 0;
// iterate through each element and increment the
// count (Notice that every pair is counted twice)
for (int i=0; i<n; i++)
{
twice_count += m[sum-arr[i]];
// if (arr[i], arr[i]) pair satisfies the condition,
// then we need to ensure that the count is
// decreased by one such that the (arr[i], arr[i])
// pair is not considered
if (sum-arr[i] == arr[i])
twice_count--;
}
// return the half of twice_count
return twice_count/2;
}
// Driver function to test the above function
int main()
{
int arr[] = {1, 5, 7, -1, 5} ;
int n = sizeof(arr)/sizeof(arr[0]);
int sum = 6;
cout << "Count of pairs is "
<< getPairsCount(arr, n, sum);
return 0;
}
My big question is, what is sum-arr? It is not declared, so it must be built in C++. However, I can't find any documentation of it and I am unsure on how it works.
I am trying to follow the code, and it doesn't make sense the sum-arr values.
arr [1,5,8,-1,5]
m [0,1,0,0,0]
sum-arr [5,1,-2,7,1]

Expression, sum - arr[n] which yields the value stored in the nth position of the array.
Here, the value of arr at n (here at the position where i points, since it is arr[i]) is subtracted with the value of sum.
Given, you say,
int arr[] = { 1, 5 , 8, -1, 5 }
and
int sum = 6
Then, for example, take i as 0...
arr[i] is represented as arr[0] which means pointing to the first element (0) in the array arr. Here, the value is 1.
And subtracting 1 from 6, we get 5.
On the other hand, sum - arr is the subtraction of an integer(int) with a pointer(int arr[] will become int * arr inside the program), which, in fact, is not possible, since a super-pointer is bigger than a sub-pointer...
However, you can do, sum - *arr (which is called dereferencing).
Last words,
Just to reduce all this confusion with using pointers and everything, just use std::vector<type>(Example: std::vector<int> arr;), which is a common practice in C++ and whats more, works just like them too! (You are stuck to using pointers in C though!).
Good luck!

My big question is, what is sum-arr?
sum is an id-expression. It names a variable of type int.
arr is an id-expression. It names a different variable, which is of type int*. It is also a sub-expression of the expression arr[i]. That expression is the subscript operator, which in this case increments the pointer arr to its i'th successive sibling in the array and indirects the pointer.
- is the subtraction operator. sum expression is the left hand operand, and arr[i] is the right hand operand.

Related

Duplicates in Array

Given an integer array nums sorted in non-decreasing order, remove some duplicates in-place such that each unique element appears at most twice. The relative order of the elements should be kept the same.
Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array nums. More formally, if there are k elements after removing the duplicates, then the first k elements of nums should hold the final result. It does not matter what you leave beyond the first k elements.
Return k after placing the final result in the first k slots of nums.
What is wrong with my code ??
map<int,int> m;
for(int i = 0 ; i < nums.size() ; i++){
m[nums[i]]++;
if(m[nums[i]] > 2)nums.erase(nums.begin() + i);
}
return nums.size();
From the given text, we can derive the following requirements
Given an integer array nums
sorted in non-decreasing order,
remove some duplicates in-place such that each unique element appears at most twice.
The relative order of the elements should be kept the same.
Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array nums.
More formally, if there are k elements after removing the duplicates, then the first k elements of nums should hold the final result.
It does not matter what you leave beyond the first k elements
Return k after placing the final result in the first k slots of nums.
So, after elicitating the requirements, we know that we have a fixed size array, presumably (because of the simplicity of the task) a C-Style array or a C++ std::array. Because of the shown source code, we assume a std::array.
It will be sorted in increasing order. Their shall be an in-place removal of elements. So, no additional variables. The rest of the requirements already shows the solution.
--> If we find duplicates (more than 2) we will shift the rest of the values one to the left and overwrite one of the duplicates. Then the logical number of elements in the array will be one less. So, the loop must run one step less.
This ends up in a rather simple program:
#include <iostream>
#include <array>
// Array with some test values
constexpr int ArraySize = 25;
std::array<int, ArraySize> nums{ 1,2,2,2,3,3,3,4,4,4,4,4,6,5,5,5,5,5,6,6,6,6,6,6,9,9 };
int main() {
// Currentlogical end of the data in the array. In the beginning, last value in the array
size_t endIndex = nums.size();
// Check allelments from left to tright
for (size_t index = 0; index < endIndex;) {
// Check, if 3 elements are same
if ((index < (endIndex -2)) and nums[index] == nums[index + 1] and nums[index + 1] == nums[index + 2]) {
// Yes, found 3 same elements. We willdelete one, so the endIndex needs to be decremented
--endIndex;
// Now hsift all array elements one to the left
for (size_t shiftIndex = index + 2; shiftIndex < endIndex; ++shiftIndex)
nums[shiftIndex] = nums[shiftIndex + 1];
}
else ++index;
}
// SHow result
std::cout << endIndex << '\n';
}
I can offer the solution of your problem.
#include <iostream>
#include <vector>
#include <set>
using namespace std;
void showContentSet(set<int>& input)
{
for(auto iterator=input.begin(); iterator!=input.end(); ++iterator)
{
cout<<*iterator<<", ";
}
return;
}
void showContentVector(vector<int>& input)
{
for(int i=0; i<input.size(); ++i)
{
cout<<input[i]<<", ";
}
return;
}
void solve()
{
vector<int> numbers={1, 2, 1, 3, 4, 5, 7, 5, 8, 5, 9, 5};
set<int> indicesToDelete;
for(int i=0; i<numbers.size(); ++i)
{
int count=0;
for(int j=0; j<numbers.size(); ++j)
{
if(numbers[i]==numbers[j])
{
++count;
if(count>2)
{
indicesToDelete.insert(j);
}
}
}
}
cout<<"indicesToDelete <- ";
showContentSet(indicesToDelete);
int newOrder=0;
cout<<endl<<"Before, numbers <- ";
showContentVector(numbers);
for(auto iterator=indicesToDelete.begin(); iterator!=indicesToDelete.end(); ++iterator)
{
numbers.erase(numbers.begin()+(*iterator-newOrder));
++newOrder;
}
cout<<endl<<"After, numbers <- ";
showContentVector(numbers);
cout<<endl;
return;
}
int main()
{
solve();
return 0;
}
Here is the result:
indicesToDelete <- 9, 11,
Before, numbers <- 1, 2, 1, 3, 4, 5, 7, 5, 8, 5, 9, 5,
After, numbers <- 1, 2, 1, 3, 4, 5, 7, 5, 8, 9,
I suggest using a frequency array.
frequency array works, That you count how many duplicates of each number while inputting, It's stored usually in an array called freq, Also can be stored in a map<int, int> or unordered_map<int, int>.
And because of input is in non-decreasing order, outputting this solution will be easy.
Note: this solution won't work if input numbers is bigger than 10^5
Solution:
#include <iostream>
const int N = 1e5 + 1; // Maximum size of input array
int n;
int nums[N], freq[N];
int main()
{
// Input
std::cin >> n;
for (int i = 0; i < n; i++)
{
std::cin >> nums[i];
freq[nums[i]]++;
}
// Outputting numbers, Using frequency array of it
for (int i = 0; i < N; i++)
{
if (freq[i] >= 1)
std::cout << i << ' ';
if (freq[i] >= 2)
std::cout << i << ' ';
}
return 0;
}
This is basically a conditional copy operation. Copy the entire range, but skip elements that have been copied twice already.
The following code makes exactly one pass over the entire range. More importantly it avoids erase operations, which will repeatedly shift all elements to the left.
vector<int> nums; // must be sorted already
if (nums.size()<=1)
return; // already done
// basically you copy all elements inside the vector
// but copy them only if the requirement has been met.
// `in` is the source iterator. It increments every time.
// `out` is the destination iterator. It increments only
// after a copy.
auto in=nums.begin();
auto out=nums.begin();
// current is the current 'int' value
int current=*in;
// `count` counts the repeat count of the current value
int count=0;
while (in!=nums.end()) {
if (*in==current) {
// The current value repeats itself, so increment
// the count value
++count;
} else {
// No, this is a new value.
// initialise current and count
current=*in;
count=1;
}
if (count<=2) {
// only if at most two elements of the same value
// copy the current value to `out`
*out=current;
++out;
}
// try next element
++in;
}
// out points to the last valid element + 1

next_permutation not by reference?

I do not understand why inside the loop, the position of the values are changed. But outside do, while loop, all the values return to the original positions. Thus i need the //here code. I also tried a pointer array, but it showed the same behavior. Why so?
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[] = {0, 1, 2};
do
{
for (int i = 0; i < 3; i++)
cout << a[i];
cout << endl;
} while (next_permutation(a, a + 3));
cout << endl;
// here
a[0] = 2;
a[1] = 1;
a[2] = 0;
do
{
for (int i = 0; i < 3; i++)
cout << a[i];
cout << endl;
} while (prev_permutation(a, a + 3));
return 0;
}
Thats how next_permutation is defined. The last permutation (the one that returns false) is the one that puts the elements in sorted order.
I suppose there is another misunderstanding. Here:
do
{
print_permutation();
} while (next_permutation(a, a + 3));
The last permutation you print inside the loop is that one before the one that makes next_permutation return false. Hence in the last iteration you are not printing the same permutation as outside of the loop. It is similar to:
bool increment(int& i) {
++i;
return i<10;
}
int i = 0;
do {
std::cout << i;
} while( increment(i) );
std::cout << i;
The last value printed inside the loop is 9, but the value of i after the loop is 10.
Every time it is called, std::next_permutation generates an permutation P' of the given container a where the current permutation is, say, P. As long as the permutation P' it generates is greater than P, it returns true. However, in the case for P being the greatest (i.e., see below for an explanation of greatness) permutation of the elements in the given container a, for instance P=[2, 1, 0] the next permutation P' it generates is [0, 1, 2], which is not greater than P. In that case, it returns false and the loop terminates. But, due to the side effect of the process, once the function returns, the elements in the container are already placed in that smallest permutation possible. That is why you see those elements in their smallest permutation possible after the loop terminates.
The word greater may be a little confusing. Basically std::next_permutation uses whatever comparison operators are available to compare individual elements and ends up iterating over them in a way that lexicographically increases with each following permutation. So, for a vector of [0, 1, 2], it would iterate the following permutations in that order:
0, 1, 2
0, 2, 1
1, 0, 2
1, 2, 0
2, 0, 1
2, 1, 0
That is why, the function recognizes that [0,1,2] would not be a greater permutation after [2,1,0] and returns false.

A function that convert a number into a vector array in c++

vector<int> initialiser(long long int number)
{
vector<int> numberArray(20);
for (vector<int>::iterator it = numberArray.begin(); it != numberArray.end(); it++)
{
numberArray[*it] = number % 10;
number /= 10;
}
return numberArray;
}
when this function is called(eg. initialiser(123456), it returns a zero array instead of an array with this digits.
vector<int> numberArray(20);
Initially, the array has 20 zeroes.
*it
This indirects through the iterator. Because all values are 0, this indirection will result in that zero value.
numberArray[*it] = number % 10;
Here, you modify the the first element of the vector i.e. numberArray[0], because *it is zero (see previous paragraph).
In later iterations, you still modify the first element because the value of the pointed element is always zero. In the last iteration the value that you set is zero, because the input integer didn't have 20 digits.

Finding the kth smallest element in an array using recursion?

#include <iostream>
using namespace std;
void moveToKthSmallest(int a[], int size, int k);
int main() {
int theArray[17] = {42, 5, 412, 56, 14, 98, 488, 4882, 24, 4, 9, 67, 9424, 2, 1, 3, 5};
int num;
cout << "Move to the kth smallest number in the array (size of 17): " << endl;
cin >> num;
moveToKthSmallest(theArray, 17, num);
return 0;
}
void moveToKthSmallest(int a[], int size, int k) {
int pivot = size / 2;
int pivotValue = a[pivot];
int index1 = 0, index2 = 0;
int s1[size], s2[size]; //not sure about this
for (int i = 0; i < size; i++) {
if (a[i] < pivotValue) {
s1[index1] = a[i];
index1++;
}
else {
s2[index2] = a[i];
index2++;
}
}
int s1Size = index1; //problem?
int s2Size = index2; //problem?
if (s1Size == k - 1) {
cout << pivotValue;
}
else if (s1Size > (k - 1)) {
moveToKthSmallest(s1, s1Size, k);
}
else if (s1Size < (k - 1)) {
moveToKthSmallest(s2, s2Size, k - (s1Size - 1));
}
}
I ask the user to input a number (greater than or equal to 0 or less than or equal to 17) and the program should output the kth smallest number in the already generated array.
The above is my attempt but it crashes whenever I run it. I think it has something to do with the declaration of the arrays s1 and s2 in the function and possibly the size values generated from index1 and index2. I've tried using vectors and dynamic arrays but I keep getting error messages in my compiler such as "error: cannot convert 'std::vector**' to 'int*' for argument '1' to 'void moveToKthSmallest" ... to be quite honest, I'm not quite sure what that means.
Am I missing something obvious here?
The first point of order is that this is tagged C++ and not C. Therefore, instead of an int a[] and an int size, you should be using a straightforward std::vector<int>.
Now, with that out of the way, in your example, you're iterating over the entire array each time you recurse.
The second point of order, I don't understand why recursion is even needed here. The answer can be found with a single iteration over your array.
The most simplest way of doing that is to use a second array, let's say std::vector<int> smallest, then iterate over your std::vector<int> a just once.
When iterating over each element:
if smallest.size() is already k, and the current value is larger than the last value in smallest, then proceed to the next value in a, otherwise remove the last value in smallest.
at this point, smallest.size() is always less than k, therefore add the current value in a to the smallest in a manner that keeps the smallest array in sorted order.
At the end of the iteration, the last value in the smallest vector is the kth smallest value in your original vector.
If you would like to know the position of the kth smallest value, this is just a minor modification to the above algorithm, by tracking the position in the smallest vector, rather than the value.
This seems to be a much simpler, straightforward solution, then a complicated recursion-based approach with a confusing pivoting operation. Also, your pivoting example requires the original array to be modified, while my approach does not, and can be used with a const std::vector<int>, even.
P.S. It's not really necessary to keep smallest in sorted order. With a slight modification to the algorithm, smallest can remain unsorted. The homework assignment here is to adjust this algorithm to not require smallest to remain in sorted order.

How do I drop the lowest value?

I'm pretty new to C++, and I need help figuring out the code for dropping the lowest value of a randomly generated set of numbers. Here is my code so far:
//Create array and populate the array with scores between 55 and 10
// Drop lowest Score
#include <iostream>
#include <cstdlib>//for generating a random number
#include <ctime>
#include <iomanip>
#include <algorithm>
#include <vector>
using namespace std;
//function prototype
int *random (int);
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
//random function, generates random numbers between 55 and 100 ??
int *random(int num)
{ int *arr; //array to hold numbers
//return null if zero or negative
if (num <= 0)
return NULL;
//allocate array
arr = new int[num];
//seed random number generator
srand(time (0));
//populate array
for (int count = 0; count < num; count++)
arr[count] = (rand()%(45) +55);
//return pointer
//
return arr;
}
For this piece of code, how would I sort or find the lowest score to drop it after the function returns the random numbers?
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
Your suggestions are appreciated!
In general, to find the lowest value in an array, you can follow this psuedo-algorithm:
min = array[0] // first element in array
for (all_values_in_array)
{
if (current_element < min)
min = current_element
}
However, you can't "drop" a value out of a static array. You could look into using a dynamic container (eg. vector), or swapping the lowest value with the last value, and pretending the size of the array is 1 less. Another low level option would be to create your own dynamic array on the heap, however, this is probably more complicated than you are looking for.
Using an vector would be much easier. To drop the lowest element, you just have to sort in reverse order, then remove the last element. Personally, I would recommend using a vector.
The obvious approach to find the smallest element is to use std::min_element(). You probably want to use std::vector<T> to hold your elements but this isn't absolutely necessary. You can remove the smallest value from an array like this:
if (count) {
int* it = std::min_element(array, array + count);
std::copy(it + 1, array + count--, it);
}
Assuming you, reasonable used std::vector<int> instead, the code would look something like this:
if (!array.empty()) {
array.erase(std::min_element(array.begin(), array.end()));
}
First find the index of the lowest number:
int lowest_index=0, i;
for (i=0; i<20; i++)
if (arr[i]<arr[lowest_index])
lowest_index=i;
Now that we know the index, move the numbers coming after that index to overwrite the index we found. The number of numbers to move will be 19 minus the found index. Ie, if index 2 (the third number, since the first is at index 0) is lowest, then 17 numbers comes after that index, so that's how many we need to move.
memcpy(&arr[lowest_index],&arr[lowest_index+1],sizeof(int)*(19-lowest_index))
Good luck!
Sort the array ascending.
The lowest value will be at the beginning of the array.
Or sort the array descending and remove the last element.
Further to what others have said, you may also choose to use something like, perhaps a std::list. It's got sorting built-in, also offering the ability to define your own compare function for two elements. (Though for ints, this is not necessary)
First, I typically typedef the vector or list with the type of the elements it will contain. Next, for lists I typedef an iterator - though both of these are merely a convenience, neither is necessary.
Once you've got a list that will holds ints, just add them to it. Habit and no need to do otherwise means I'll use .push_back to add each new element. Once done, I'll sort the list, grab the element with the lowest value (also the lowest 'index' - the first item), then finally, I'll remove that item.
Some code to muse over:
#include <cstdio>
#include <cstdlib>
#include <list>
using namespace std;
typedef list<int> listInt;
typedef listInt::iterator listIntIter;
bool sortAsc(int first, int second)
{
return first < second;
}
bool sortDesc(int first, int second)
{
return first > second;
}
int main (void)
{
listInt mList;
listIntIter mIter;
int i, curVal, lowestScore;
for (i=1; i<=20; i++)
{
curVal = rand()%45 + 55;
mList.push_back(curVal);
printf("%2d. %d\n", i, curVal);
}
printf("\n");
mList.sort();
// mList.sort(sortAsc); // in this example, this has the same effect as the above line.
// mList.sort(sortDesc);
i = 0;
for (mIter=mList.begin(); mIter!=mList.end(); mIter++)
printf("%2d. %d\n", ++i, *mIter);
printf("\n");
lowestScore = mList.front();
mList.pop_front();
printf("Lowest score: %d\n", lowestScore);
return 0;
}
Oh, and the choice to use printf rather than cout was deliberate too. For a couple of reasons.
Personal preference - I find it easier to type printf("%d\n", someVar);
than cout << someVar << endl;
Size - built with gcc under windows, the release-mode exe of this example is 21kb.
Using cout, it leaps to 459kb - for the same functionality! A 20x size increase for no gain? No thanks!!
Here's an std::list reference: http://www.cplusplus.com/reference/stl/list/
In my opinion the most optimal solution to your problem would be to use a linked list to store the numbers, this way you can use an algorithm with complexity O(N) = N to find the smallest element in the list, it is a similar finding method given by user1599559 or Mikael Lindqvist, you only need stored together with the minimum value the pointer to the Item(ItemX) in the linked list that store it, then to eliminate Item X just tell Item X - 1 points to Item X + 1 and free memory allocated by Item X