int *sub(int *A,int q)
{
int i = id(A,q)+1,j = id(A,q)-1;
int *l , *m ;
m = (int*)malloc(sizeof(int));
*m = q;
l = m ;
for(i ; *(A+i) != '\0' && *(A + i) >= q ; ++i)
{
++l = (int*)malloc(sizeof(int));
*l = *(A+i);
}
++l = (int*)malloc(sizeof(int));
*l = '\0';
for(j ; j>=0 && *(A + j) >= q ; j--)
{
--m = (int*)malloc(sizeof(int));
*m = *(A+i);
}
for(i = 0 ; *(m + i) != '\0' ; i++)
cout<<*(m+i)<<"##\t";
return m;
}
It's a function that is supposed to take a pointer to a 1D array (A) and then return a pointer to another 1D array(m) which is subarray of A and has elements greater than or equal to q(passed as parameter to the function sub)
I guess there is some problem with the way I manipulate int pointers.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<int> arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int q = 5;
std::vector<int> result;
std::copy_if(arr.begin(), arr.end(), std::back_inserter(result), [q](int i){return i >= q; });
std::for_each(result.begin(), result.end(), [](int i){std::cout << i << std::endl; });
getline(std::cin, std::string());
return 0;
}
You have no guarantee that m+i will ever be '\0', at least not for space that has been malloc'ed.
On top of the points mentioned in the comments, like making sure all space is freed appropriately. This just looks like a big memory leak all over the place.
Related
bool isSubset(int arr1[], int m,int arr2[], int n){
set<int> hashset;
for (int i = 0; i < m; i++){
hashset.insert(arr1[i]);
}
for (int i = 0; i < n; i++) {
if (hashset.find(arr2[i]) == hashset.end())
return false;
}
return true;
}
Is this correct method to find whether arr2 is sub array of arr1 or not
because sub array is contiguous part of array but this code is not checking for any order that's why I want to be sure.
Is this correct method to find whether arr2 is sub array of arr1 or not
No, it isn't. Your method doesn't consider the order of elements. It is more of a method to find whether a bunch of numbers (given in arr2) exist in an arr1.
For instance, if int arr1[] = {1, 2, 3} and int arr2[] = {2, 1}, the method you implemented will return true, while it should return false.
Here is how you would do it:
#include <iostream>
bool isSubset(int array[], int m, int subarray[], int n)
{
if (n > m)
return false;
for (int i = 0; i <= m-n; i++) {
int ii = i, j;
for (j = 0; j < n; j++)
if (subarray[j] != array[ii])
break;
else
ii++;
if (j == n)
return true;
}
return false;
}
Then call it like this:
int main()
{
int array[] = {1, 2, 3};
const int m = sizeof(array) / sizeof(*array);
int subarray1[] = {1, 2};
const int n1 = sizeof(subarray1) / sizeof(*subarray1);
int subarray2[] = {2, 1};
const int n2 = sizeof(subarray2) / sizeof(*subarray2);
std::cout << isSubset(array, m, subarray1, n1) << "\n"; // Will print 1
std::cout << isSubset(array, m, subarray2, n1) << "\n"; // Will print 0
}
You understood that the way your code is checking subarray is wrong.
A suggestion-
Use of C language style array in C++ is discouraged. Instead, you should use the appropriate standard container, provided in Containers library. You can use std::array container in place of plain C style array. Below is the sample code to check subarray:
#include <iostream>
#include <array>
#include <algorithm>
int main () {
std::array<int,12> arr1 {9,5,2,5,9,2,4,7,0,4,5,1};
std::array<int,3> arr2 {5,9,2};
bool res = false;
size_t pos = 0;
std::array<int,12>::iterator x;
while ((x = std::find(arr1.begin() + pos, arr1.end(), arr2[0])) != arr1.end()) {
size_t currpos = x - arr1.begin();
if ((arr1.size() - currpos >= arr2.size()) &&
((std::equal(arr1.begin() + currpos, arr1.begin() + currpos + arr2.size(), arr2.begin())))) {
res = true;
break;
}
pos = currpos + 1;
}
if (res) {
std::cout << "arr2 is subarray of arr1" << std::endl;
} else {
std::cout << "arr2 is not subarray of arr1" << std::endl;
}
return 0;
}
I'm trying to write a code where there is a research of even numbers and then it deletes the even numbers and then shifts all the other elements.
i is for offset and are the actual position of the elements in the array.
k is the position of the even number in the array.
int k;
for(i=0; i < N; i++)
{
if(Array[i] % 2 == 0)
{
for(k=i+1; k < N; k++)
{
Array[k-1] = Array[k];
}
N--;
}
}
Array=[2,10,3,5,8,7,3,3,7,10] the even numbers should be removed, but a 10
stays in the Array=[10,3,5,7,3,3,7].
Now is more than 3 hours that I'm trying to figure out what's wrong in my code.
This appears to be some sort of homework or school assignment. So what's the actual problem with the posted code?
It is that when you remove an even number at index i, you put the number that used to be at index i + 1 down into index i. Then you continue the outer loop iteration, which will check index i + 1, which is the number that was at the original i + 2 position in the array. So the number that started out at Array[i + 1], and is now in Array[i], is never checked.
A simple way to fix this is to decrement i when you decrement N.
Though already answered, I fail to see the reason people are driving this through a double for-loop, repetitively moving data over and over, with each reduction.
I completely concur with all the advice about using containers. Further, the algorithms solution doesn't require a container (you can use it on a native array), but containers still make it easier and cleaner. That said...
I described this algorithm in general-comment above. you don't need nested loops fr this. You need a read pointer and a write pointer. that's it.
#include <iostream>
size_t remove_even(int *arr, size_t n)
{
int *rptr = arr, *wptr = arr;
while (n-- > 0)
{
if (*rptr % 2 != 0)
*wptr++ = *rptr;
++rptr;
}
return (wptr - arr);
}
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
size_t n = remove_even(arr, sizeof arr / sizeof *arr);
for (size_t i=0; i<n; ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
Output
3 5 7 3 3 7
If you think it doesn't make a difference, I invite you to fill an array with a million random integers, then try both solutions (the nested-for-loop approach vs. what you see above).
Using std::remove_if on a native array.
Provided only for clarity, the code above basically does what the standard algorithm std::remove_if does. All we need do is provide iterators (the array offsets and size will work nicely), and know how to interpret the results.
#include <iostream>
#include <algorithm>
int main()
{
int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
auto it = std::remove_if(std::begin(arr), std::end(arr),
[](int x){ return x%2 == 0; });
for (size_t i=0; i<(it - arr); ++i)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
Same results.
The idiomatic solution in C++ would be to use a STL algorithm.
This example use a C-style array.
int Array[100] = {2,10,3,5,8,7,3,3,7,10};
int N = 10;
// our remove_if predicate
auto removeEvenExceptFirst10 = [first10 = true](int const& num) mutable {
if (num == 10 && first10) {
first10 = false;
return false;
}
return num % 2 == 0;
};
auto newN = std::remove_if(
std::begin(Array), std::begin(Array) + N,
removeEvenExceptFirst10
);
N = std::distance(std::begin(Array), newN);
Live demo
You could use a std::vector and the standard function std::erase_if + the vectors erase function to do this:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> Array = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
auto it = std::remove_if(
Array.begin(),
Array.end(),
[](int x) { return (x & 1) == 0 && x != 10; }
);
Array.erase(it, Array.end());
for(int x : Array) {
std::cout << x << "\n";
}
}
Output:
10
3
5
7
3
3
7
10
Edit: Doing it the hard way:
#include <iostream>
int main() {
int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
size_t N = sizeof(Array) / sizeof(int);
for(size_t i = 0; i < N;) {
if((Array[i] & 1) == 0 && Array[i] != 10) {
for(size_t k = i + 1; k < N; ++k) {
Array[k - 1] = Array[k];
}
--N;
} else
++i; // only step i if you didn't shift the other values down
}
for(size_t i = 0; i < N; ++i) {
std::cout << Array[i] << "\n";
}
}
Or simpler:
#include <iostream>
int main() {
int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
size_t N = sizeof(Array) / sizeof(int);
size_t k = 0;
for(size_t i = 0; i < N; ++i) {
if((Array[i] & 1) || Array[i] == 10) {
// step k after having saved this value
Array[k++] = Array[i];
}
}
N = k;
for(size_t i = 0; i < N; ++i) {
std::cout << Array[i] << "\n";
}
}
I am trying to delete any duplicates but not having much success..
void deleatingRepeatingElement (int myArrayLength, int myArray[])
{
for (int i = 1 ; i < myArrayLength; i++){
// start at second index because you don't need to compare the first element to anything, it can't have duplicate that comes first
for (int j = 0; j < i ; j++){
if (myArray[i] == myArray[j]){
myArray[j] = myArray[j + 1];
myArrayLength--;
}
}
}
}
I think there were two main mistakes:
You didn't shift all of the following items when deleting.
You didn't "reset" after deleting.
Here is annotated code that seems to work:
#include <iostream>
/* Remove element at given index from array
* Returns the new array length
* (Note that "int array[]" means exactly the same as "int *array",
* so some people would consider "int *array" better style)
*/
int arrayRemoveAt(int index, int array[], int arrayLength)
{
// Check whether index is in range
if (index < 0 || index >= arrayLength)
return arrayLength;
for (int i = index + 1; i < arrayLength; i++)
{
array[i - 1] = array[i];
}
return arrayLength - 1;
}
/*
* Returns the new length of the array
*/
int deleatingRepeatingElement(int myArrayLength, int myArray[])
{
for (int i = 1; i < myArrayLength; i++)
{
// start at second index because you don't need to compare the first element to anything, it can't have duplicate that comes first
for (int j = 0; j < i; j++)
{
if (myArray[i] == myArray[j])
{
myArrayLength = arrayRemoveAt(i, myArray, myArrayLength);
// After deleting an entry, we must "reset", because now the index i
// might point to another number, which may be a duplicate
// of a number even before the current j.
// The i-- is so that after i++, we will end up with the same i
i--;
break;
}
}
}
// Important: The caller needs this for looping over the array
return myArrayLength;
}
int main(int argc, char **argv)
{
int array[] = {5, 6, 2, 1, 2, 6, 6};
int newSize = deleatingRepeatingElement(7, array);
for (int i = 0; i < newSize; i++)
{
std::cout << array[i] << std::endl;
}
return 0;
}
If you use a static array (such as in my example, as opposed to a dynamic one), you may consider using std::array or a template construction as shown in https://stackoverflow.com/a/31346972/5420386.
Here is the solution to your problem:
#include <iostream>
#include <set>
#define ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0])))
using namespace std;
int *deleteRepeatedElements(int myArray[], int arrayLength) {
set<int> setArray (myArray, myArray+arrayLength);
int setLength = setArray.size();
static int myPointer[4];
int i = 0;
for (set<int>::iterator it = setArray.begin(); it != setArray.end(); ++it) {
myPointer[i] = *it;
i++;
}
return myPointer;
}
int main() {
int myArray[6] = {5, 3, 5, 6, 2, 4};
int arrayLength = ARRAY_SIZE(myArray);
int* myPointer = deleteRepeatedElements(myArray, arrayLength);
int pointerLength = sizeof(myPointer)/sizeof(*myPointer);
for (int* i = &myPointer[0]; *myPointer != 0; i = ++myPointer) {
cout << *i << " ";
}
cout << '\n';
return 0;
}
I'm trying to write a function that prints the K largest integers from an array of unsorted values. What am I doing wrong?
#include <iostream>
void printKLargest(int array[], int k, int size);
int main() {
int array[5] = {1, 100, 2, 500, 6};
int k = 2;
int size = sizeof(array)/sizeof(array[0]);
findKLargest(array, k, size);
}
void printKLargest(int array[], int k, int size) {
int *largest = new int[k];
for (int i = 0; i < size; i++) {
if (array[i] > largest[0]) {
largest[0] = array[i];
for (int j = 1; j < k && largest[j-1] > largest[j]; j++) {
int t = largest[j]; largest[j] = largest[j-1]; largest[j-1] = t;
}
}
}
for (int i = 0; i < k; i++) {
std::cout << largest[i] << "\n";
}
}
The code above only prints the first integer from largest correctly. In C I was able to get it working correctly using malloc, but using new in C++ is throwing me off a bit. Thank you.
edit - if I change the line int *largest = new int[k] to int *largest = (int *)malloc(sizeof(k)); I get the desired value. Can somebody explain why this is the case?
At least the allocated elements pointed to by largest were not initialized
int *largest = new int[k];
Thus the program has undefined behaviour.
Also after the assignment
if (array[i] > largest[0]) {
largest[0] = array[i];
you lost the value of largest[0] that could be copied in largest[1].
The assignment can be done simply if to use standard algorithm std::partial_sort_copy declared in header <algorithm>
For example
#include <vector>
#include <algorithm>
#include <functional>
//...
void printKLargest( const int array[], size_t n, size_t k )
{
if ( n < k ) k = n;
std::vector<int> largest( k );
std::partial_sort_copy( array, array + n,
largest.begin(), largest.end(),
std::greater<int>() );
for ( int x : largest ) std::cout << x << ' ';
std::cout << std::endl;
}
Here is a demonstrative program
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
void printKLargest( const int array[], size_t n, size_t k )
{
if ( n < k ) k = n;
std::vector<int> largest( k );
std::partial_sort_copy( array, array + n,
largest.begin(), largest.end(),
std::greater<int>() );
for ( int x : largest ) std::cout << x << ' ';
std::cout << std::endl;
}
int main()
{
int a[] = { 5, 3, 7, 6, 3, 9, 0 };
printKLargest( a, sizeof( a ) / sizeof( *a ), 2 );
}
The program output is
9 7
Instead of the vector you may use a dynamically allocated array but you should not forget to delete it.
I have an array let's say with 5 items, if element[i] is less than 3 need to move element[i+1] in place of element[i].
int array[5] = {4, 2, 3, 5, 1};
int number = 3;
for (int i = 0; i < number; i++)
{
if (array[i] > number)
{
for (int j = 0; j < i - 1; j++)
{
array[j] = array[j + 1];
}
number = number - 1;
}
}
expected result is array = {2, 3, 1, anyNumber, anyNumber};
A O(n) working code for the above problem.. But as others pointed out in the comments.. You end up with an array that is using less space then allocated to it..
#include<stdio.h>
int main()
{
int arr[] = {4, 2, 3, 5, 1};
int* temp1 = arr;
int* temp2 = arr;
int i, n1 = 5, n2 = 5;
for(i = 0; i < n1; i++)
{
if(*temp2 >= 3)
{
*temp1 = *temp2;
temp1++;
temp2++;
}
else
{
n2--; //the number of elements left in the array is denoted by n2
temp2++;
}
}
}
Nested loops give you O(n2) complexity, and non-obvious code.
Better use std::remove_if:
int array[5] = {4, 2, 3, 5, 1};
int number = 3;
remove_if( begin( array ), end( array ), [=]( int x ) { return x>number; } );
Disclaimer: code untouched by compiler's hands.
Try this code. You should not decrease number at each step. Also, the second loop should start at i and stop at the end of array:
int array[5] = {4, 2, 3, 5, 1};
int number = 3;
for (int i = 0; i < number; i++)
{
if (array[i] > number)
{
for (int j = i; j < 5; j++)
{
array[j] = array[j + 1];
}
}
}
Here's a more compact and idiomatic (that's how I view it anyway) way to remove items from an array:
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
int array[] = {4, 2, 3, 5, 1};
int* begin = array;
int* end = begin + sizeof(array)/sizeof(array[0]);
int number = 3;
end = std::remove_if(begin, end, [&number](int v) {return v > number;});
std::copy(begin, end, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
Just for comparison, here's a version using std::vector:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
std::vector<int> array = {4, 2, 3, 5, 1};
int number = 3;
auto end = std::remove_if(array.begin(), array.end(), [&number](int v) {return v > number;});
std::copy(array.begin(), end, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
As an alternative, if you want to keep your items, but denote what will be at some later time, "removed", the algorithm that can be used is stable_partition:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <functional>
int main()
{
int vValues[] = {4,2,3,5,1};
// partition the values on left and right. The left side will have values
// <= 3, and on right >3. The return value is the partition point.
int *p = std::stable_partition(vValues, vValues + 5,
std::bind2nd(std::less_equal<int>(), 3));
// display information
std::cout << "Partition is located at vValues[" << std::distance(vValues, p) << "]\n";
std::copy(vValues, vValues + 5, std::ostream_iterator<int>(std::cout, " "));
}
Output:
Partition is located at vValues[3]
2 3 1 4 5
You will see that 2,3,1 are on the left of partition p, and 4,5 are on the right of the partition p. So the "removed" items start at where p points to. The std::partition ensures the elements are still in their relative order when done.
I created my own example, hope this helps people as a reference:
// Removing an element from the array. Thus, shifting to the left.
void remove(){
int a[] = {1, 2, 3, 4, 5, 6};
int size = sizeof(a)/sizeof(int); // gives the size
for(int i = 0; i < size; i++){
cout << "Value: " << a[i] << endl;
}
int index = 2; // desired index to be removed
for(int i = 0; i < size; i++){
if(i == index){
for(int j = i; j < size; j++){
a[j] = a[j+1];
}
}
}
size--; // decrease the size of the array
cout << "\nTesting output: " << endl;
for(int i = 0; i < size; i++){
cout << "Value: " << a[i] << endl;
}
}
int main(){
remove();
return 0;
}