i'm writing a code for a project, in which i need to move values inside a vector! For example, i have a completely "null" vector:
[0][0][0][0][0]
Then i will add a value to it's first position: [10][0][0][0][0]!
Ok, now i need to add again a value to the first position, but i cant lose the value already there, i want to move it to the right, like:
[0][10][0][0][0]
To put the new one there: [5][10][0][0][0]
And then do this again, move the 5 and the 10 to the right again, to add a new one in the first, and so on!
I hope i was clear enough!
#EDIT :
Its done guys! Thanks to everyone that tried to help!
The problem was solved using #AkashPradhan function:
void changeposition(int* vetor, unsigned int size, int valor)
{
unsigned int i = size - 1;
for(; i > 0; --i)
vetor[i] = vetor[i-1] ;
vetor[0] = valor ;
}
Thanks #AkashPradhan! The function worked perfectly with my code!
You can use a Linked List and add to the front node or you could use an array and shift the elements by one position for each insertion.
In this case, I would recommend using a Linked List as the insertion routine will not involving moving every element. However if frequent random access to elements in required, use the array approach.
void insert_front(int* array, unsigned int size, int value)
{
unsigned int i = size - 1;
for(; i > 0; --i)
array[i] = array[i-1] ;
array[0] = value ;
}
Note that the routine does not check if you are inserting more elements that the size of the array.
You could implement this as a ring buffer, in which case you don't need to copy the elements all the time. An example of it would be:
typedef struct
{
size_t bufferSize;
size_t currentPos;
int *data;
} ring_buffer;
void init_buffer(ring_buffer *buffer, size_t N)
{
buffer->bufferSize = N;
buffer->currentPos = 0;
buffer->data = malloc(N*sizeof(int));
}
void free_buffer(ring_buffer *buffer)
{
free(buffer->data);
}
void push_buffer(ring_buffer *buffer, int value)
{
++buffer->currentPos;
if (buffer->currentPos >= buffer->bufferSize)
buffer->currentPos = 0;
buffer->data[buffer->currentPos] = value;
}
int get_buffer(ring_buffer *buffer, size_t pos)
{
size_t dataPos = buffer->currentPos + pos;
if (dataPos >= buffer->bufferSize)
dataPos -= buffer->bufferSize;
return buffer->data[dataPos];
}
or you could use a linked list as suggested by #AkashPradhan.
Define your own array, implement push operation, shift right data when push a new element. This implementation would delete the stale element.
typedef struct Array {
int *data;
size_t len; // current size of the array
size_t cap; // capacity of the array
}Array;
Array * new_array (size_t cap_){
Array *arr = (Array *)malloc(sizeof(Array));
arr->cap = cap_;
arr->len = 0;
arr->data = (int*)malloc(sizeof(int) * cap);
return arr;
}
void free_array(Array * arr){
if (arr->data != NULL)
free(arr->data);
free(arr);
}
void push(int x, Array *arr) {
int ptr = std::min(len, cap) - 2;
for(int i = ptr;i >= 0;i --) {
arr->data[ptr + 1] = arr->data[ptr];
}
arr->data[0] = x;
len = std::max(cap, len + 1);
}
Update : You can also use Tamás Szabó 's answer to avoid data movement.
If you need to write the corresponding function yourself then it can look the following way
size_t move( int a[], size_t n )
{
if ( n++ != 0 )
{
for ( size_t i = n; --i != 0; ) a[i] = a[i-1];
}
return n;
}
And you could use it the following way
size_t n = 0;
n = move( a, n );
a[0] = 10;
n = move( a, n );
a[0] = 5;
for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
printf( "\n" );
Otherwise you have to use standard C function memmove the following way
memmove( a + 1, a, n * sizeof( int ) );
++n;
where n is the current number of actual elements in the array.
Related
I am trying to do a void insertion(), but always get a segmentation fault, see following. Same time, I referenced this link.
First, I did realloc(), then move every memory to the next space after the position, last put the insertion in the position and increase nArraySize.
#include <stdio.h>
#include <stdlib.h>
void printArray(double array[], unsigned int size)
{
for (unsigned int i = 0; i < size; ++i)
{
printf("%.3f ", array[i]);
}
printf("\n");
}
void insert(double **array,
size_t *nArraySize,
double insertion,
unsigned int position)
{
//realloc the memory space first
*array = realloc(*array, (*nArraySize+1) * sizeof(double));
for(unsigned int i = nArraySize[0]-1; i >= position; i--)
{
*array[i+1] = *array[i];
}
*array[position] = insertion;
*nArraySize += 1;
}
int main()
{
double *t = calloc(4, sizeof(double));
t[0] = 0;
t[1] = 1;
t[2] = 2;
t[3] = 3;
size_t k = 4;
insert(&t, &k, 1, 1);
printf("k is %zu\n", k);
printArray(t, k);
free(t);
}
Please help. Any suggestion is welcome.
These statements are incorrect due to the operator precedence.
*array[i+1] = *array[i];
*array[position] = insertion;
That is postfix operators have a higher precedence than unary operators.
You have to write either
( *array )[i+1] = ( *array )[i];
( *array )[position] = insertion;
or as you are already doing like
array[0][i+1] = array[0][i];
array[0][position] = insertion;
Pay attention to that your function insert is unsafe because there is no check whether the value of position is less than or equal to the current number of elements in the passed array.
Also this for loop
for(unsigned int i = nArraySize[0]-1; i >= position; i--)
{
( *array )[i+1] = ( *array )[i];
}
can invoke undefined behavior. First of all the variable i has always a non-negative number. That is the value of i can not be negative because the variable i has the type unsigned int. Now let's assume that *nArraySize is equal to 1 and position is equal to 0; In this case you have the loop
for(unsigned int i = 0; i >= 0; i--)
{
( *array )[i+1] = ( *array )[i];
}
and after the first iteration of the loop the value of i will be very big that is greater than 0.
So it will be better to rewrite the loop the following way
for(unsigned int i = *nArraySize; i > position; i--)
{
( *array )[i] = ( *array )[i-1];
}
I need to filter some specific elements from an array. I write the code which work perfectly:
#include <stdio.h>
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
int main (int argc, char *argv[]) {
// our initial array
int x[] = {1,2,-3,4,5};
// initialize filtered_array with pointer
int *filtered;
int upper_bound = 4, lower_bound = 1, i, j=0, total = -1,result;
size_t n = NELEMS(x);
printf("size of the main array: %d\n",n);
// check which element satisfy the condition and count them
for (i=0;i<n;++i)
{
total = ((x[i] >= lower_bound) && (x[i] <= upper_bound)) ? total+1 : total;
};
// allocate array size for filtered array
filtered = (int*) calloc(total,sizeof(int));
for (i=0;i<n;++i)
{
// filter element from main array and store them in filtered array
result = ((x[i] >= lower_bound) && (x[i] <= upper_bound)) ? 1 : 0;
if(result) {
filtered[j] = x[i];
++j;
};
};
for (i = 0; i<total+1; ++i){
printf("%d ",filtered[i]);
};
return 0;
}
But can I avoid to create a new array like I used filtered and dynamically do this for the main array by some overwrite trick?
For starters your program is incorrect.
Firstly you need to include the header <stdlib.h>
#include <stdlib.h>
Secondly, initially total is set to -1
total = -1
So if the original array contains only one element that satisfies the condition then total will be equal to 0 due to this statement
total = ((x[i] >= lower_bound) && (x[i] <= upper_bound)) ? total+1 : total;
As a result this statement
filtered = (int*) calloc(total,sizeof(int));
is trying to allocate a memory with the size equal to 0. If the memory will be allocated (it is implementation defined) then you may not write anything in this memory. Otherwise the program will have undefined behavior.
In any case you are counting elements that satisfy the condition incorrectly and hence allocating a block of memory of an incorrect size.
Also there is no sense to insert a null statement after compound statements as you are doing
for (i=0;i<n;++i)
{
//...
};
^^^
Remove such redundant semicolons.
And you are using an incorrect conversion specifier in this call of printf.
printf("size of the main array: %d\n",n);
^^^
You have to write
printf("size of the main array: %zu\n",n);
^^^
As for your question
But can I avoid to create a new array like I used filtered and
dynamically do this for the main array by some overwrite trick?
then what you need is to change the array in place and to track the number of actual elements that satisfy the condition.
For example
int x[] = {1,2,-3,4,5};
// initialize filtered_array with pointer
size_t n = NELEMS(x);
int upper_bound = 4, lower_bound = 1;
printf( "size of the main array: %zu\n", n );
size_t m = 0;
for ( size_t i = 0; i < n; ++i )
{
if ( x[i] >= lower_bound) && x[i] <= upper_bound )
{
if ( m != i )
{
x[m] = x[i];
}
++m;
}
}
for ( size_t i = 0; i < m; ++i )
{
printf( "%d ", x[i] );
}
putchar( '\n' );
If you need to reallocate the original array according to the number of elements that satisfy the condition then the code can look for example the following way
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//...
size_t n = 5;
int *x = malloc( n * sizeof( int ) );
memcpy( x, ( int[] ){ 1, 2, -3, 4, 5 }, n * sizeof( int ) );
int upper_bound = 4, lower_bound = 1;
printf( "size of the main array: %zu\n", n );
size_t m = 0;
for ( size_t i = 0; i < n; ++i )
{
if ( x[i] >= lower_bound) && x[i] <= upper_bound )
{
if ( m != i )
{
x[m] = x[i];
}
++m;
}
}
if ( m != n )
{
int *tmp = realloc( x, m * sizeof( int ) );
if ( tmp != NULL )
{
x = tmp;
for ( size_t i = 0; i < m; ++i )
{
printf( "%d ", x[i] );
}
putchar( '\n' );
}
}
free( x );
What you are looking for is called modification (in this case filtering) in place.
That's even pretty simple:
int* filter(int* begin, int* end)
{
int* pos = begin; // start at the beginning of the array
for(; begin != end; ++begin)
{
if(*begin != 0) // your appropriate condition!
// this one filters out all zero values...
{
*pos++ = *begin; // copy current element to retain into
// first position not yet used
// (pos always points to one element past
// the last one retained!)
}
}
return pos; // as above, points to one past the last element retained
}
The return value is important to know how many elements remained.
If you prefer, you can instead write an index-based variant avoiding pointer arithmetics...
The basic idea about the filtering algorithm is that you just copy the elements towards the front, overwriting those values that either are filtered away or have already been copied.
Edit: Additional explanations:
begin and end pointers are to be passed as pointer to first element of the array and pointer to one past the array (typical C++ semantics when iterating over C++ STL containers, though these come with their own iterator types instead of pointers...).
So you'd call the function like:
int array[N];
int* newEnd = filter(array, array + sizeof(array)/sizeof(*array));
This is typical C++ semantics when iterating over STL containers (though these come with their specific iterator types instead of poitners).
If you don't like:
size_t filter(size_t length, int array[length]) // note: length as array subscript
// is ignored anyway...
{
int* pos = array;
int* begin = array;
int* end = array + length;
// now following the identical loop as above
return pos - array; // pointer difference; if pos points one past the last
// element you get the *number* of elements retained
}
About *pos++ = *begin: That's nothing special and any good C book should explain that nicely to you...
It copies the value begin points to to the address pos points to and increments pos afterwards.
An indexing loop doing the same might look as follows:
size_t pos = 0;
for(size_t i = 0; i < length; ++i)
{
array[pos++] = array[i]
}
return pos;
I am trying to write a sorting algorithm using a function that finds the adress of the minimum element in the array:
#include <stdio.h>
int * findMin(int * start,int * end) ///function to return the adress of the smallest array element
{
int *min = start;
int x;
int size = (end - start);
for(x=0; x<size; x++)
{
if (*(start+x)<*min)
min = (start+x);
}
return min;
}
But here in my sort algorithm, since the last element has nothing more to compare itself with, is mistakenly left as it is
void sort(int * start, int * end) ///funtion to sort the array in ascending order
{
int x,temp;
int size = (end - start);
for (x = 0; x <size; x++)
{
if ( *(start+x) > *findMin(start,end))
{
temp = *findMin(start+x,end);
*findMin(start+x,end) = *(start+x);
*(start+x) = temp;
}
}
}
int main()
{
int arr[10]={5,11,3,12,17,25,1,9,14,2};
sort(arr,&arr[9]);
for(int i=0;i<10;i++)
printf("%d ",arr[i]);
printf("\n");
}
How can I correct this?
The expression in this declaration
int size = (end - start);
does not give the exact size of the array. At least you should write
int size = end - start + 1;
However it is not a good idea to pass the pointer to the last element of the array instead of the pointer to the memory after the last element of the array. In this case you can specify an empty range as start is equal to end.
Also if the function accepts two pointers then there is no need to introduce intermediate variables used as indices in loops.
And this code snippet
temp = *findMin(start+x,end);
*findMin(start+x,end) = *(start+x);
*(start+x) = temp;
is very inefficient.
Here is a demonstrative program that shows how the functions can be implemented.
#include <stdio.h>
int * findMin( const int * start, const int * end ) ///function to return the adress of the smallest array element
{
const int *min = start;
if ( start != end )
{
while ( ++start != end )
{
if ( *start < *min ) min = start;
}
}
return ( int * )min;
}
void selection_sort( int *start, int *end ) ///funtion to sort the array in ascending order
{
for ( ; start != end; ++start )
{
int *min = findMin( start, end );
if ( min != start )
{
int tmp = *start;
*start = *min;
*min = tmp;
}
}
}
int main(void)
{
int arr[] = { 5, 11, 3, 12, 17, 25, 1, 9, 14, 2 };
const size_t N = sizeof( arr ) / sizeof( *arr );
for ( const int *p = arr; p != arr + N; ++p )
{
printf( "%d ", *p );
}
putchar( '\n' );
selection_sort( arr, arr + N );
for ( const int *p = arr; p != arr + N; ++p )
{
printf( "%d ", *p );
}
putchar( '\n' );
return 0;
}
The program output is
5 11 3 12 17 25 1 9 14 2
1 2 3 5 9 11 12 14 17 25
But here in my sort algorithm, since the last element has nothing more to compare itself with, is mistakenly left as it is
No, that's at best a misleading characterization. Your findMin() does not specifically compare array elements to their immediate successors, so the fact that *end has no successor is irrelevant. The problem is (in part) simply that you have an off-by-one error, resulting in never comparing *end with *min. That mistake would be harder to make and easier to recognize if you relied more directly on pointer arithmetic and comparisons:
int *findMin(int *start, int *end) {
int *min = start;
// The original code is equivalent to this variant:
// for (int *x = start; x < end; x++) {
// but this is what you need for an inclusive upper bound:
// for (int *x = start; x <= end; x++) {
// or, since initially min == start, this would be even better:
for (int *x = start + 1; x <= end; x++) {
if (*x < *min) {
min = x;
}
}
return min;
}
I am a computer science freshman and I still have some difficulties when it comes to pointers. I am trying to implement a quick sort program in C.I currently have 2 errors but I am not able to figure out how to fix it.
On the main function, when I am calling partition, I got an Incompatible pointer types
On the swap function: Thread 1: EXC_BAD_ACCESS (code=1, address=0x200000007)
void swap(int *i, int* j){
*i = *j;
*j = *i;
*i = *j;
}
void partition(int* array[], int size){
int pivot = size;
int i = - 1;
for(int j = 0 ; j < size - 1 ; j++){
if(array[j] < array[pivot]){
i++;
swap(array[i],array[j]);
}
}
}
int main() {
int array[] = {7,2,1,8,6,3,5,4};
int size = sizeof(array)/sizeof(array[0]);
partition(&array,size);
return 0;
}
For starters if an array has N elements then the valid range of indices is [0, N-1]
Thus there is an attempt to access memory beyond the array
int pivot = size;
int i = - 1;
for(int j = 0 ; j < size - 1 ; j++){
if(array[j] < array[pivot])
^^^^^^^
Your function swap does not make sense.
void swap(int *i, int* j){
*i = *j;
*j = *i;
*i = *j;
}
After the first expression statement
*i = *j;
the both objects pointed to by the pointers i and j will have the same value.
The function can be defined the following way.
void swap( int *p, int *q )
{
int tmp = *p;
*p = *q;
*q = tmp;
}
and called like
swap( &array[i], &array[j] );
The function partition is also invalid. Apart from the incorrect used algorithm at least its first parameter is declared also incorrectly.
Instead of
void partition( int* array[], int size );
the function should be declared like
void partition( int *array, int size );
or more correctly like
void partition( int *array, size_t size );
and the function should be called like
int array[] = {7,2,1,8,6,3,5,4};
size_t size = sizeof(array)/sizeof(array[0]);
partition( array,size );
On the other hand, the function partition should return the position that divides the array into two parts. So the final function declaration will look like
size_t partition( int array[], size_t size );
Below there is a demonstrative program that shows how a recursive function quick sort can be written using functions swap and partition.
#include <stdio.h>
void swap( int *p, int *q )
{
int tmp = *p;
*p = *q;
*q = tmp;
}
size_t partition( int a[], size_t n, int pivot )
{
size_t i = 0;
while ( i != n )
{
while ( i != n && a[i] < pivot ) i++;
while ( i != n && !( a[--n] < pivot ) );
if ( i != n ) swap( a + i, a + n );
}
return i;
}
void quick_sort( int a[], size_t n )
{
if ( n != 0 )
{
size_t pos = partition( a, n - 1, a[n - 1] );
swap( a + pos, a + n - 1 );
quick_sort( a, pos );
quick_sort( a + pos + 1, n - pos - 1 );
}
}
int main(void)
{
int a[] = { 7, 2, 1, 8, 6, 3, 5, 4 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
quick_sort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
7 2 1 8 6 3 5 4
1 2 3 4 5 6 7 8
There are a few problems in here:
The pointer notation has the weird effect that the star comes after the thing it points to, so the int* array[] in partition is an array of pointers to integers, while what you call it with in main is a pointer to an array of integers.
An array[] is actually a pointer by itself (though with some slightl technical differences, but in general something that accepts a pointer will also accept an array). You are mainly using the array in partition as an array of integers (the array[j] < array[pivot] should be a comparison of content, but with an int* array[] it is a comparison of address), so you should change it to just being an int array[]. Note that this will also help with resolving point 1, as you just need to remove the superflous referencing when you call partition.
When you index an array it counts as a dereferencing, so when you call swap(array[i],array[j]) (assuming you have made the corrections suggested above) you are passing ints and not int*s, you need to change it to swap(&array[i],&array[j]).
In swap you are setting both of their values to j's. This happens because the information of what is in i is destroyed when you write over it. There are several ways to handle this, the 2 main ones are saving the information in a temporary variable, and the second is through bit-hacking. Here are 2 examples:
void swap(int *i, int* j){
int temp = *j;
*j = *i;
*i = temp;
}
An a version using exlusive or:
void swap(int *i, int* j){
*i= *j ^ *i;
*j= *j ^ *i;
*i= *j ^ *i;
}
pointers
I wasn't sure if the question was asking about a pointer based quicksort, so here is an example, using Lomuto partition scheme. In the partition loop, it recurses on the smaller part, and loops back for the larger part, limiting stack space to O(log(n)), but worst case time complexity remains at O(n^2).
void QuickSort(int *lo, int *hi)
{
int *pi;
int *pj;
int pv;
int t;
while (lo < hi){
pv = *hi; /* pivot */
pi = lo; /* partition */
for (pj = lo; pj < hi; ++pj){
if (*pj < pv){
t = *pi; /* swap *pi, *pj */
*pi = *pj;
*pj = t;
++pi;
}
}
t = *pi; /* swap *pi, *hi */
*pi = *hi; /* to place pivot */
*hi = t;
if(pi - lo <= hi - pi){ /* recurse on smaller part */
QuickSort(lo, pi-1); /* loop on larger part */
lo = pi+1;
} else {
QuickSort(pi+1, hi);
hi = pi-1;
}
}
}
This question already has answers here:
Algorithm: efficient way to remove duplicate integers from an array
(34 answers)
Closed 8 years ago.
I want small clarification in array concept in C.
I have array:
int a[11]={1,2,3,4,5,11,11,11,11,16,16};
I want result like this:
{1,2,3,4,5,11,16}
Means I want remove duplicates.
How is it possible?
You can't readily resize arrays in C - at least, not arrays as you've declared that one. Clearly, if the data is in sorted order, it is straight-forward to copy the data to the front of the allocated array and treat it as if it was of the correct smaller size (and it is a linear O(n) algorithm). If the data is not sorted, it gets messier; the trivial algorithm is quadratic, so maybe a sort (O(N lg N)) followed by the linear algorithm is best for that.
You can use dynamically allocated memory to manage arrays. That may be beyond where you've reached in your studies, though.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static int intcmp(const void *pa, const void *pb)
{
int a = *(int *)pa;
int b = *(int *)pb;
if (a > b)
return +1;
else if (a < b)
return -1;
else
return 0;
}
static int compact(int *array, int size)
{
int i;
int last = 0;
assert(size >= 0);
if (size <= 0)
return size;
for (i = 1; i < size; i++)
{
if (array[i] != array[last])
array[++last] = array[i];
}
return(last + 1);
}
static void print(int *array, int size, const char *tag, const char *name)
{
int i;
printf("%s\n", tag);
for (i = 0; i < size; i++)
printf("%s[%d] = %d\n", name, i, array[i]);
}
int main(void)
{
int a[11] = {1,2,3,4,5,11,11,11,11,16,16};
int a_size = sizeof(a) / sizeof(a[0]);
print(a, a_size, "Before", "a");
a_size = compact(a, a_size);
print(a, a_size, "After", "a");
int b[11] = {11,1,11,3,16,2,5,11,4,11,16};
int b_size = sizeof(b) / sizeof(b[0]);
print(b, b_size, "Before", "b");
qsort(b, b_size, sizeof(b[0]), intcmp);
print(b, b_size, "Sorted", "b");
b_size = compact(b, b_size);
print(b, b_size, "After", "b");
return 0;
}
#define arraysize(x) (sizeof(x) / sizeof(x[0])) // put this before main
int main() {
bool duplicate = false;
int a[11] = {1,2,3,4,5,11,11,11,11,16,16}; // doesnt have to be sorted
int b[11];
int index = 0;
for(int i = 0; i < arraysize(a); i++) { // looping through the main array
for(int j = 0; j < index; j++) { // looping through the target array where we know we have data. if we haven't found anything yet, this wont loop
if(a[i] == b[j]) { // if the target array contains the object, no need to continue further.
duplicate = true;
break; // break from this loop
}
}
if(!duplicate) { // if our value wasn't found in 'b' we will add this non-dublicate at index
b[index] = a[i];
index++;
}
duplicate = false; // restart
}
// optional
int c[index]; // index will be the number of objects we have in b
for(int k = 0; k < index; k++) {
c[k] = b[k];
}
}
If you really have to you can create a new array where that is the correct size and copy this into it.
As you can see, C is a very basic (but powerful) language and if you can, use a vector to but your objects in instead (c++'s std::vector perhaps) which can easily increase with your needs.
But as long as you only use small numbers of integers you shouldn't loose to much. If you have big numbers of data, you can always allocate the array on the heap with "malloc()" and pick a smaller size (maybe half the size of the original source array) that you then can increase (using realloc()) as you add more objects to it. There is some downsides reallocating the memory all the time as well but it is a decision you have to make - fast but allocation more data then you need? or slower and having the exact number of elements you need allocated (which you really cant control since malloc() might allocate more data then you need in some cases).
//gcc -Wall q2.cc -o q2 && q2
//Write a program to remove duplicates from a sorted array.
/*
The basic idea of our algorithm is to compare 2 adjacent values and determine if they
are the same. If they are not the same and we weren't already looking previusly at adjacent pairs
that were the same, then we output the value at the current index. The algorithm does everything
in-place and doesn't allocate any new memory. It outputs the unique values into the input array.
*/
#include <stdio.h>
#include <assert.h>
int remove_dups(int *arr, int n)
{
int idx = 0, odx = -1;
bool dup = false;
while (idx < n)
{
if (arr[idx] != arr[idx+1])
{
if (dup)
dup = false;
else
{
arr[++odx] = arr[idx];
}
} else
dup = true;
idx++;
}
return (odx == -1) ? -1 : ++odx;
}
int main(int argc, char *argv[])
{
int a[] = {31,44,44,67,67,99,99,100,101};
int k = remove_dups(a,9);
assert(k == 3);
for (int i = 0;i<k;i++)
printf("%d ",a[i]);
printf("\n\n");
int b[] = {-5,-3,-2,-2,-2,-2,1,3,5,5,18,18};
k = remove_dups(b,12);
assert(k == 4);
for (int i = 0;i<k;i++)
printf("%d ",b[i]);
printf("\n\n");
int c[] = {1,2,3,4,5,6,7,8,9};
k = remove_dups(c,9);
assert(k == 9);
for (int i = 0;i<k;i++)
printf("%d ",c[i]);
return 0;
}
you should create a new array and you should check the array if contains the element you want to insert before insert new element to it.
The question is not clear. Though, if you are trying to remove duplicates, you can use nested 'for' loops and remove all those values which occur more than once.
C does not have a built in data type that supports what you want -- you would need to create your own.
int a[11]={1,2,3,4,5,11,11,11,11,16,16};
As this array is sorted array, you can achieve very easily by following code.
int LengthofArray = 11;
//First elemnt can not be a duplicate so exclude the same and start from i = 1 than 0.
for(int i = 1; i < LengthofArray; i++);
{
if(a[i] == a[i-1])
RemoveArrayElementatIndex(i);
}
//function is used to remove the elements in the same as index passed to remove.
RemoveArrayElementatIndex(int i)
{
int k = 0;
if(i <=0)
return;
k = i;
int j =1; // variable is used to next item(offset) in the array from k.
//Move the next items to the array
//if its last item then the length of the array is updated directly, eg. incase i = 10.
while((k+j) < LengthofArray)
{
if(a[k] == a[k+j])
{
//increment only j , as another duplicate in this array
j = j +1 ;
}
else
{
a[k] = a[k+j];
//increment only k , as offset remains same
k = k + 1;
}
}
//set the new length of the array .
LengthofArray = k;
}
You could utilise qsort from stdlib.h to ensure your array is sorted into ascending order to remove the need for a nested loop.
Note that qsort requires a pointer to a function (int_cmp in this instance), i've included it below.
This function, int_array_unique returns the duplicate free array 'in-place' i.e. it overwrites the original and returns the length of the duplicate free array via the pn pointer
/**
* Return unique version of int array (duplicates removed)
*/
int int_array_unique(int *array, size_t *pn)
{
size_t n = *pn;
/* return err code 1 if a zero length array is passed in */
if (n == 0) return 1;
int i;
/* count the no. of unique array values */
int c=0;
/* sort input array so any duplicate values will be positioned next to each
* other */
qsort(array, n, sizeof(int), int_cmp);
/* size of the unique array is unknown at this point, but the output array
* can be no larger than the input array. Note, the correct length of the
* data is returned via pn */
int *tmp_array = calloc(n, sizeof(int));
tmp_array[c] = array[0];
c++;
for (i=1; i<n; i++) {
/* true if consecutive values are not equal */
if ( array[i] != array[i-1]) {
tmp_array[c] = array[i];
c++;
}
}
memmove(array, tmp_array, n*sizeof(int));
free(tmp_array);
/* set return parameter to length of data (e.g. no. of valid integers not
* actual allocated array length) of the uniqe array */
*pn = c;
return 0;
}
/* qsort int comparison function */
int int_cmp(const void *a, const void *b)
{
const int *ia = (const int *)a; // casting pointer types
const int *ib = (const int *)b;
/* integer comparison: returns negative if b > a
and positive if a > b */
return *ia - *ib;
}
Store the array element with small condition into new array
**just run once 100% will work
!)store the first value into array
II)store the another element check with before stored value..
III)if it exists leave the element--and check next one and store
here the below code run this u will understand better
int main()
{
int a[10],b[10],i,n,j=0,pos=0;
printf("\n enter a n value ");
scanf("%d",&n);
printf("\n enter a array value");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);//gets the arry value
}
for(i=0;i<n;i++)
{
if(check(a[i],pos,b)==0)//checks array each value its exits or not
{
b[j]=a[i];
j++;
pos++;//count the size of new storing element
}
}
printf("\n after updating array");
for(j=0;j<pos;j++)
{
printf("\n %d",b[j]);
} return 0;
}
int check(int x,int pos,int b[])
{ int m=0,i;
for(i=0;i<pos;i++)//checking the already only stored element
{
if(b[i]==x)
{
m++; //already exists increment the m value
}
}
return m;
}