Finding Duplicates in a array - Syntax Explanation - c++

I don't have any idea about this syntax int *count = new int[sizeof(int)* (size - 2)]
What kind of array that will create.
I thought they are trying to create map like structure. But how does it work?
#include <bits/stdc++.h>
using namespace std;
void printRepeating(int arr[], int size)
{
int *count = new int[sizeof(int)*(size - 2)];
int i;
cout << " Repeating elements are ";
for(i = 0; i < size; i++)
{
if(count[arr[i]] == 1)
cout << arr[i] << " ";
else
count[arr[i]]++;
}
}
// Driver code
int main()
{
int arr[] = {4, 2, 4, 5, 2, 3, 1};
int arr_size = sizeof(arr)/sizeof(arr[0]);
printRepeating(arr, arr_size);
return 0;
}
// This is code is contributed by rathbhupendra

Finding duplications in an array is of course a solved problem. IMHO a very simple solution is:
sort the array use std::sort()
use a loop to check if an element is equal to it's successor, ie. for(int i = 1; i < num_elements; i++){ if(arr[i-1]==arr[i]){...duplicate!...}}
This requires O(n) memory and O(n*log(n)) time, so it's quite ok. You can also use a hashmap, but that's pretty much the same.
Anyways, to your question(s):
int *count = new int[sizeof(int)* (size - 2)];
This is incorrect. I assume it used to be this C code:
int num_elements = size-2; // we want size-2 elements (not sure why)
int total_bytes = sizeof(int) * num_elements;
int *count = calloc(total_bytes); // reserve space, and set to 0
Which one could translate to this C++ code:
int num_elements = size-2;
int * count = new int[num_elements]{0}; // alloc and set to zero
So the person who did the port misunderstands fundamentals about C++.
Let's dig further.
For the sake of it, the problem formulation appears to be:
You are given an array of n+2 elements. All elements of the array
are in range 1 to n. And all elements occur once except two
numbers which occur twice. Find the two repeating numbers
I have made tiny changes to make the solution less crazy, and I've added annotations.
// #include <bits/stdc++.h> is a bad choice.
// This includes _EVERYTHING_ in C++,
// but it only works in GCC afaik. For this particular
// case we just need cout, so:
#include <iostream>
// using the std namespace like this spills function calls like crazy in the global namespace.
// it is both, conventient and "not too bad" (imho) in cpp files,
// but never ever do this in .h files where it affects multiple cpp files.
using namespace std;
void printRepeating(int arr[], int size)
{
// create a new array of size-2 and set to zero
int *count = new int[(size - 2)]{0};
int i;
cout << " Repeating elements are ";
// loop all elements
for(i = 0; i < size; i++)
{
int value = arr[i];
// increase the count for `value`
// note that if value<=0 or value>size-2,
// then the program will crash!
// the problem description is contrived, but it does
// state that all values need to be >0 and <=size-2,
// so this next array access is fine!
count[value-1]++;
// we still have to subtract 1, because C arrays start
// at index 0, but our problem description says we start at 1.
// we could also create an array of size-1 and
// "ignore" the first position in count[0] (it would never get used!)
// if the element appears the second time...
if(count[value-1] == 2){
// then print it
cout << value << " ";
// btw: if you check with count[value-1]==2, then only
// the first duplicate is printed.
// you could compare with count[value-1]>=2 then all
// repeating elements are printed repeatetly.
}
}
// free up the memory. we allocated with `new[]`
// so we also have to use `delete[]`
delete [] count;
}
// Driver code
int main()
{
int arr[] = {4, 2, 4, 5, 2, 3, 1};
// next line is a standard trick.
// a single int consumes 4bytes (typically),
// the array will have size 7*4=28 bytes, so sizeof(arr)=28
// the first element is an int, so sizeof(arr[0]) = 4
// so sizeof(arr)/sizeof(arr[0]) = 7
// c and c++ don't have arr.length like java,etc., that's
// why under certain circumstances this "trick" is used.
int arr_size = sizeof(arr)/sizeof(arr[0]);
// call the function
printRepeating(arr, arr_size);
return 0;
}
// This is code is contributed by rathbhupendra.
// Maybe fixed and annotated by hansi:)
I hope this helps you and answers some questions. Good luck with your C++ adventures!

Related

Why is there an error in my integer array after declaring an integer in my main function?

I am trying out some codes that is based on finding all possible combinations that add up to a integer's value that is declared in the main function. However, the problem is when I call the function "findCombinations(n);", it gives an error at "int arr[n];". That is the only line which has an error which is stopping me from running the program. If you know of a solution, do let me know.
#include <iostream>
using namespace std;
void findCombinationsUtil(int arr[], int index,
int num, int reducedNum)
{
// Base condition
if (reducedNum < 0)
return;
// If combination is found, print it
if (reducedNum == 0)
{
for (int i = 0; i < index; i++)
cout << arr[i] << " ";
cout << endl;
return;
}
// Find the previous number stored in arr[]
// It helps in maintaining increasing order
int prev = (index == 0) ? 1 : arr[index - 1];
// note loop starts from previous number
// i.e. at array location index - 1
for (int k = prev; k <= num; k++)
{
// next element of array is k
arr[index] = k;
// call recursively with reduced number
findCombinationsUtil(arr, index + 1, num,
reducedNum - k);
}
}
void findCombinations(int n)
{
// array to store the combinations
// It can contain max n elements
int arr[n];
//find all combinations
findCombinationsUtil(arr, 0, n, n);
}
int main()
{
int n = 10;
findCombinations(n);
return 0;
}
C-style array dimensions must be known at compile-time in Standard C++.
You can make n be a compile-time function parameter like this:
template<int n>
void findCombinations()
{
// array to store the combinations
// It can contain max n elements
int arr[n];
//find all combinations
findCombinationsUtil(arr, 0, n, n);
}
int main()
{
const int n = 10;
findCombinations<n>();
return 0;
}
From http://www.cplusplus.com/doc/tutorial/arrays/:
NOTE: The elements field within square brackets [], representing the number of elements in the array, must be a constant expression, since arrays are blocks of static memory whose size must be determined at compile time, before the program runs.
While some compilers will allow it, you should avoid dynamic size arrays.
Here are a few options:
If the size of the array will always be 10, initiate it to hard-coded const 10.
Use std::shared_ptr to an array pointer:
std::shared_ptr pArray;
pArray=std::make_shared(n)
Use std::vector to dynamically allocate the size. (IMHO this is the preferred option).
use c-style pointers (IMHO should only be used as last resort)
Template class (wasteful, as it created and compiles many instances of the same function)
Type of variable arr must be known at compile time. If you need storage of variable size, you have to allocate it.
Possible alternative (one of many)
#include <vector>
void findCombinations(int n)
{
// array to store the combinations
// It can contain max n elements
std::vector<int> arr(n); // allocate n elements
//find all combinations
findCombinationsUtil( &*arr.begin(), 0, n, n);
}
if compiler at least partially complies to C++11 e.g. it's late gcc 4.6 or higher or VS2010 and higher, then there is method data() that returns pointer to internal storage. But better to rewrite, templatize or overload findCombinationsUtil to use a container or iterator

How to remove integers in array less than X in C++?

I found the same question for PHP and I tried to do the same in C++.
I tried following:
// returns new array with numbers lower then "number", len is set to
// new length.
int * filter(int array[], int &len, int number) {
int cnt = 0;
for (int i = 0; i < len; i++) {
if (array[i] < number) {
cnt++;
}
}
int *ret = new int[cnt];
cnt = 0;
for (int i = 0; i < len; i++) {
if (array[i] < number) {
ret[cnt] = array[i];
cnt++;
}
}
len = cnt;
return ret;
}
This function will create a new array with the integers that are lower than the integer number. I tried to bypass the problem that I don't know how long the new array should be.
Is there any better way to solve this problem?
Yes, use std::vector type. It will automatically handles allocations for you each time you push value to it (using push_back method).
Example
#include <iostream>
#include <vector>
int main() {
std::vector<int> a;
a.push_back(1);
a.push_back(2);
for (int value : a) {
std::cout << value << '\n';
}
}
It's also a good idea to avoid new syntax, as it doesn't automatically deallocate, unlike std::vector.
Also, while this is unrelated to question, C++ provides a function that does what you want already called std::copy_if.
std::remove is the algorithm you're looking for.
#include <iterator>
#include <algorithm>
int main()
{
int array[4] = {1, 42, 314, 42};
// If you only know `array` as a pointer, and `len`, then
// `std::begin(array)` becomes `array`, and
// `std::end(array)` becomes `array + len`.
auto end = std::remove(std::begin(array), std::end(array), 42);
// Now `end` points to the "new end" of the array.
// And `std::distance(std::begin(array), end)` is the "new length".
}
It moves all matched elements (42 in the example) to the end of the array. When inspecting array after std::remove runs, you get {1, 314, 42, 42}, and end points past the last nonmatching element (the first 42 in this case).
It's also possible to copy the nonmatching elements to another array using std::remove_copy, or std::copy_if, but in order to do this, you'll have to allocate another array of elements. At this point, you're better off using a dynamic growing array such as std::vector. In that case, use std::vector::erase like here in the answers with std::remove.

