Рекурсивная функция для переворота строки

Напишите рекурсивную версию функции реверс (ы), который переворачивает строку s на месте.

Я изучаю K&R и написал код для вопроса.

void reverse(char s[], int n)   // The seconde argument should be always 1.
{               // The function should be always called as reverse(s, 1);
    int temp;
    int len;

    len = strlen(s);
    if ((len + 1) / 2 > n)
        reverse(s, n + 1);
    
    temp = s[n-1];
    s[n-1] = s[(len - 1) - (n-1)];
    s[(len - 1) - (n-1)] = temp;
}

Второй аргумент n говорит, что reverse () в настоящее время вызывается n раз. Функция работает так, как будто она устанавливает ось симметрии на s[(strlen(s) + 1) / 2](поскольку целочисленное деление усекается, оно не всегда симметрично по оси, но функция ведет себя так, как будто усечения не происходит, и это точно симметричная ось) и соответственно изменить s[n - 1] с s[(strlen(s) - 1) - (n - 1)] наоборот. Функция прекращает свой рекурсивный вызов, когда индекс оси больше n.

Я видел другие решения (это и это). Я думаю, что они использовали отличную идею для вопроса. Но мне интересно, что вы думаете о моем. Спасибо за чтение!

1 ответ
1

Если честно, это плохой способ решить проблему — рекурсия с strlen() не лучшая идея. Недавно было обнаружено, что у Rockstar Games экраны загрузки в GTA5 были увеличены на несколько минут из-за вызова парсера JSON. strlen() на строке несколько раз.

Вместо этого при рекурсивной обработке строк, требующей знания длины строки, эту длину следует передавать вместе с указателем.

Что касается длины, вы сохраняете длину строки в переменной с типом int а не size_t который strlen() возвращается. С этим есть две проблемы — первая заключается в том, что int подписан и size_t беззнаковый, а второй заключается в том, что size_t часто больше, чем int, особенно с современными 64-битными системами, определяющими первые как uint64_t и последний как int32_t.

Наконец, вы можете избежать больших умственных затрат, используя вместо этого два указателя — один на начало строки и один на конец строки. Затем вы остановите рекурсию, когда начало уже не до конца.

  • Спасибо за объяснение с множеством информативных причин и даже с реальной проблемой. Кстати, я не понимаю ваш второй абзац. one should pass that length alongside the pointer. Вы имели в виду, что я должен использовать strlen() только один раз перед вызовом рекурсивной функции и вставить это возвращаемое значение в фактический параметр?

    — на ол


  • 1

    Звучит правильно.

    — user30482

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *