The code is recursive dynamic programming for the 0/1 Knapsack problem.
So let me start by saying that the code seems correct because when I run it, It shows results but only if I uncomment the printf line (please see the highlighted part) and it has nothing to do with the solution (I used it only for testing purpose) which I find totally weird. Can somebody please tell me why is this happening.
int main() {
int DP_Recursive(int W, static int wt[], static int val[], int n, static int dp[][]);
static int wt[5] = { 5, 10, 20, 30 };
static int val[5] = { 50, 60, 100, 120 };
static int dp[5][60]; //marker 2-D array
for (int i = 0; i <= 5; i++) {
for (int w = 0; w <= 50; w++) {
dp[i][w] = -1;
}
}
printf("The total loot is %d$.", DP_Recursive(50, wt, val, 2, dp));
}
//Recursive D.P. solution
int DP_Recursive(int W, static int wt[], static int val[], int n, static int dp[5][60]) {
//-------**HIGHLIGHTED PART**-----------
printf("%d", dp[2][30]);
//--------------------------
//Base case
if (n == 0 || W == 0)
return 0;
if (dp[n][W] != -1)
return dp[n][W];
if (wt[n-1] > W) {
dp[n][W] = DP_Recursive(W, wt, val, n - 1, dp);
return dp[n][W];
} else {
dp[n][W] = max(val[n-1] + DP_Recursive(W - wt[n-1], wt, val, n-1, dp),
DP_Recursive(W, wt, val, n-1, dp));
}
return dp[n][W];
}
There are multiple issues int the code:
[Major] The prototype for DP_recursive is incorrect: use int DP_Recursive(int W, int wt[], int val[], int n, static int dp[5][60]) in both the function declaration before the main() function (outside the body of main) and for the function definition itself.
[Minor] the arrays in main() do not need to be declared static.
[Major] the initialization loops run one step too far: for (int i = 0; i <= 5; i++) iterates 6 times with i ranging from 0 to 5 inclusive. You should use < instead of <= in both loops. As a rule of thumb, always check twice before using <=, and always prefer excluded upper bounds.
[Major] the inner initialization loop uses 50 instead of 60 as the upper bound, causing the array to be partially initialized and result incorrect (undefined behavior) instead of 110. It is better to use a countof macro to get the number of elements in an array.
[Minor] you should end the output with a newline (\n)
[Minor] main() should return 0 upon successful termination.
you did not post the definition of max, it is advisable to define it as a function.
the include file <stdio.h> is missing too.
Here is a modified version:
#include <stdio.h>
int DP_Recursive(int W, int wt[], int val[], int n, int dp[5][60]);
int max(int a, int b) {
return a < b ? b : a;
}
#define countof(a) (sizeof(a) / sizeof((a)[0])) // number of elements in an array
int main() {
int wt[5] = { 5, 10, 20, 30 };
int val[5] = { 50, 60, 100, 120 };
int dp[5][60]; //marker 2-D array
for (size_t i = 0; i < countof(dp); i++) {
for (size_t w = 0; w < countof(dp[i]); w++) {
dp[i][w] = -1;
}
}
printf("The total loot is %d$.\n", DP_Recursive(50, wt, val, 2, dp));
return 0;
}
//Recursive D.P. solution
int DP_Recursive(int W, int wt[], int val[], int n, int dp[5][60]) {
//-------**HIGHLIGHTED PART**-----------
printf("%d ", dp[2][30]);
//--------------------------
//Base case
if (n == 0 || W == 0)
return 0;
if (dp[n][W] != -1)
return dp[n][W];
if (wt[n-1] > W) {
dp[n][W] = DP_Recursive(W, wt, val, n - 1, dp);
return dp[n][W];
} else {
dp[n][W] = max(val[n-1] + DP_Recursive(W - wt[n-1], wt, val, n-1, dp),
DP_Recursive(W, wt, val, n-1, dp));
}
return dp[n][W];
}
Related
I have this one task. To make it more clear, I am gonna use picture below as an example. Input and output is separated with dotted line. First line of input is number N - number of sets. For every set, it's first line are 2 numbers - first one declares how many numbers am I gonna process and second one is number of intervals. Second line specifies the numbers to process and third line contains 2 numbers X and Y, which create and interval. For every interval I have to output 3 numbers - lowest number on interval, index of highest number on interval and XOR of all numbers. Everything is running fine except it is really slow for big data and I have no idea how to make work faster. I have attached my code and large data input as well.
input.txt
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int id;
int index;
} Censor;
int Xor(const int x, const int y, const Censor array[]) {
int xor = array[x].id;
if (x == y) {
return xor;
}
for (int i = x + 1; i <= y; i++) {
xor ^= array[i].id;
}
return xor;
}
int int_cmp(const void *a, const void *b) {
const Censor *ia = (const Censor *)a;
const Censor *ib = (const Censor *)b;
return (ia->id - ib->id);
}
int LowestId(const int x, const int y, Censor array[]) {
int id = array[x].id;
if (x == y) {
return id;
}
qsort(array, y - x + 1, sizeof(Censor), int_cmp);
return array[0].id;
}
int HighestIdIndex(const int x, const int y, Censor array[]) {
int index = array[x].index;
if (x == y) {
return index;
}
qsort(array, y - x + 1, sizeof(Censor), int_cmp);
return array[y].index;
}
int main() {
int t, n, q, b, e;
int max = 100;
int count = 0;
int *output = (int *)malloc(max * sizeof(output));
scanf("%d", &t); //number of sets
for (int i = 0; i < t; i++) {
scanf("%d %d", &n, &q);
//I am making 3 separate arrays for numbers, because some of them are being sorted and some of them not
Censor lowest_id[n];
Censor highest_id_index[n];
Censor xor[n];
//This loop fills arrays with the numbers to be processed
for (int j = 0; j < n; j++) {
scanf("%d", &(lowest_id[j].id));
lowest_id[j].index = j;
highest_id_index[j].id = lowest_id[j].id;
highest_id_index[j].index = j;
xor[j].id = lowest_id[j].id;
xor[j].index = j;
}
// Now I am scanning intervals and creating output. Output is being stored in one dynamically allocated array.
for (int k = 0; k < q; k++) {
scanf("%d %d", &b, &e);
if (count + 3 >= max) {
max *=2;
int *tmp = (int *)realloc(output, max * sizeof(tmp));
if (tmp == NULL) {
return 1;
} else {
output = tmp;
}
}
output[count++] = LowestId(b, e, lowest_id);
output[count++] = HighestIdIndex(b, e, highest_id_index);
output[count++] = Xor(b, e, xor);
}
}
printf("---------------------\n");
for (int i = 0; i < count; i++) {
printf("%d\n", output[i]);
}
free(output);
return 0;
}
Thanks #Dan MaĊĦek and #Alex Lop. Sorting subarray in this case was unnecessary. Much easier is to iterate through the subarray in linear complexity.
I want to find the number within a range in an array and must be in a recursive way. The function variables couldn't be modified.
Let's say in the range of 2 and 3
The input is : int a[] = {4, 1, 3, 1, 3, 2};
and the output will be = {3,3,2} , 3 found
Not sure how to code the recursive function in this case. The below I have tried not working.
int within(int a[], int N, int lower, int upper, int result[])
{
if(N == 1 && N <= upper && N>= lower)
return a[0];
return within(&a[1], N-1, lower, upper, result);
}
int main()
{
int a[] = {4, 1, 3, 1, 3, 2};
int result[6] = {0};
int i, nResult;
nResult = within(a, 6, 2, 3, result);
printf("%d data passed the bounds\n", nResult);
for (i = 0; i < nResult; i++){
printf("%d ", result[i]);
}
printf("\n");
return 0;
}
I want to find the number within a range in an array
Let's say in the range of 2 and 3
Normally a for loop or similar would be so much easier here
If it has to be recursive....
// need to have another number - r - number in range
// r starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int r, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[r]= a[0];
r++;
}
if(N==0) {
return r;
} else {
r = within(&a[1], N-1, lower, upper, r, result);
return r;
}
}
the function will give a return value of the number of values found within the range.
The code above is recursive, but so much more complicated and fragile than a simple loop... such as the fragment below
for (i=0;i<N;i++) {
if(a[i] <= upper && a[i]>= lower) {
result[r]= a[i];
r++;
}
}
If it has to be recursive wihtout r...
// need to have another number - result[0] - number in range
// result[0] starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[0]++;
result[result[0]]= a[0];
}
if(N==0) {
return result[0];
} else {
result[0] = within(&a[1], N-1, lower, upper, result);
return result[0];
}
}
now result conatins
{number in range, first number in range, second number in range....}
Something like this. If you want to implement a recursive function, try to do it in the way that the recursive call happens at the end.
#include <stdio.h>
int find_in_range(int* out, int const *in, int length, int from, int to)
{
if (length == 0)
{
return 0;
}
int addon;
if (*in >= from && *in <= to)
{
*out = *in;
++out;
addon = 1;
}
else
{
addon = 0;
}
return find_in_range(out, in + 1, length - 1, from, to) + addon;
}
#define N 6
int main()
{
int in[N] = {4, 1, 3, 1, 3, 2};
int out[N] = {0};
int num_found = find_in_range(out, in, N, 2, 3);
for (int i = 0; i < num_found; ++i)
{
printf("%d ", out[i]);
}
printf("\n");
return 0;
}
You can modify the following code as per your requirements. This is just a proof of concept code:
#include <stdio.h>
#include <stdlib.h>
static int result[4];
static int ctr1 = 0;
static int ctr2 = 0;
void recFind(int* arr, int* key){
if(ctr2 == 8)
return;
if(*arr >= key[0] && *arr <= key[1])
result[ctr1++] = *arr;
arr++;
ctr2++;
recFind(arr, key);
}
int main(){
int arr[] = {1,3,3,6,4,6,7,8};
int key[] = {1,4};
recFind(arr, key);
printf(" { ");
for(int i = 0; i < 4; i++){
printf("%d ", result[i]);
}
printf("}\n");
}
As it follows from the description of the assignment the function should provide two values: the number of elements that satisfy the condition and an array that contains the elements themselves.
It is evident that the array should be allocated dynamically. And it is logically consistent when the function itself returns the number of elements while the pointer to the generated array is passed by reference as an argument.
The recursive function can look the following way
#include <stdio.h>
#include <stdlib.h>
size_t get_range( const int a[], size_t n, int lower, int upper, int **out )
{
size_t m;
if ( n )
{
m = get_range( a, n - 1, lower, upper, out );
if ( lower <= a[n-1] && a[n-1] <= upper )
{
int *tmp = realloc( *out, ( m + 1 ) * sizeof( int ) );
if ( tmp )
{
tmp[m] = a[n-1];
*out = tmp;
++m;
}
}
}
else
{
*out = NULL;
m = 0;
}
return m;
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
int lower = 2, high = 3;
int *out;
size_t n = get_range( a, N, lower, high, &out );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", out[i] );
}
putchar( '\n' );
free( out );
return 0;
}
The program output is
2 3 3 2
Below codes will work for you in recursive way. If you don't want to print the numbers just comment out printf statement inside function printfRange. Hope you can understand the logic :-
int within(int *a, int rngH, int rngL, int length)
{
int len = length;
static int i = 0;
static int found = 0;
if(len <=0 )
{
return i;
}
if (*a == rngH)
{
printf("%d,",*a);
i++;
found = 1;
within(++a,rngH, rngL,--len);
}
else if(*a == rngL && found > 0)
{
printf("%d,",*a);
i++;
within(++a,rngH, rngL,--len);
}
else
{
within(++a,rngH, rngL,--len);
}
return i;
}
int main() {
int a[] = {4, 1, 3, 1, 3, 2};
int total = within(a,3,2,6);
printf("\n");
printf("Total :%d\n",total);
return 0;
}
i need to enter number of points(x,y), and then sort the points,from the closest one to (0,0) to the one that is far.. for example:
Enter number of points: 3
Enter point: 1 6
Enter point: 2 5
Enter point: 4 4
Sorted points:(2,5) (4,4) (1,6)
now i did a function that will find the distance,and i did an array and put the distance between two coordinate x and y,and i want to use merge sort to sort the array, my problem is how to go back and print the actual coordinate x y ... (i hope you would understand the problem),what can i do? i thought of putting the cordinate an array and sort them but that won't work :\
(and i didn't learn struct so i can't use unless if there is no other way ...)
plz anyone can help me i really have no idea have to continue:\
#include <stdio.h>
#include <stdlib.h>
void Enter_numbers(int x,int *z,int *first_coordinate,int *second_coordinate);
int distance(int a,int b);
void merge(int a[], int na, int b[], int nb, int c[]);
int merge_sort(int ar[], int n);
int main()
{
int x;
int *z;
int *first_coordinate;
int *second_coordinate;
printf("Enter number of points: ");
scanf("%d",&x);
z=(int*)malloc(x*sizeof(int));
first_coordinate=(int*)malloc(x*sizeof(int));
second_coordinate=(int*)malloc(x*sizeof(int));
Enter_numbers(x,z,first_coordinate,second_coordinate);
free(z);
free(first_coordinate);
free(second_coordinate);
return 0;
}
int distance(int a,int b)
{
int dis;
dis=((a*a)+(b*b));
return dis;
}
void Enter_numbers(int x,int *z,int *first_coordinate,int *second_coordinate)
{
int a=0,b=0;
int i=0;
int diss=0;
while(x>0)
{
printf("Enter points: ");
scanf("%d %d",&a,&b);
diss=distance(a,b);
z[i]=diss;
first_coordinate[i]=a;
second_coordinate[i]=b;
++i;
x--;
}
}
and the merge sort function i will use after i figure what to do :
int merge_sort(int ar[], int n)
{
int len;
int *temp_array, *base;
temp_array = (int*)malloc(sizeof(int)*n);
if(temp_array == NULL) {
printf("Dynamic Allocation Error in merge_sort");
return FAILURE;
}
for (len = 1; len < n; len *= 2) {
for (base = ar; base < ar + n; base += 2 * len) {
merge(base, len, base + len, len, temp_array);
memcpy(base, temp_array, 2*len*sizeof(int));
}
}
free(temp_array);
return SUCCESS;
}
and here is merge ...
void merge(int a[], int na, int b[], int nb, int c[])
{
int ia, ib, ic;
for(ia = ib = ic = 0; (ia < na) && (ib < nb); ic++)
{
if(a[ia] < b[ib]) {
c[ic] = a[ia];
ia++;
}
else {
c[ic] = b[ib];
ib++;
}
}
for(;ia < na; ia++, ic++) c[ic] = a[ia];
for(;ib < nb; ib++, ic++) c[ic] = b[ib];
}
I would use a struct for solving this task.
If you haven't learned struct yet, this seems to be a good time to learn it.
Note: If you really can't use stuct, see the last part of the answer.
With struct it could be something like:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int x;
int y;
int squared_distance;
} dpoint;
int squared_dst(int x, int y)
{
return (x*x + y*y);
}
// Compare function used for sorting
int compare_dpoint_dst(const void * e1, const void * e2)
{
dpoint* p1 = (dpoint*)e1;
dpoint* p2 = (dpoint*)e2;
if (p1->squared_distance > p2->squared_distance) return 1;
if (p1->squared_distance < p2->squared_distance) return -1;
return 0;
}
void print_dpoint(dpoint dp)
{
printf("(%d, %d) : sd = %d\n", dp.x, dp.y, dp.squared_distance);
}
#define N 5
int main(void) {
// Array of points (fixed size for simplicity)
dpoint ps[N];
// Dummy input (for simplicity)
int x[N] = {1,5,2,3,4};
int y[N] = {9,3,7,1,3};
for (int i = 0; i < N; ++i)
{
ps[i].x = x[i];
ps[i].y = y[i];
}
// Calculate squared distance for all points
for (int i = 0; i < N; ++i)
{
ps[i].squared_distance = squared_dst(ps[i].x, ps[i].y);
}
printf("unsorted:\n");
for (int i = 0; i < N; ++i)
{
print_dpoint(ps[i]);
}
// Sort the points
qsort (ps, sizeof(ps)/sizeof(*ps), sizeof(*ps), compare_dpoint_dst);
printf("sorted:\n");
for (int i = 0; i < N; ++i)
{
print_dpoint(ps[i]);
}
return 0;
}
Notice that you can do the sorting on the squared distance so that you don't need square root in the program.
The program above will generate:
unsorted:
(1, 9) : sd = 82
(5, 3) : sd = 34
(2, 7) : sd = 53
(3, 1) : sd = 10
(4, 3) : sd = 25
sorted:
(3, 1) : sd = 10
(4, 3) : sd = 25
(5, 3) : sd = 34
(2, 7) : sd = 53
(1, 9) : sd = 82
No use of struct
If you for some reason can't use struct, you can use a shadow array to track the sorting but you'll have to write your own sorting. I don't recommend this approach - learn about structinstead. Anyway, it could be something like:
int x[N];
int y[N];
int sd[N]; // squared distance
int sw[N]; // swap order
// read input and calculate distance
// ...
// Fill sw with 0, 1, 2, ....
for (int i=0; i < N; ++i) sw[i] = i;
mySort(sd, sw, N);
// Now you can use sw for printing
for (int i=0; i < N; ++i)
{
// print element sw[i]
printf("(%d,%d)\n", x[sw[i]], y[sw[i]]);
}
}
void mySort(int sd[], int sw[], int N)
{
// .... code for sorting
// ....
// Assume that you need to swap element i and j here
temp = sd[i];
sd[i] = sd[j];
sd[j] = temp;
// Then do exactly the same for sw
temp = sw[i];
sw[i] = sw[j];
sw[j] = temp;
// ....
// ....
}
I want to find the max number in array by recursion,
What wrong with this code.
#include<stdio.h>
int find_max(int *a,int n){
int m_max;
if(n==1){
return a[0];
}
m_max=find_max(a,n-1);
if(a[n-1]>m_max)
m_max=a[n-1];
}
As #moffeltje comments, "There isn't a return when n != 1"
if(a[n-1]>m_max)
m_max=a[n-1];
return m_max; // add
}
This linear approach gives recursion a bad name. If there are n numbers, the maximum recursive depth is n. Much better to divide in 2 for a max depth of log2(n)
int find_max(const int *a, int n) {
if (n <= 1) {
return a[0];
}
int left = find_max(a, n/2);
int right = find_max(&a[n/2], n - n/2);
return left > right ? left : right;
}
--- Minor stuff follows
Cope with corner cases where n < 1 or a == NULL.
int find_max(const int *a, int n) {
if (n <= 1 || a == NULL) {
if (n <= 0 || a == NULL) return INT_MIN; // or throw error
return a[0];
}
...
Changing int find_max(int *a, int n) --> int find_max(const int *a, int n) allows constant arrays to be passed also.
Array sizes are best typed as size_t rather than int.
int find_max(const int *a, size_t n) {
...
}
#include<stdio.h>
int find_max(int *a,int n){
int m_max;
if(n==1){
return a[0];
}
m_max=find_max(a,n-1);
if(a[n-1]>m_max)
m_max=a[n-1];
return m_max;
}
you have not returned anything when n!=1.
Look when designing these things you should always check the -
The base case. Here in this case it is achieved when n=1.(one element left and it is the largest one)
The recursive case. Here you will use the computed values to smaller cases and now you will build the solution thinking that the previous cases are calcualted already.
Combine Combine the calculate results. The last if condition that you have provided. But you forgot to put a return that is not giving the result to one stage to others. That's where there is this problem.
Alternatively, you could simplify the function.
int max_array_val( int* a_Array, int a_Size )
{
int max = a_Array[ 0 ];
for( int i = 1; i < a_Size; i++ )
if( a_Array[ i ] > max )
max = a_Array[ i ];
return max;
}
int main()
{
int int_array[ 6 ] = { 3, 2, 6, 5, 5, 2 };
printf( "Maximum number is: %i\n\n", max_array_val( int_array, sizeof( int_array ) / sizeof( int ) ) );
system( "pause" );
return 0;
}
int getMax(int const * arr, int size) {
if (size == 1)
return *arr;
int ans = getMax(arr + 1, size - 1);
return *arr > ans ? *arr : ans;
}
I am learning C and came over the topic of sorting. I wrote a comp() function in and used qsort to sort an array of int. Now for the next task I need to remove the duplicates from the array.
Is it possible to sort and remove duplicates at the same time?
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int indexes[10] = { 0, 98, 45, 65, 45, 98, 78, 56, 65, 45 };
int comp(const void * elem1, const void * elem2) {
int f = *((int*) elem1);
int s = *((int*) elem2);
if (f > s) {
return 1;
}
if (f < s) {
return -1;
}
return 0;
}
void printIndexArray() {
int i = 0;
for (i = 0; i < 10; i++) {
printf("i is %d\n", indexes[i]);
}
}
int main() {
qsort(indexes, sizeof(indexes) / sizeof(int), sizeof(int), comp);
printIndexArray();
return 0;
}
Since your numbers are already sorted, removing dupes is easy. In C++, it's even built in as std::unique:
http://en.cppreference.com/w/cpp/algorithm/unique
Assuming you want to do it yourself, you can do it the same way unique does it:
int* unique (int* first, int* last)
{
if (first==last) return last;
int* result = first;
while (++first != last)
{
if (!(*result == *first))
*(++result)=*first;
}
return ++result;
}
Yes
This can be achieved by mergesort. If both left and right are the same just merge the one value
That's the code that removes the duplicates using mergesort. This snippet of code does the removing work:
else if(a[p1] == a[p2])
{
merged[p] = a[p1];
p1++;
p2++;
}
That's the iterative merge sort while the recursive version would be easier.
#include <stdio.h>
#include <stdlib.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
int indexes[10] = { 0, 98, 45, 65, 45, 98, 78, 56, 65, 45 };
void merge(int *a, int s, int m, int e)
{
int p1 = s;
int p2 = m + 1;
int * merged = (int*)malloc(sizeof(int) * (e - s + 1));
int p = 0;
while(p1 < m + 1 && p2 < e + 1)
{
if(a[p1] > a[p2])
{
merged[p] = a[p2];
p2++;
}
else if(a[p1] == a[p2])
{
merged[p] = a[p1];
p1++;
p2++;
}
else
{
merged[p] = a[p1];
p1++;
}
p++;
}
while(p1 < m + 1)
{
merged[p++] = a[p1++];
}
while(p2 < e + 1)
merged[p++] = a[p2++];
int i;
for(i = 0;i < (e -s+1); i++)
{
a[s + i] = merged[i];
}
free(merged);
}
void merge_sort(int *a, int n)
{
int width;
for(width = 1; width < n; width = 2 * width)
{
int i;
for(i = 0; i < n; i = i + 2 * width)
{
merge(a, i, min(i + width - 1, n - 1), min(i + 2 * width - 1, n - 1) );
}
}
}
void printIndexArray()
{
int i = 0;
for(i = 0; i < 10; i++)
{
printf("i is %d\n", indexes[i]);
}
}
int main()
{
merge_sort(indexes, sizeof(indexes) / sizeof(int) );
printIndexArray();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int indexes[10] = { 0, 98, 45, 65, 45, 98, 78, 56, 65, 45 };
size_t undup(int array[], size_t len)
{
size_t src,dst;
if (!len) return 0;
for (src=dst=1; src < len; src++) {
if (array[dst-1] == array[src]) continue;
array[dst++] = array[src];
}
return dst;
}
int comp(const void * elem1, const void * elem2) {
int f = *((int*) elem1);
int s = *((int*) elem2);
if (f > s) return 1;
if (f < s) return -1;
return 0;
}
void printIndexArray(size_t len) {
size_t i = 0;
for (i = 0; i < len; i++) {
printf("array[%zu] is %d\n", i, indexes[i]);
}
}
int main() {
size_t len = 10;
printf("Before sort\n" );
printIndexArray(len);
qsort(indexes, sizeof indexes / sizeof indexes[0], sizeof indexes[0], comp);
printf("After sort\n" );
printIndexArray(len);
len = undup(indexes,10);
printf("After undup\n" );
printIndexArray(len);
return 0;
}
The short answer is: yes.
The long answer is: it is always possible, but the complexity to do it depends heavily on the algorithm you use.
The more complex algorithms like quick-sort, slow-sort, bucket-sort, and straight-radix-sort do not lend themselves to such an enhancement, because they rely on the data being in a consecutive array, that can implicitly be split into subarrays. So, when you detect a duplicate, you cannot easily take it out. Again, it is possible, but certainly not a problem for beginners.
The less complex in-place algorithms like bubble-sort, insertion-sort, and shell-sort make it relatively easy: you can just replace one of the duplicates you detect with a sentinel value that sorts greater than all legal values, and let it rise to the top. After that, you just need to scoop off the cream of sentinel values and you are done.
The algorithms that really lend themselves to removing duplicates, are the ones that use intermediate arrays that grow/shrink in the process; in these cases you can just shrink or skip growing one of these intermediate arrays when you detect a duplicate. Candidates are merge-sort and heap-sort.
Note, however, that it is more prudent to just sort the array, and eliminate duplicates in a second, separate step. Why? Because eliminating duplicates adds complexity to the inner loop of the sorting algorithm, which is of O(n*log(n)) in most relevant cases. But eliminating duplicates from a sorted array is an O(n) operation, making the split operation faster than the fused one.