how do i create dynamic array in cpp

I have this function:
void reverse(int* nums, unsigned int size)
This function is supposed to reverse the values in the array it is getting.
Now for reversing I thought to create another array with the size of the array passed in. Assigning this new one from the end of the original array to the start.
But I am a kind of new in C++, So I don't know how to create dynamic array in the size of the parameter of the function.
It's actually not necessary to allocate a new array here. See if you can find a way to solve this problem just by rearranging the existing elements in-place.
Given that this seems like it's an exercise with pointers, you can allocate space by using the new[] operator:
int* auxiliaryArray = new int[size];
You'd then free it by writing
delete[] auxiliaryArray;
However, this isn't the preferred way of doing this in C++. The better route is to use std::vector, which does all its own memory management. That would look like this:
std::vector<int> auxSpace(size);
You can then access elements using the square brackets as you could in a real array. To do this, you'll need to #include <vector> at the top of your program.
In C++, the recommended way to create an array of variable size would be to use an std::vector
#include <vector>
void reverse(int* nums, unsigned int size)
{
std::vector<int> V(size);
...
}
But that approach isn't the best here for performance because it requires additional memory to be allocated of the size of the array, which could be big. It would be better to start from the outside of the array and swap members one by one that are at mirroring positions (so if the size is 5, swap 0 and 4, then swap 1 and 3 and leave 2 alone). This only requires temporary storage of a single int.
You can do it without the need to create another array:
void reverse(int* array, const int size){
for(int i = 0; i < size / 2; i++){
int tmp = array[i];
array[i] = array[size - 1 - i];
array[size - 1 - i] = tmp;
}
}
int main(){
int array[] = {1, 3, 5, 7, 9, 11};
const int size = sizeof(array) / sizeof(array[0]);
reverse(array, size);
for(int i(0); i < size; i++)
std::cout << array[i] << ", ";
}
As you can see above in the loop you only need to swap the first element (element 0) with the n-1 element and the second one with n-1-1 and son on...
Remember arrays are indexed from 0 through n-1.
If you want to allocate new array which is not practical:
int* reverse2(int* array, const int size){
int* tmp = new int[size];
for(int i(size - 1), j(0); j < size; j++, i--)
tmp[j] = array[i];
return tmp;
}
int main(){
int array[] = {1, 3, 5, 7, 9, 11};
for(int i(0); i < size; i++)
std::cout << array[i] << ", ";
std::cout << std::endl;
int* newArray = reverse2(array, size);
for(int i(0) ; i < size; i++)
std::cout << newArray[i] << ", ";
std::cout << std::endl;
delete[] newArray;
return 0;
}
If you want to use a new array you can, but I think is to kill flies with a cannon.
Looks like you are using plain C code and not C++. I say that because of the signature of the function. The signature of the function in a common C++ code could be something like this other:
void reverse(std::vector& items);
You can reverse the current array without a new array, using the current one. You are passing the pointer to the first item of the array, and the content is not constant so that you can modify it. A better signature for the function could be:
void reverse(int* const nums, const unsigned int size);
Looks like a pointer problem. Think about the boundaries to iterate the positions of the array. Would you need to iterate the whole array? Maybe only half array? ;)
As bonus track, what about to exchange the values without an auxiliar variable? (this is true into this case that we are using the fundamental type int... remember the binary arithmetic).
array[pos_head] ^= array[pos_tail];
array[pos_tail] ^= array[pos_head];
array[pos_head] ^= array[pos_tail];

How to delete an Array with negative integers

