Remove all occurrences of a number in an array in C++ [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Supposed we passed in the array {1, 2, 3, 1, 2, 3, 1}, and we wanted to
remove all occurrences of the number 3. The resulting array would be
{1, 2, 1, 2, 1}, and the return value would be 5, because there are now
only 5 items in the array.
This function is wrong. I don't know how to remove the occurrences. I know my index holds the positions of the occurrences. So i need to delete those positions from my array. HELP!!
I can only use arrays, i cannot use vectors or pointers.
void test() {
int data[] = { 2, 1, 3, 2, 5, 2, 7, 8, 4, 9 };
int length = 10;
int x = 2;
int index = 0;
int counter =0;
int tempIndex = 0;
int finalLength = 0;
for (int i = 0; i < length; i++)
{
if (x != data[i]) {
tempIndex = i;
counter++;
cout << "Array: " << tempIndex << endl;
}
}
cout << "Size: " << counter << endl;
}

you can make use of std::remove function available in C++ you can do something like below
int data[] = { 2, 1, 3, 2, 5, 2, 7, 8, 4, 9 };
int length = 10;
int* pbegin = myints;
int* pend = data+sizeof(data)/sizeof(int);
pend = std::remove (pbegin, pend, 3);
for (int* p=pbegin; p!=pend; ++p)
std::cout << *p;

As others have already said until they were blue in the face (probably) you cannot resize arrays. The memory is fixed. What you can do is keep track of matching elements that you want to "remove" and shift the remaining elements to make it appear that they have been removed. The reality will be that the array in memory will still be the size you started with, but you can print the results using the computed size of your "new" array.
The following code should do what you want. The first argument is your data array, the next argument will be the fixed size of said array. The last argument is the number you want to "remove" all occurrences of. The function remove_match will return the size of your data array minus any matches it found. The array will be shifted such that only the non-matching elements will be shown if you were to print the resulting array using the return value as it's new size.
int remove_match(int array[], int length, int match)
{
size_t shift(0);
int removed(0);
for (size_t i = 0; i < length; ++i)
{
if (array[i] == match)
{
removed++;
}
else
{
array[shift++] = array[i];
}
}
return (length - removed);
}
You would invoke this function like this for example
int match = 2;
int data[] = { 2, 1, 3, 2, 5, 2, 7, 8, 4, 9 };
int length = 10;
int newLength = remove_match(data, length, match);
// validate your results
for(int i = 0; i < newLength; ++i)
{
std::cout << data[i] << " ";
}
std::cout << std::endl;

You can't resize a C-style array without creating a new one. It is fixed. If you are looking for counting occurrence of a particular element and tracking the sum of the new data, then you could simply do
void test() {
int data[] = { 2, 1, 3, 2, 5, 2, 7, 8, 4, 9 };
int length = 10;
int x = 2;
//int index =0;
int sum(0);
int counter = 0;
for (int i = 0; i < length; i++) {
if (x == data[i]) {
//index = i;
//--counter; //return # of ocurrences in array
//cout << "Position of ocurrences: " << index << endl;
++counter;
}else{
sum += data[i];
}
}
//for (int a = counter; a < length; a++) {
//data[a] = data[a + 1];
//cout <<"testing"<< data[a];
//}
cout << "Number of ocurences: " << counter << " sum: " << sum << endl;
}
Another approach is to assign the repeated element with zero but this will not resize the array but rather it eliminates the repeated one. This is a workaround approach but it modifies the original data.

Related

How to convert 2D array to 1D in C++?

So for example I have a 2D array A={{1,2,3}, {2,3},{5}}; and I want to get all the rows existing in the array A. I have the length of array stored in variable "lenA", here lenA=3. Also I have an Array B which has the length of each subarray in A. Say B={3,2,1} in this case. In reference to my example array A, how to I dynamically get 3 subarrays from one 2D array i.e. A?
So as a result I would have something like:
A1={1,2,3}
A2={2,3}
A3={5}
You can't dynamically generate new identifiers in C++. The closest you can get is using the preprocessor to generate your names, and by definition, that's done before compilation.
If you already have a fixed number of named array pointers, you could assign those dynamically. But any solution that must accept an arbitrary number of rows at runtime will require that you use something like an array index.
for (int i = 0; i < lenA; i++)
{
// Do something with the row at A[i]
}
Pseudo code
for i in 0 to lenA-1
for j in 0 to lenB[i]-1
A[i][j] whatever...
My try converting A(4x4) to triangle *a[4]:
#include <iostream>
#include <algorithm>
int main()
{
constexpr int lenA = 4;
double A[lenA][lenA]={{1,2,3,4}, {5,6, 7, 0}, {8, 9,0,0},{10,0,0,0}};
double *a[lenA];
int B[lenA] = {4, 3, 2, 1};
for (int i=0; i < lenA; i++)
{
a[i] = new double [ B[i] ];
std::copy_n(A[i], B[i], a[i]);
}
for (int i=0; i<lenA; i++) {
std::cout << "row " << i << ": ";
for (int j=0; j<B[i]; j++) {
std::cout << a[i][j] << ". ";
}
std::cout <<std::endl;
}
return 0;
}
result:
$ ./a.exe
row 0: 1. 2. 3. 4.
row 1: 5. 6. 7.
row 2: 8. 9.
row 3: 10.
you can find the verification of the below code at http://cpp.sh/57pi2
A1D represent the 1-Dimensional array which you was looking for,
#include <iostream>
int main()
{
const int lenA = 4;
double A2D[][lenA]={{1,2,3,4},{5,6,7},{8,9},{10}};
double *A1D;
int B[lenA] = {4,3,2,1};
int num_of_elements = 0;
for (int i=0; i < lenA; i++)
num_of_elements += B[i];
A1D = new double[num_of_elements] ;
for (int i=0, k=0; i<lenA; i++)
for (int j=0; j<B[i]; j++)
A1D[k++] = A2D[i][j];
for (int j=0; j<num_of_elements; j++)
std::cout << A1D[j] << std::endl;
}
std::ranges in C++20 or ranges library (C++14 compliant) does it in clean way:
double A[][4] {
{ 1, 2, 3, 4},
{ 5, 6, 7, 0},
{ 8, 9, 0, 0},
{10, 0, 0, 0}
};
for (auto x : std::ranges::views::join(A))
std::cout << x << '\n';
https://godbolt.org/z/hPP7e9

insertElement() function doesn't work as intended

I'm having an issue in my program with my insertElement() function. What I had intended insertElement to do is to take the index from the prototype and move all the values to the right, including the value on that index, to the right ONCE. So, If I were to have my array {1, 2, 3, 4} and I wanted to insert the value "10" at the index "2", the resulting array would be {1, 2, 10, 3, 4}.
I know I'd have to tweak my insertElement() function to fix this issue, but I'm not sure where to start, could anybody give me a hand? Here is my code:
#include <iostream>
using namespace std;
const int CAPACITY = 20;
void displayArray(int array[], int numElements)
{
for (int i = 0; i < numElements; i++)
cout << array[i] << " ";
cout << endl;
}
bool insertElement(int array[], int& numberElements, int insertPosition, int insertTarget)
{
int p = 0;
int j = 1;
int arrayPositionFromLast = (numberElements-1);
if (numberElements>=CAPACITY)
{
cout << "Cannot insert an element, array is full." << endl;
return false;
} else {
for (int i=arrayPositionFromLast; i>insertPosition; i--)
{
array[arrayPositionFromLast-p]=array[arrayPositionFromLast-j];
p++;
j++;
}
array[insertPosition] = insertTarget;
}
return true;
}
int main()
{
int array[6] = {1, 2, 3, 4, 5, 6};
int numArrayElements = 6;
int endOfArrayValue, insertedValue, insertedValuePosition;
cout << "Enter a value and a position to insert: ";
cin >> insertedValue >> insertedValuePosition;
insertElement(array, numArrayElements, insertedValuePosition, insertedValue);
displayArray(array, numArrayElements);
}
first you should define your array with CAPACITY
int array[CAPACITY] = {1, 2, 3, 4, 5, 6};
You can move your data with memmove.
if (numberElements>=CAPACITY)
{
cout << "Cannot insert an element, array is full." << endl;
return false;
} else {
memmove(array + insertPosition+ 1, array + insertPosition, (numberElements - insertPosition) * sizeof (int));
array[insertPosition] = insertTarget;
}

How to double values in 2d array? C++

I'm trying to double each number in 2D arrays. For example the values in array1 would become {2,4,6}{4,8,12}{6,12,18}. The problem is that my code doubles the only the first number. Can someone give me some direction on what to do?
#include <iostream>
#include <iomanip>
using namespace std;
const int N = 3;
int doubleValues(int arr[][N])
{
for (int i = 0; i < N; i++)
{
arr[i][N] *= 2;
for (int j = 0; j < N; j++)
{
arr[N][j] *= 2;
return arr[i][j];
}
}
}
void showArray(int arr[][N])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cout << setw(4) << arr[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int array1 [N][N] = {
{ 1, 2, 3 } ,
{ 2, 4, 6 } ,
{ 3, 6, 9 }
};
int array2 [N][N] = {
{ 3, 4, 5 } ,
{ 6, 8, 10 } ,
{ 9, 12, 15 }
};
cout << "The values for array1 doubled are: \n";
doubleValues(array1);
showArray(array1);
cout << "The values for array2 double are: \n";
doubleValues(array2);
showArray(array2);
system("pause");
}
You have a return arr[i][j] in the inner loop of your doubleValues function. After doubling the first element, your function returns without doing any more work.
The solution is to remove this return statement. (And change doubleValues to a void function, because it doesn't need to return a value.)
Also, your doubleValues function seems to be modifying the wrong elements anyway. Both your accesses to arr[i][N] and arr[N][j] access elements out of bounds of your declared array size. You should probably be modifying arr[i][j] within your loop.
If you can use std::array for this project (since you know the size of your array at compile time) , you can use the functions within the <algorithm> header to easily implement your doubleValues function and not worry about hand-writing the loops.
template<typename T, std::size_t size>
void doubleValues(std::array<T,size>& arr)
{
std::transform(std::begin(arr),std::end(arr),std::begin(arr), [](auto x) { return 2 * x; });
}
This method would require that you break your 2d-array structure down into a single dimension, which can be accomplished with relative ease. For example,
std::array<int,N*N> array1 = { 1, 2, 3, 2, 4, 6, 3, 6, 9 };
std::array<int,N*N> array2 = { 3, 4, 5, 6, 8, 10, 9, 12, 15}
In the case where the size of the arrays could change dynamically, you can swap out std::array for std::vector.

Algorithm for deleting multiple array elements and shifting array

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;
}

Linear Search returning array with indices value is found at

I attempted a program to return an array with the indicies of the array where a specific inputed value is found, but every run results in an error, which seems to be an infinite run time. The error seems to be occuring right after printing out the last of the indicies found.
Can anyone help?
(Side note: I've seen multiple pages about deleting pointers when done with them; should I be doing that here?)
Forgot to mention - I want the first slot of the returned array to save the size of the array, so that it can be accessed easily later on in the program
#include <iostream>
#include <vector>
using namespace std;
int* linearSearch(int* n, int k, int f) {
// Input: Index 0 Address ; Size of Array; Element to Search
// Output: Array of Found Indicies
vector <int> a;
int* b;
for(int i = 0; i < k; i++)
if(n[i] == f)
a.push_back(i);
*b = a.size();
for(int i = 0; i < a.size(); i++)
b[i + 1] = a[i];
return b;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
int* k = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(int i = 0; i < k[0]; i++) {
cout << "Found at index: " << k[i + 1] << endl;
}
return 0;
}
int* b;
....
*b = a.size();
b has to be allocated. Try following:
int* b = new int[a.size() + 1];
b[0] = a.size();
I see what you meant. b will have magically length in first element. This was in Pascal/Delphi but not the case in C/C++.
You are writing to heap memory that you never claimed.
int* b;
This pointer, having never been initialized, points to an undefined memory address. Then when you use the indexing operator to assign your matches, you are writing to the subsequent bytes following the undefined memory address.
You need to allocate space for storing the results using the 'new[]' operator. Additionally, if you had correctly claimed the memory, you would be assigning the number of match results to the first element in the result array - something that doesn't seem to be your intention.
Take a look at dynamic memory allocation in C++ using the new [] operator.
If you use std::vector anyway, why not to use it where it is needed the most? Also if you not suppose to modify array by that pointer express that by const pointer:
std::vector<int> linearSearch(const int* n, int k, int f)
{
std::vector<int> res;
for(int i = 0; i < k; i++)
if(n[i] == f) res.push_back(i);
return res;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
std::vector<int> k = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(int i = 0; i < k.size(); i++) {
cout << "Found at index: " << k[i] << endl;
}
return 0;
}
This is not perfect but this is much closer to a correct implementation and you should be able to take it further with some work:
#include <iostream>
#include <vector>
using namespace std;
std::vector<int> linearSearch(int* n, int k, int f)
{
vector <int> a;
for(int i = 0; i < k; i++)
{
if(n[i] == f)
{
a.push_back(i);
}
}
return a ;
}
int main() {
int c[10] = {4, 4, 6, 3, 7, 7, 3, 6, 2, 0};
std::vector<int> result = linearSearch(&c[0], sizeof(c)/sizeof(int), 4);
for(unsigned int i = 0; i < result.size(); i++)
{
cout << "Found at index: " << result[i + 1] << endl;
}
return 0;
}