Удаление символа и перемещение его в строку - PullRequest
0 голосов
/ 02 февраля 2019

Мне нужны идеи для рекурсивного кода, который удаляет конкретный символ в строке и объединяет все остальные строковые символы

Например:

"погода пасмурная"

введенный символ 'e':

результат:

"th wathr облачно"

Я действительно понятия не имею, как начать, спасибо за помощь.

Ответы [ 7 ]

0 голосов
/ 02 февраля 2019

Моя очередь сделать предложение!Я добавляю тест assert и использую существующие функции (strchr и strcpy).

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

int removeChar(char *str, char chr)
{
    assert(str != 0);                   // Always control entry !
    char *str_pnt = strchr(str, chr);   

    if (str_pnt) {
        strcpy(str_pnt, str_pnt+1); 
        removeChar(str_pnt, chr);
    }
}

void main (void)
{
    char str[] = "the weather is cloudy";
    char char_to_delete = 'e';

    removeChar(str, char_to_delete);
    puts(str);
}
0 голосов
/ 02 февраля 2019

#include <stdio.h>

/**
* Returns the number of removed chars.
* Base case: if the current char is the null char (end of the string)
* If the char should be deleted return 1 + no of chars removed in the remaining string.
* If it's a some other char simply return the number of chars removed in the remaining string
*/
int  removeCAfterwardsAndCount(char* s,char c){
  if((*s) == '\0'){
      return 0;
  }

  if((*s) == c){
     int noOfChars = removeCAfterwardsAndCount(s+1,c);// s+1 means the remaining string
      s[noOfChars] = *s; // move the current char (*s) noOfChars locations ahead

    return  noOfChars +1; // means this char is removed... some other char should be copied here...

  }
  else{
      int noOfChars  = removeCAfterwardsAndCount(s+1,c);
      s[noOfChars ] = *s;
    return  noOfChars ; // means this char is intact ... 
  }

}

int main()
{

    char s[] = "Arifullah Jan";
    printf("\n%s",s);
    int totalRemoved = removeCAfterwardsAndCount(s,'a');
    char *newS = &s[totalRemoved]; // the start of the string should now be originalPointer + total Number of chars removed

    printf("\n%s",newS);

    return 0;
}

Тестовый код здесь

Чтобы избежать перемещения символов с помощью петель.Я просто перемещаю символы вперед, что создает пустое пространство в начале строки.Указатель newS - это просто новый указатель той же строки, чтобы исключить пустую строку / строку мусора.

0 голосов
/ 02 февраля 2019
#include <stdio.h>
#include <string.h>

char *remove_char(char *str, int c)
{
    char *pos;
    char *wrk = str;
    while((pos = strchr(wrk, c)))
    {
        strcpy(pos, pos + 1);
        wrk = pos;
    }
    return str;
}

int main()
{
    char str[] = "Hello World";
    printf(remove_char(str, 'l'));

    return 0;
}

Или более быстрая, но трудная для понимания версия:

char *remove_char(char *str, int c)
{
    char *pos = str;
    char *wrk = str;
    while(*wrk)
    {
        if(*wrk == c)
        {
            *wrk++;
            continue;
        }
        *pos++ = *wrk++;
    }
    *pos = 0;
    return str;
}

Оба требуют, чтобы строка была доступна для записи (поэтому вы не можете передать указатель на строковый литерал, например)

0 голосов
/ 02 февраля 2019
#include <stdio.h>

void remove_impl(char* s, char c, char* d) {
    if (*s != c) {
        *d++ = *s;
    }
    if (*s != '\0') {
        remove_impl(++s, c, d);
    }
}

void remove(char* s, char c) {
    remove_impl(s, c, s);
}

int main() {
    char s[] = "the weather is cloudy";
    remove(s, 'e');
    puts(s);
}

Как это работает?Рассмотрим remove_impl.s - исходная строка, c - символ, который нужно удалить из s, d - результирующая строка, в которую записаны символы s, не равные c.Рекурсивно перебирает символы s.Если следующий символ не равен c, то он записывается в d.Точка остановки рекурсии - это условие проверки достижения конца s.Поскольку необходимо изменить исходную строку, реализована оболочка (remove), в которой в качестве d передается исходная строка (s).

0 голосов
/ 02 февраля 2019

Простой способ сделать это - перебрать строку и добавить любую букву, которая не соответствует нежелательной.

Вот демонстрация:

char *source = "the weather is cloudy";
int source_len = strlen(source);

char *target = (char *)calloc(source_len, sizeof(char));
int target_len = 0;

char to_remove = 'e';

for(int i = 0; i < source_len; i++)
{
    if(source[i] != to_remove)
    {
        target[target_len++] = source[i];
    }
}

puts(target); // Output "th wathr is cloudy" in the console
0 голосов
/ 02 февраля 2019
#include <stdio.h>

void RemoveChar(char* str, char chr) {
char *str_old = str;
char *str_new = str;

while (*str_old)
{
    *str_new = *str_old++;
    str_new += (*str_new != chr);
}

*str_new = '\0'; }

int main() {
char string[] = "the weather is cloudy";

RemoveChar(string, 'e');

printf("'%s'\n", string);

return 0; }
0 голосов
/ 02 февраля 2019

Это можно сделать разными способами.То, о чем я сейчас думаю, это массив not Allowed char, который будет фильтровать, какой символ должен отображаться или нет.Примерно так:

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

// Global Scope variable declaration
int notAllowedChar[128] = {0}; // 0 for allowed , 1 for not allowed
char inputString[100];


void recursion(int pos, int len) {

    if( pos >= len ) {
       printf("\n"); // new line
       return;
    }

    if( notAllowedChar[inputString[pos]]) {// not printing
       recursion( pos + 1 , len );
    }
    else {
       printf("%c", inputString[pos]);
       recursion( pos + 1 , len );
    }

}

int main() {

 gets(inputString);  // taking input String

    printf("Enter not allowed chars:: "); // here we can even run a loop for all of them
    char notAllowed;
    scanf("%c", &notAllowed);
    notAllowedChar[notAllowed] = 1;
    int len = strlen(inputString);
    recursion( 0 , len );

}

Как это работает

Допустим, у нас есть простая строка «Hello world», и мы хотим, чтобы l был удален из финальной строки, поэтому итоговый результат будет«Heo word»

Здесь длина «Hello world» составляет 11 символов перед вызовом функции рекурсии, поэтому мы проверяем индекс 'l', который составляет 108 значений ascii link 1 в массиве notAllowedChar.

теперь мы вызываем метод рекурсии со значением (0, 11), в методе рекурсии мы имеем в основном 2 логических операции if, первая для base case, где мы завершаем наш рекурсивный вызов, когда pos равноили больше 11. и если это не так, мы выполним вторую логическую операцию, если current char для печати или нет.Это просто проверка, где этот символ находится в списке notAllowedChar или нет.Каждый раз, когда мы увеличиваем pos value + 1 и выполняем рекурсивный вызов, и, наконец, когда pos равно или больше 11, это означает, что мы приняли все наше решение о печати char или нет, наша рекурсия прекратится.Я попытался назначить переменную со значимым именем.Если вы до сих пор не понимаете, как эта работа, вам следует использовать простую базовую симуляцию рекурсии (поиск в YouTube), а также попробовать вручную отладить изменение значения в recursion local scope.Это может занять время, но это будет достойно понимания.Все самое лучшее.

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