I was trying to solve the following problem,
Given an array of integers, every element appears three times except
for one. Find that single one.
When the input are all positive, I will not get any errors, but when the input contains negative integers, the line delete index; will give error, does anybody know why?
i.e.
A[] = {1,2,3,4,1,2,3,4,1,3,4} works fine, but A[] = {-2,-2,1,1,-3,1,-3,-3,-4,-2} does not.
The code is as follow,
#include <iostream>
#include <map>
class Solution {
public:
int singleNumber(int A[], int n) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
int *index;
std::map<int, int> m;
index = new signed int[(n+1)/3];
int flag = 0;
int result;
for(int i=0; i<n; i++) {
if(m.find(A[i]) == m.end()) {
m[A[i]] = 1;
index[flag] = A[i];
flag++;
} else {
m[A[i]] = m[A[i]] + 1;
}
}
for(int i=0; i<(n+1)/3; i++) {
if(m[index[i]] != 3) {
result = index[i];
}
}
delete index;
return result;
}
};
int main()
{
Solution s;
int A[] = {1,2,3,4,1,2,3,4,1,3,4};
int result = s.singleNumber(A, 11);
std::cout <<result;
return 0;
}
The first array contains 11 elements, which causes the line index = new signed int[(n+1)/3]; to allocate an array of (11+1)/3 = 4 elements. The second array contains 10 elements, which causes that line to allocate an array of (10+1)/3 = 3 elements.
3 elements is insufficient to record the unique values in A (-4, -3, -2, and 1), so you overflow the array.
You should allocate at least (n+2)/3 elements. It would also be prudent to test the value of flag to ensure it never exceeds the array bounds. It will not if the input array obeys the constraint that every element but one appears three times (presuming this means it will appear one or two times, not four or more), but can you rely on that constraint being obeyed?
Additionally, the loop for(int i=0; i<(n+2)/3; i++) is insufficient to iterate through all the elements that were added to the map. You should be sure you iterate through all the members of m.
Incidentally, singleNumber can be implemented in a much more fun way without any dynamic allocation or library calls:
int singleNumber(int A[], int n) {
int b = 0, c = 0;
while (n--)
{
b ^= A[n] & c;
c ^= A[n] & ~b;
}
return c;
}
However, this is completely not what your instructor is expecting.

Int Array Length C++

