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;
}
Related
I am trying to remove odd numbers from an array, but I'm not allowed to create a new array to store the new values.
So, if I have arr[1,2,3,4,5,6,7,8,9]
then I need it to be arr[2,4,6,8] so that arr[0] will be 2 and not 1.
I can't seem to be able to drop the even numbers without creating a new array to store the values and then feed it back into the original array with the new values.
I have tried to make arr[i] = 0 if its an odd number but then I wasn't able to drop the 0 and replace it with the next even number.
So far, I have this:
void removeOdd(int arr[], int& arrSize){
int i, j = 0;
int temp;
int newArrSize;
for(i = 0, newArrSize = arrSize; i < arrSize; i++){
if(arr[i] % 2 != 0){
arr[i] = 0;
}
}
arrSize = newArrSize;
}
// Moves all even numbers into the beginning of the array in their original order
int removeOdd(int arr[], int arrSize) {
int curr = 0; // keep track of current position to insert next even number into
for (int i = 0; i < arrSize; ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
return curr;
}
int main() {
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int newSize = removeOdd(arr, 10);
for (int i = 0; i < newSize; ++i) {
std::cout << arr[i] << " ";
}
}
0 2 4 6 8
You might want to use std::vector:
void removeOdd(std::vector<int>& arr) {
int curr = 0;
for (int i = 0; i < (int)arr.size(); ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
arr.resize(curr);
}
int main() {
std::vector<int> arr = { 0,1,2,3,4,5,6,7,8,9 };
removeOdd(arr);
for (int number : arr) {
std::cout << number << " ";
}
}
Normally (unless this is homework of some sort), you should use the algorithms in the <algorithm> header.
Using std::remove_if with std::vector's erase member function, you will accomplish exactly what you want with less code:
std::vector<int> vec{ 1,2,3,4,5,6,7,8,10 };
vec.erase(std::remove_if(std::begin(vec), std::end(vec), [](auto const& i) {
return i % 2 != 0;
}), std::end(vec));
Demo
The task: Create a function that takes a list of numbers as a parameter, and returns a list of numbers where every number in the list occurs only once
As far as I know, functions can't return arrays. But if a function's parameter is an array, it will be automatically a reference parameter, so it will "overwrite" the input array even if it's a void function. Is there any way to overwrite (as reference parameter) the input array with a smaller one?
To be specific: in the code below I would like to overwrite the number[10] array with the newArray[6]
I just started to learn code this week, this is a practice task for me, so I would like to use C++ basics to solve this one, without pointers and more complex stuff. If it's not possible, it's okay too.
#include <iostream>
#include <string>
void selectionSort(int[], int);
void unique(int[], int);
void print(int[], int);
int main(int argc, char *args[]) {
int numbers[] = {1, 11, 34, 11, 52, 61, 0, 1, 34, 1, 61, 72};
int size = sizeof(numbers) / sizeof(int);
unique(numbers, size);
return 0;
}
void unique(int arr[], int size) {
selectionSort(arr, size);
int newSize = 1;
for (int i = 0; i < size - 1; ++i) {
if (arr[i] < arr[i + 1]) {
newSize++;
}
}
int newArray[newSize];
int index = 0;
for (int i = 0; i < size - 1; ++i) {
if (arr[i] < arr[i + 1]) {
newArray[index] = arr[i];
++index;
}
}
newArray[newSize - 1] = arr[size - 1];
print(newArray, newSize);
}
void selectionSort(int arr[], int size) {
for (int i = 0; i < size; i++) {
int min = i;
for (int j = i; j < size; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
std::swap(arr[i], arr[min]);
}
}
void print(int arr[], int size) {
for (int i = 0; i < size; ++i) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
This is not valid C++:
int newArray[newSize];
That's VLA, which is C99, only available with gcc.
Instead, do:
int* newArray = new int[newSize];
Return this:
return std::make_pair(newArray, newSize);
As you need to return the size as well!! Even if you can overwrite the input array (you can, obviously, depends on your contract, the documentation of your function), you need to return the new size.
But you may want to take a real C++ class.
I have this program that makes and populates an array. Then it is sent to a function called reverse, which reverses the order in the array. The compiler keeps giving errors. I'm not quite sure why.
CODE
void reverse(int* array, int size) {
for (int i = 0; i < size/2; i++) {
int temp = array[i];
array[i] = array[size-i];
array[size-i] = temp;
} // end of for loop
} // end of reverse
int main( int argc, char** argv ) {
int array[8];
// get and print size of the array
int size = sizeof(array) / sizeof(array[0]);
printf("Size is %d\n", size);
// populate array
for (int i = 0; i < size; i++) {
array[i] = i;
} // end of for loop
// display array before reversing
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
} // end of for loop
// new line
printf("\n");
// reverse the array
reverse(&array, size);
// display the array again after reversing
for (int i = 0;i < size; i++) {
printf("%d ", array[i]);
} // end of for loop
} // end of main
It keeps giving me this error
main.cc:17:14: error: indirection requires pointer operand ('int' invalid)
int temp = *array[i];
^~~~~~~~~
main.cc:18:3: error: indirection requires pointer operand ('int' invalid)
*array[i] = *array[size-i];
^~~~~~~~~
main.cc:18:15: error: indirection requires pointer operand ('int' invalid)
*array[i] = *array[size-i];
^~~~~~~~~~~~~~
main.cc:19:3: error: indirection requires pointer operand ('int' invalid)
*array[size-i] = temp;
^~~~~~~~~~~~~~
4 errors generated.
make: *** [main.o] Error 1
I did solve this problem a little differently, maybe you will use this code:
#include <iostream>
void displayArray(int table[], int size);
void rev(int table[], int size);
void fillTheArray(int table[], int size);
int main(int argc, char** argv) {
int myArray[8];
int size = sizeof(myArray) / sizeof(myArray[0]);
std::cout << "Array size is: " << size << std::endl;
fillTheArray(myArray, size);
displayArray(myArray, size);
std::cout << std::endl;
rev(myArray, size);
displayArray(myArray, size);
std::cin.get();
return 0;
}
void fillTheArray(int table[], int size) {
for (int i = 0; i < size; i++) {
table[i] = i;
}
}
void displayArray(int table[], int size) {
for (int i = 0; i < size; i++) {
std::cout << table[i] << " ";
}
std::cout << std::endl;
}
void rev(int table[], int size) {
int *start = table;
int *end = table + (size - 1);
for (int i = 0; i < size; i++) {
if (start < end) {
int temp = *end;
*end = *start;
*start = temp;
}
start++;
end--;
}
}
I can see two errors in this code. First is: wrong way of passing parametr to function:
// reverse the array
reverse(&array, size);
you should do this just like this(array name is pointer to first element of this array):
reverse(array, size);
Second problem is with reverser - you try to access some random memory outside arrar range:
array[i] = array[size-i];
Remember that in C++ array index's start with 0 not 1. So if your array is size of 8 - largest insext of this array is 7 (0, 1, 2, 3, 4, 5, 6, 7). Your code should look like this:
array[i] = array[size -i -1];
And it should work as you expected.
It is my solution with pointers:
void reverse(int arr[], int count)
{
int* head = arr;
int* tail = arr + count - 1;
for (int i = 0; i < count/2; ++i)
{
if (head < tail)
{
int tmp = *tail;
*tail = *head;
*head = tmp;
head++; tail--;
}
}
for (int i = 0; i < count; ++i)
{
std::cout << arr[i] << " ";
}
}
or just use functions build in C++: std::reverse in 'algorithm' library.
It's a lot of examples on stackoverflow with this kind of examples:
Reverse Contents in Array
You have fixed most of the compiler errors in your code except one.
The line
reverse(&array, size);
should be
reverse(array, size);
After that is fixed, you have to fix logic errors in reverse.
You are using the wrong index for accessing the upper half of the array.
void reverse(int* array, int size) {
for (int i = 0; i < size/2; i++) {
int temp = array[i];
array[i] = array[size-i]; // When i is 0, you are accessing array[size]
// That is incorrect.
array[size-i] = temp;
} // end of for loop
} // end
You need to use
void reverse(int* array, int size) {
for (int i = 0; i < size/2; i++) {
int temp = array[i];
array[i] = array[size-i-1];
array[size-i-1] = temp;
}
}
Another way to approach the algorithm would be to use two indices.
void reverse(int* array, int size) {
for (int i = 0, j = size-1; i < j; ++i, --j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Working program: http://ideone.com/ReVnGR.
You're passing **int instead of *int to the reverse method:
reverse(&array, size);
Pass it like that:
reverse(array, size);
How can I finish my code to take an integer array (arr[]), its length (N), and the number of elements to right-shift (M).
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void shiftright (int myarray[], int size);
int main (void)
{
int myarray [] = {1, 2, 3, 4, 5};
shiftright( myarray, 5);
for ( int i = 0; i < 5; i++)
{
cout << myarray[i] << ' ';
}
return (0);
}
void shiftright (int myarray[], int size, int M)
{
for (int m = (size - 1); m >= 1; m--) {
int temp = myarray[size - 1];
for (int i = (size - 1); i >= 1; i--)
{
myarray[i] = myarray[i - 1] ;
}
myarray[0] = temp;
}
}
Instead of rolling your own, simply use a standard algorithm.
if (m > 0 && size > 0)
std::rotate(myarray, myarray + m % size, myarray + size);
Looks like you're trying to perform a "rotate" operation. Have you considered creating an indexer with an offset and not actually having to rotate anything at all? (This is far less costly.)
Anyways, just remove your outer loop to shift once:
void shiftright (int myarray[], int size)
{
int temp = myarray[size - 1];
for (int i = (size - 1); i >= 1; i--)
{
myarray[i] = myarray[i - 1];
}
myarray[0] = temp;
}
Now, you may create another method to shift m times:
void shiftright (int myarray[], int size, int m)
{
for (int i = 0; i < m; i++)
{
shiftright(myarray, size);
}
}
This is obviously very costly in terms of performance, so you may want to explain what you need this for.
I would like to sort an array in ascending order using C/C++. The outcome is an array containing element indexes. Each index is corespondent to the element location in the sorted array.
Example
Input: 1, 3, 4, 9, 6
Output: 1, 2, 3, 5, 4
Edit: I am using shell sort procedure. The duplicate value indexes are arbitrarily chosen based on which duplicate values are first in the original array.
Update:
Despite my best efforts, I haven't been able to implement a sorting algorithm for an array of pointers. The current example won't compile.
Could someone please tell me what's wrong?
I'd very much appreciate some help!
void SortArray(int ** pArray, int ArrayLength)
{
int i, j, flag = 1; // set flag to 1 to begin initial pass
int * temp; // holding variable orig with no *
for (i = 1; (i <= ArrayLength) && flag; i++)
{
flag = 0;
for (j = 0; j < (ArrayLength - 1); j++)
{
if (*pArray[j + 1] > *pArray[j]) // ascending order simply changes to <
{
&temp = &pArray[j]; // swap elements
&pArray[j] = &pArray[j + 1]; //the problem lies somewhere in here
&pArray[j + 1] = &temp;
flag = 1; // indicates that a swap occurred.
}
}
}
};
Since you're using C++, I would do it something like this. The SortIntPointers function can be any sort algorithm, the important part is that it sorts the array of pointers based on the int that they are pointing to. Once that is done, you can go through the array of pointers and assign their sorted index which will end up in the original position in the original array.
int* intArray; // set somewhere else
int arrayLen; // set somewhere else
int** pintArray = new int*[arrayLen];
for(int i = 0; i < arrayLen; ++i)
{
pintArray[i] = &intArray[i];
}
// This function sorts the pointers according to the values they
// point to. In effect, it sorts intArray without losing the positional
// information.
SortIntPointers(pintArray, arrayLen);
// Dereference the pointers and assign their sorted position.
for(int i = 0; i < arrayLen; ++i)
{
*pintArray[i] = i;
}
Hopefully that's clear enough.
Ok, here is my atempt in C++
#include <iostream>
#include <algorithm>
struct mycomparison
{
bool operator() (int* lhs, int* rhs) {return (*lhs) < (*rhs);}
};
int main(int argc, char* argv[])
{
int myarray[] = {1, 3, 6, 2, 4, 9, 5, 12, 10};
const size_t size = sizeof(myarray) / sizeof(myarray[0]);
int *arrayofpointers[size];
for(int i = 0; i < size; ++i)
{
arrayofpointers[i] = myarray + i;
}
std::sort(arrayofpointers, arrayofpointers + size, mycomparison());
for(int i = 0; i < size; ++i)
{
*arrayofpointers[i] = i + 1;
}
for(int i = 0; i < size; ++i)
{
std::cout << myarray[i] << " ";
}
std::cout << std::endl;
return 0;
}
create a new array with increasing values from 0 to n-1 (where n is the length of the array you want to sort). Then sort the new array based on the values in the old array indexed by the values in the new array.
For example, if you use bubble sort (easy to explain), then instead of comparing the values in the new array, you compare the values in the old array at the position indexed by a value in the new array:
function bubbleRank(A){
var B = new Array();
for(var i=0; i<A.length; i++){
B[i] = i;
}
do{
swapped = false;
for(var i=0; i<A.length; i++){
if(A[B[i]] > A[B[i+1]]){
var temp = B[i];
B[i] = B[i+1];
B[i+1] = temp;
swapped = true;
}
}
}while(swapped);
return B;
}
create a new Array and use bubble sort to rank the elements
int arr[n];
int rank[n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(arr[i]>arr[j])
rank[i]++;
The rank of each element will be rank[i]+1 to be in the order of 1,2,....n
Well, there's a trival n^2 solution.
In python:
newArray = sorted(oldArray)
blankArray = [0] * len(oldArray)
for i in xrange(len(newArray)):
dex = oldArray.index(newArray[i])
blankArray[dex] = i
Depending on how large your list is, this may work. If your list is very long, you'll need to do some strange parallel array sorting, which doesn't look like much fun and is a quick way to introduce extra bugs in your code.
Also note that the above code assumes unique values in oldArray. If that's not the case, you'll need to do some post processing to solve tied values.
Parallel sorting of vector using boost::lambda...
std::vector<int> intVector;
std::vector<int> rank;
// set up values according to your example...
intVector.push_back( 1 );
intVector.push_back( 3 );
intVector.push_back( 4 );
intVector.push_back( 9 );
intVector.push_back( 6 );
for( int i = 0; i < intVector.size(); ++i )
{
rank.push_back( i );
}
using namespace boost::lambda;
std::sort(
rank.begin(), rank.end(),
var( intVector )[ _1 ] < var( intVector )[ _2 ]
);
//... and because you wanted to replace the values of the original with
// their rank
intVector = rank;
Note: I used vectorS instead of arrays because it is clearer/easier, also, I used C-style indexing which starts counting from 0, not 1.
This is a solution in c language
#include <stdio.h>
void swap(int *xp, int *yp) {
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// A function to implement bubble sort
void bubbleSort(int arr[], int n) {
int i, j;
for (i = 0; i < n - 1; i++)
// Last i elements are already in place
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(&arr[j], &arr[j + 1]);
}
/* Function to print an array */
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 98};
int arr_original[] = {64, 34, 25, 12, 22, 11, 98};
int rank[7];
int n = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);
//PLACE RANK
//look for location of number in original array
//place the location in rank array
int counter = 1;
for (int k = 0; k < n; k++){
for (int i = 0; i < n; i++){
printf("Checking..%d\n", i);
if (arr_original[i] == arr[k]){
rank[i] = counter;
counter++;
printf("Found..%d\n", i);
}
}
}
printf("Original array: \n");
printArray(arr_original, n);
printf("Rank array: \n");
printArray(rank, n);
return 0;
}