Usuwanie elementu tablicy w C


Napisałem następujący program, aby usunąć element tablicy wprowadzony przez użytkownika.
#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();
}

Działa dobrze dla większości danych wejściowych, ale gdy dane wejściowe wyglądają mniej więcej tak:
1 2 2 3 5
(tutaj
2
jest powtarzane sekwencyjnie), a usuwany element to
2
, exit-
1 2 3 5
.
Jak mogę zmienić program tak, aby wszystkie wystąpienia wstawionego elementu zostały usunięte?
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Po tym, jak wstawiłem i-zbyt jak poniżej
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
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Inne plakaty dały ci 2 rozwiązania ... myślę, że zrozumienie, dlaczego tak się dzieje, też jest dobre :)
Weźmy Twój przykład
1, 2, 2, 3, 5
i postępuj zgodnie z kodem linia po linii
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 */
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli nie zależy Ci na kolejności elementów w tablicy, możesz przenieść ostatni element tablicy do nowo utworzonej luki (sprytnie zmniejszając długość tablicy o jeden). Może to być znacznie bardziej wydajne niż przetaczanie elementów: w terminologii informatycznej oznacza to, że usunięcie elementu to O (1), a nie O (N).
a[i] = a[--l];

Jeśli twój indeks i zapętla tablicę, będziesz chciał jeszcze raz zapętlić ten element:
a[i--] = a[--l];

Na przykład, aby usunąć wszystkie elementy „3” z tablicy o długości „l”:
for (i = 0; i < l; ++i) {
if (a[i] == 3) {
a[i--] = a[--l];
}
}

Jeśli ty

naprawdę

dbać o kolejność elementów w tablicy, najbardziej efektywne jest użycie memmove niż ręczne przesuwanie elementów. Jest przeznaczony do użytku w przypadku nakładania się pamięci źródłowej i docelowej.
memmove(a + i, a + i + 1, sizeof(a[0]) * (l - i - 1));
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Zmień „jeśli” na „podczas”:

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
}
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

użyj nowej tablicy.
int array[l];
int k=0;
for(i=0;i<l;i++)
{
if(a[i]!=key)
{
array[k]=a[i];
k++;
}}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

#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;
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Twoja metoda z 2 zagnieżdżonymi pętlami
for
jest zbyt skomplikowana. Możesz po prostu zeskanować tablicę w indeksie
i
i skopiować wszystkie elementy inne niż
key
z innym indeksem
len
. Wynikowa długość tablicy to końcowa wartość
len
.
Oto zmodyfikowana wersja:
#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;
}

Wpisy:
  • Prototypem
    main
    bez argumentów jest
    int main (void)
    i uważane jest za dobry styl zwracania
    0
    dla sukcesu.
  • zawsze sprawdzaj zwracaną wartość
    scanf ()
    . Zapobiega to wielu błędom i niezdefiniowanym zachowaniom w przypadku nieprawidłowych danych wejściowych. Oszczędza również dużo czasu na szukaniu w niewłaściwych miejscach, gdy dane wejściowe były po prostu nieprawidłowe.
  • unikaj nazywania zmiennej
    l
    , ponieważ wygląda ona zbyt blisko
    1
    w wielu czcionkach o stałej szerokości.
  • zawsze kończy wyjście programu nową linią.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się