I have to use a dynamic length int array in my program, and want to be able to get the number of objects in it at various points in my code. I am not that familiar with C++, but here is what I have. Why is it not giving me the right length? Thanks.
<#include <iostream>
Using Namespace std;
int length(int*);
void main()
{
int temp[0];
temp[0] = 7;
temp [1] = 10;
temp[2] = '\0';
cout << length(temp) << endl;
}
int length(int* temp)
{
int i = 0;
int count = 0;
while (*temp + i != '\0')
{
count++;
i++;
}
return count;
}
currently it just goes into an endless loop ;_;
In C++ arrays are not dynamic. Your temp array has zero length, and attempting to write to members beyond its length is undefined behaviour. It's most likely not working as it will be writing over some part of the stack.
Either create a fixed size array with enough space to put everything you want to in it, or use a std::vector<int> which is a dynamic data structure.
#include <iostream>
#include <vector>
using namespace std;
int length(int*);
int main () // error: ‘::main’ must return ‘int’
{
int temp[3];
temp[0] = 7;
temp[1] = 10;
// don't use char constants for int values without reason
temp[2] = 0;
cout << length(temp) << endl;
vector<int> vec_temp;
vec_temp.push_back(7);
vec_temp.push_back(10);
cout << vec_temp.size() << endl;
}
int length(int* temp)
{
int i = 0;
int count = 0;
while (*(temp + i) != 0) // *temp + i == (*temp) + i
{
count++;
i++; // don't really need both i and count
}
return count;
}
For the vector, there's no need to specify the size at the start, and you can put a zero in, and finding the length is a simple operation rather than requiring a loop.
Another bug inside your loop was that you were looking at the first member of the array and adding i to that value, rather than incrementing the pointer by i. You don't really need both i and count, so could write that a couple of other ways, either incrementing temp directly:
int length(int* temp)
{
int count = 0;
while (*temp != 0)
{
++count;
++temp;
}
return count;
}
or using count to index temp:
int length(int* temp)
{
int count = 0;
while (temp[count] != 0)
++count;
return count;
}
This approach is a bad idea for a couple of reasons, but first here's some problems:
int temp[0];
This is an array of 0 items, which I don't even think is permitted for stack elements. When declaring an array like this you must specify the maximum number of values you will ever use: E.g. int temp[10];
This is super important! - if you do specify a number less (e.g. [10] and you use [11]) then you will cause a memory overwrite which at best crashes and at worst causes strange bugs that are a nightmare to track down.
The next problem is this line:
while (*temp + i != '\0')
That this line does is take the value stores in the address specified by 'temp' and add i. What you want is to get the value at nth element of the address specified by temp, like so:
while (*(temp + i) != '\0')
So that's what's wrong, but you should take five minutes to think about a better way to do this.
The reasons I mentioned it's a bad idea are:
You need to iterate over the entire array anytime you require its length
You can never store the terminating element (in this case 0) in the array
Instead I would suggest you maintain a separate value that stores the number of elements in the array. A very common way of doing this is to create a class that wraps this concept (a block of elements and the current size).
The C++ standard library comes with a template class named "vector" which can be used for this purpose. It's not quite the same as an array (you must add items first before indexing) but it's very similar. It also provides support for copying/resizing which is handy too.
Here's your program written to use std::vector. Instead of the 'length' function I've added something to print out the values:
#include <vector>
#include <iostream>
void print(std::vector<int> const& vec)
{
using namespace std;
for (size_t i = 0; i < vec.size(); i++)
{
cout << vec[i] << " ";
}
cout << endl;
}
int main()
{
std::vector<int> temp;
temp.push_back(7);
temp.push_back(10);
print(temp);
return 0;
}
You could try:
while (*(temp + i) != '\0')
Your current solution is calculating temp[0] + i (equals 7+i), which apparently is not what you want.
Not only C++ arrays are not dynamic as Pete points out, but only strings (char *) terminate with '\0'. (This is not to say that you can't use a similar convention for other types, but it's rather unusual, and for good reasons: in particular, relying on a terminator symbol requires you to loop through an array to find its size!)
In cases like yours it's better to use the standard library.
#include <vector>
#include <iostream>
int main()
{
std::vector<int> v;
v.push_back(7);
v.push_back(10);
std::cout << v.size() << std::endl;
return 0;
}
If you don't want to use std::vector, try this:
#include <iostream>
using namespace std;
int main () {
int vet[] = {1,2,3,4,5,6};
cout << (sizeof (vet) / sizeof *(vet)) << endl;
return 0;
}
The most common way to get the size of a fixed-length array is something like this:
int temp[256];
int len = sizeof (temp) / sizeof (temp[0]);
// len == 256 * 4 / 4 == 256 on many platforms.
This doesn't work for dynamic arrays because they're actually pointers.
int* temp = new int[256];
int len = sizeof (temp) / sizeof (temp[0]);
// len == 4 / 4 == 1 on many platforms.
For a dynamic-length array if you care about the size, you're best off storing it somewhere when you allocate the array.
The problem with your loop, as pointed out by many is that you have an operator precedence problem here:
*temp + i
should be:
*(temp + i)
But the bigger problem, also pointed out above, is that you don't appear to understand pointers versus fixed-length arrays and are writing off the end of your array.
If you want to use array properly, you have to allocate enough memory for storing values. Once you specified its length, you can't change it. To know array size, you should store it in variable e.g.:
int n;
cin>>n;
int array = new int[n];
int array_length=n;
If you want to change array's length, best way is to use std container, for example std::vector.
Here is the answer to your question
int myarr [] = {1, 2, 3, 4, 5};
int length = sizeof(myarr) / sizeof(myarr[0]);
cout << length;
Because you only allocate space for an array of zero elements.
The following lines
temp [1] = 10;
temp[2] = '\0';
do not allocate more memory or resize the array. You are simply writing data outside the array, corrupting some other part of the application state. Don't do that. ;)
If you want a resizable array, you can use std::vector (and use the push_back member function to insert new values)
A vector also has the size() member function which tells you the current size.
If you want to use the primitive array, you have to track the size yourself. (and, when resizing the array is necessary, copy all elements from the old array to the new, larger one)
To get dynamic behavior in arrays, use a std::vector, or fall back on the old school c style using int * with manual memory allocation (new and delete)[*]
[*] C implementations (discussed in the context of character arrays as C dynamic string length) used malloc, realloc, and free, but these should be avoided in c++ code.
Try this out:
int length(int* temp)
{
int count = 0;
while (*temp != 0 && *temp != -858993460)
{
++count;
++temp;
}
return count;
}