Reputation: 408
I wrote the following program to delete an array element entered by the user.
#include <stdio.h>
#include <conio.h>
void main() {
int j, i, a[100], n, key, l;
clrscr();
printf("Enter the number of elements:");
scanf("%d", &n);
printf("\nEnter the elements:\n");
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
printf("\nEnter the element to delete:");
scanf("%d", &key);
l = n; //Length of the array
for (i = 0; i < l; i++) {
if (a[i] == key) {
for (j = i; j < l; j++)
a[j] = a[j + 1];
l--; //Decreasing the length of the array
}
}
printf("\nThe new array is \n");
for (i = 0; i < l; i++)
printf("%d ", a[i]);
getch();
}
It works fine for most inputs but when the input is something like: 1 2 2 3 5
(here 2
repeats consecutively) and the element to be deleted is 2
, the output is 1 2 3 5
.
How can I modify the program such that all instances of the entered element is removed?
Upvotes: 5
Views: 36278
Reputation: 145307
Your method with 2 nested for
loops is too complicated. You can simple scan the array with an index i
and copy all elements different from key
with a different index len
. The resulting array length is the final value of len
.
Here is a modified version:
#include <stdio.h>
#include <conio.h>
int main(void) {
int a[100];
int i, n, key, len;
clrscr();
printf("Enter the number of elements: ");
if (scanf("%d", &n) != 1) {
printf("invalid input\n");
return 1;
}
if (n < 0 || n > 100) {
printf("invalid number of elements\n");
return 1;
}
printf("\nEnter the elements:\n");
for (i = 0; i < n; i++) {
if (scanf("%d", &a[i]) != 1) {
printf("invalid input\n");
return 1;
}
}
printf("\nEnter the element to delete: ");
if (scanf("%d", &key) != 1) {
printf("invalid input\n");
return 1;
}
for (i = len = 0; i < n; i++) {
if (a[i] != key)
a[len++] = a[i];
}
printf("\nThe new array is:\n");
for (i = 0; i < len; i++)
printf("%d ", a[i]);
printf("\n");
getch();
return 0;
}
Notes:
The prototype for main
without arguments is int main(void)
and it is considered good style to return 0
for success.
always test the return value of scanf()
. This prevents many bugs and undefined behavior for invalid input. It also saves a lot of time looking in the wrong places when input was just invalid.
avoid naming a variable l
as it looks too close to 1
in many fixed pitch fonts.
always terminate the program output with a newline.
Upvotes: 0
Reputation: 1
#include<stdio.h>
int main(){
int size;
int array[20];
int delete_pos;
int i;
printf("Enter the Size of the Array :");
scanf("%d",&size);
for(i=0;i<=size-1;i++){ //no of elements taken are 1 less than size of the array asked.
printf("\nEnter the element[%d] :",i+1);
scanf("%d",&array[i]);
}
printf("\nEnter the Position of the array to be deleted :");
scanf("%d",&delete_pos);
for(i=delete_pos-1;i<=size;i++){ //every element of the array is replaced by array on next position.
array[i]=array[i+1];}
size=size-1; // Reducing the size of the array as one element is deleted.
printf("Your new array is \n");
for(i=0;i<=size-1;i++){ //printing the entire new array.
printf("%d ",array[i]);
}
printf("\n\n");
return 0;
}
Upvotes: 0
Reputation: 1686
use a new array.
int array[l];
int k=0;
for(i=0;i<l;i++)
{
if(a[i]!=key)
{
array[k]=a[i];
k++;
}
}
Upvotes: 0
Reputation: 16449
Change "if" to "while":
for(i=0;i<l;i++) { while (i<l && a[i]==key) { for(j=i;j<l;j++) a[j]=a[j+1]; l--; //Decreasing the length of the array } }
Upvotes: 1
Reputation:
If you don't care about the order of the elements in the array, you can move the last element of the array into the newly formed gap (cunningly reducing the length of the array by one). This can be vastly more efficient than shunting the elements down: in computer science term this makes deleting an element O(1) rather than O(N).
a[i] = a[--l];
If your i index is looping over the array, you'll want to loop over this element again:
a[i--] = a[--l];
For example, to remove all elements '3' from an array of length 'l':
for (i = 0; i < l; ++i) {
if (a[i] == 3) {
a[i--] = a[--l];
}
}
If you do care about the order of the elements in the array, it's most efficient to use memmove rather than move elements by hand. It's designed to be used where the source and destination memory overlap.
memmove(a + i, a + i + 1, sizeof(a[0]) * (l - i - 1));
Upvotes: 3
Reputation: 108986
Other posters have given you 2 solutions ... I think understanding why it happens is good too :)
Let's take your example 1, 2, 2, 3, 5
and follow the code line by line
i = 0; /* first time through the loop; i "points" to 1 */
if (a[i] == 2) ... /* nope; next loop */
i = 1;
if (a[1] == 2) ... /* yes! let's go inside the if */
/* move all elements back
** and "decrease" array length */
/* array is now 1, 2, 3, 5 */
/* next loop */
i = 2;
if (a[i] == 2) ... /* nope; OH! Wait ...
** a[1] is the new 2 and it wasn't checked */
Upvotes: 2
Reputation: 6287
After l-- put i-- too as shown below
if(a[i]==key)
{
for(j=i;j<l;j++)
a[j]=a[j+1];
l--; //Decreasing the length of the array
i--; //check again from same index i
}
Upvotes: 5