Удаление всех символов строки s1, встречающихся в s2 - C (СИ)
Формулировка задачи:
Здравствуйте! Пытаюсь решить задание из книги Кернигана и Ричи "Язык программирования Си".
Задание звучит так: "Напишите альтернативную версию ф-ции squeeze(s1,s2), которая бы удаляла из строки s1 все символы, встречающиеся в строке s2". Судя по контексту, речь идёт о массивах (а не о строковых константах)
Вот, что я написал:
Проблема в том, что если ввести во вторую строку более одного символа, то символ конца строки проглатывается, и в результирующем массиве оказываются
// Упражнение 2.4. Напишите squeeze(s1,s2), которая бы удаляла из строки s1 все символы, встречающиеся в строке s2. #include <stdio.h> #define STR_LIM 75 // макс. длина строки void squeeze(char s1[], char s2[]); void getline(char arr[], int str_length); int main() { char arr1[STR_LIM], arr2[STR_LIM]; printf("\n Программа удаляет из строки №1 все символы, содержащиеся в строке №2.\n"); printf("\n Введите строку№1...\n:>"); getline(arr1, STR_LIM); // получаем первую строку printf("\n Теперь введите строку№2...\n:>"); getline(arr2, STR_LIM); // получаем вторую строку // Подытоживая собранные данные... printf("\nВы ввели:%s и захотели удалить из неё символы: %s\n", arr1, arr2); squeeze(arr1, arr2); // Вывод результата printf("Получилась строка: %s\n", arr1); return 0; } //getline(arr[], limit): Получает из входного потока строку недлинее limit и сохраняет её в массиве-аргументе arr[] void getline(char arr[], int lim) { int x, i; i = 0; while ((x = getchar()) != '\n' && i < lim-2) arr[i++] = x; arr[i] = '\0'; } //squeeze(s1,s2): Удаляет из строки s1 все символы. встречающиеся в строке s2. void squeeze(char s1[], char s2[]) { int i, m, n; for (i = 0; s2[i] !='\0'; i++) // перебираем нежелательные символы из 2й строки for(m = n = 0; s1[m] != '\0'; m++) if (s1[m] != s2[i] && s1[m] != '\0') s1[n++] = s1[m]; s1[n] = '\0'; }
лишние символы
. Допустим, если ввести в 1ю строку "12345ggggg6789" и во вторую "gg", то получим "1234567896789
". Никак не могу сообразить, как с этим справиться, не разводя писанину... Если не трудно - подскажите плз!p.s.:
в задании говорилось про "альтернативную" версию. Так вот, в изначальной версии squeeze имела в качестве второго (удаляемого) аргумента простой символ. Можно сказать, что тело функции почти не изменилось, только обрело 1 лишнуюю переменную и внешний цикл, перебирающий все символы строки s2, которые не должны оставаться в s1. В связи с этим я думаю, что может надо было вообще по-другому подходить к решению?
Решение задачи: «Удаление всех символов строки s1, встречающихся в s2»
textual
Листинг программы
#include <stdio.h> //функция удаляет из строки 1 все символы, которые есть в строке 2 void squeeze(char s1[], char s2[]) { int i, j, k, sovp; for(i=k=0; s1[i]!='\0'; i++) { sovp = 0; for(j=0; s2[j]!='\0'; j++) { if(s1[i]==s2[j]) sovp = 1; } if(!sovp) //если совпадений не было s1[k++] = s1[i]; } s1[k] = '\0'; } int main() { char line1[] = "12345ggggg6789", line2[] = "gg"; squeeze(line1, line2); printf("%s", line1); return 0; }
Объяснение кода листинга программы
- Включаем файл стандартного ввода/вывода
- Функция squeeze принимает два аргумента типа char: s1 и s2.
- Внутри функции объявляем четыре переменные: i, j, k и sovp.
- Переменная i используется для индексации строки s1, а переменная j - для индексации строки s2.
- Переменная k используется для индексации результирующей строки s1.
- Переменная sovp используется для проверки, был ли найден символ из строки s2 в строке s1.
- Используя два вложенных цикла, проходим по каждому символу строки s1.
- Для каждого символа проверяем, есть ли такой же символ в строке s2.
- Если символ найден, то переменной sovp присваивается значение 1.
- Если после прохода по всем символам строки s2 символ не был найден, то он добавляется в результирующую строку s1.
- После прохода по всем символам строки s1 добавляется символ '\0' для завершения строки.
- В функции main создаем две строки: line1 и line2.
- Строка line1 содержит
12345ggggg6789
, а строка line2 содержитgg
. - Вызываем функцию squeeze, передавая ей строку line1 и строку line2.
- После выполнения функции squeeze выводим на экран результат, используя функцию printf.
- Результатом будет строка
123456789
, так как все вхождения символаg
были удалены из строки line1. - Возвращаем 0, чтобы указать, что программа успешно завершилась.
- Если бы в функции main мы передали другие строки, например,
abracadabra
иab
, то результатом было быaracadabra
, так как все вхождения символаab
были удалены из исходной строки.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д