Как эта функция reverse () работает в приведенном ниже коде? - PullRequest
0 голосов
/ 24 июня 2019

Я нашел этот код в Интернете, который переворачивает строки в Си с помощью указателей. Я понимаю большинство из них, но я не понимаю функцию reverse(): почему она использует length / 2?

Если я изменил условие во втором цикле for на length в функции reverse(), он также отобразит тот же результат.

// function to reverse the string s which is an array of some size
void reverse(char *s) {
    int length, c;
    char *begin = NULL, *end = NULL, temp;

    length = string_length(s);
    begin = s;
    end = s;

    for (c = 0; c < length - 1; c++)
        end++;

    for (c = 0; c < length / 2; c++) {
        temp = *end;
        *end = *begin;
        *begin = temp;

        begin++;
        end--;
    }
}

int string_length(char *pointer) {
    int c = 0;

    while (*(pointer + c) != '\0')
        c++;

    return c;
}

Ответы [ 3 ]

2 голосов
/ 24 июня 2019

Давайте используем простое сравнение:

  • у вас есть шар в каждой руке, скажем черный в правой руке и белый в левой руке.
  • если выпоменяйте шары один раз, вы фактически полностью изменили ситуацию.
  • но если вы поменяете шары дважды, вы вернетесь в исходное положение.
  • следовательно, число свопов должно быть вдвое меньшеиз шаров.

То же самое касается букв в строке, если вы выполните length перестановки, вы получите исходную строку.Чтобы получить обратную строку, вы должны остановиться на половине длины строки.

Обратите также внимание, что код более сложный, чем требуется.Вот упрощенная версия:

// function to reverse the string s which is an array of some size
void reverse(char *s) {
    char *begin, *end;

    for (end = begin = s; *end; end++)
        continue;

    while (begin < end) {
        char temp = *begin;
        *begin++ = *--end;
        *end = temp;
    }
}
0 голосов
/ 24 июня 2019

Потому что, когда c равно 0, вы поменяете местами элементы в s[0] и s[length-1]. Когда c равно 1, вы поменяете местами элементы на s[1] и s[length-2] и так далее. Если бы вы использовали length вместо length/2, вы бы перевернули строку и затем вернули ее обратно к оригиналу.

0 голосов
/ 24 июня 2019

Посмотрите, что делается в цикле:

temp = *end;
*end = *begin;
*begin = temp;

Это типичный код подкачки, который здесь меняет два символа *begin и *end строки. Указатели перебирают начало и конец строки и приближаются к середине.

Используя минимальный пример abcd, давайте посмотрим, сколько символов нам нужно поменять местами:

abcd (Original string)
dbca (Swapped 'a' and 'd') - iteration 1
dcba (Swapped 'b' and 'c') - finished after 2 iterations

Таким образом, вам нужно поменять местами только половину символов (length / 2 итераций), поскольку вы меняете два из них при каждой операции. Это также объясняет, почему вы получаете исходную строку при изменении на length - 1 итераций:

dcba (result from above after 2 iterations)
dbca (Swapped 'c' and 'b') - iteration 3
abcd (Swapped 'd' and 'a') - original string after 4 iterations
...