Как «удалить» каждый элемент в массиве по значению в C - PullRequest
0 голосов
/ 26 ноября 2018

Я пытался решить эту проблему около 5 дней. Не могу найти решение, пожалуйста, пришлите помощь.Я должен реализовать функцию «удаления» каждого элемента в массиве по значению.Допустим, мой массив "Hello", и я хочу удалить все "l".Пока я могу удалить только один раз.Кстати, имейте в виду, мне не разрешают использовать указатели для этой функции ... (мы еще не изучали это в моей школе) Вот мой код:

#include <stdio.h>
#include <string.h>

void strdel(char array[], char c);

int main(void)
{
    char source[40];
    printf("\nStrdel test: ");
    strcpy(source, "Hello");
    printf("\nsource = %s", source);
    strdel(source, 'l');
    printf("\nStrdel: new source = %s", source);
    return 0;
}

void strdel(char array[], char c)
{
    int string_lenght;
    int i;
    for (string_lenght = 0; array[string_lenght] != '\0'; string_lenght++) {} 

    for (i = 0; i < string_lenght; i++) {
        if (array[i] == c) {
            for (i = i; array[i] != '\0'; ++i)
                array[i] = array[i + 1];
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Простое использование 2 индексов, один для чтения и один для записи. @ Carl Norum

void strdel(char array[], char c) {
  int read_index = 0;
  int write_index = 0;
  while (array[read_index] != '\0') {
    if (array[read_index] != c) {
      array[write_index] = array[read_index];
      write_index++;  // Only advance write_index when a character is copied
    }
    read_index++;     // Always advance read_index
  }
  array[write_index] = '\0';
}

Имеет производительность O (n), намного быстрее, чем использование вложенных циклов for(), что составляет O (n * n).


Подробности:

OP: Кстати, помните, мне не разрешено использовать указатели для этой функции.

Обратите внимание, что array in void strdel(char array[], char c) - указатель, даже если он может выглядеть как массив.

int для индексации массива - это нормально для ученика и большого количества кода, но лучше использовать size_t.int может не хватать необходимого диапазона.Тип size_t - это тип без знака, который не является ни слишком узким, ни слишком широким для индексации массива.Это становится важным для очень длинных строк .

0 голосов
/ 26 ноября 2018

Ваша проблема связана с использованием переменной i в обоих циклах.Поэтому, как только внутренний цикл будет выполнен, внешний цикл завершится сразу после.

Используйте другую переменную для внутреннего цикла.

void strdel(char array[], char c)
{
    int string_lenght;
    int i, j;
    for (string_lenght = 0; array[string_lenght] != '\0'; string_lenght++) {} 

    for (i = 0; i < string_lenght; i++) {
        if (array[i] == c) {
            for (j = i; array[j] != '\0'; ++j)  // Use variable j instead of i
                array[j] = array[j + 1];

           --i;              // Decrement i to "stay" at the same index
           --string_lenght;  // As one character were just removed
        }
    }
}

Выше показано, как заставить подход OP работать.Для лучшего решения смотрите ответ от @chux: https://stackoverflow.com/a/53487767/4386427

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...