Форум программистов, компьютерный форум CyberForum.ru

Реверсирование строк - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 27, средняя оценка - 4.67
Golovastik
 Аватар для Golovastik
11 / 11 / 0
Регистрация: 25.05.2009
Сообщений: 435
08.09.2009, 00:08     Реверсирование строк #1
Всем добрый вечер! Как всегда, практикуюсь по книжным примерам. Вот дошёл до темы реверсирования строк, то есть расположения букв в обратном порядке. Столкнулся с таким кодом, и не ясен стал цикл,то есть как именно происходит замена букв в нём?
Если кто может, подскажите,если не сложно? Не ясен сам цикл, и строка перед ним: end = &str[len-1];
Заранее благодарю.

Вот исходник:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;
 
int main() 
{
setlocale(0, "" ); 
char str[] = "Россия - щедрая душа";
char *start, *end;
int len;
char t;
 
cout<<"Исходная строка: "<<str<<'\n';
len = strlen(str);
start = str;
end = &str[len-1];
while(start < end)
{
    t = *start;
    *start = *end;
    *end = t;
    start++;
    end--;
}
cout<<"Результат после реверсирования: \n"<<str;
 
cin.get();
return 0;
 
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.09.2009, 00:08     Реверсирование строк
Посмотрите здесь:

C++ Реверсирование
C++ Найти количество строк в максимальном множестве попарно непохожих строк заданной матрицы
C++ По некоторому количеству строк (не более N) найти пары строк с общим словом
C++ Реверсирование строк
C++ Ввод нескольких строк или массив строк
Написать программу, использующую стандартную функцию сравнения строк для определения среди трех строк, вводимых пользователем, одинаковых. C++
C++ Определить номера тех строк целочисленной матрицы A[N,K], которые совпадают с массивом D[K], если таких строк нет - выдать соответствующее сообщение
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
08.09.2009, 00:14     Реверсирование строк #2
все довольно просто -
C++
1
end = &str[len-1];
- указатель на конец строки (адрес последнего символа)
C++
1
2
3
4
5
6
7
8
while(start < end) //пока символы не пересеклись
{
        t = *start; //в направление вперед - символ в t
        *start = *end; // в символ с начала - символ с конца
        *end = t; //в конечный - с начала
        start++; //сдвигаем указатель начала вперед
        end--;//указатель на конец назад
}
M128K145
Эксперт C++
 Аватар для M128K145
8276 / 3495 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
08.09.2009, 00:24     Реверсирование строк #3
Хм... Мне кажется, что это не самый лучший учебник(ну или пример в частности). Вот
мой вариант
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
int main() 
{
    setlocale(LC_ALL, "Russian"); 
    char str[] = "Россия - щедрая душа";
    std::cout<<"Исходная строка: "<<str<<'\n';
 
    size_t len = strlen(str);
    for(unsigned short i = 0; i < len/2; ++i)
        str[i] ^= str[len - i - 1] ^= str[i] ^= str[len - i - 1];
    std::cout<<"Результат после реверсирования: \n"<<str<<'\n';
 
    system("pause");
    return 0;
}
, он намного проще. Все вышесказанное действительно, если тема - это не работа с указателями.

C++
1
2
3
4
5
6
7
8
9
10
end = &str[len-1];//запись в end - последнего символа строки
while(start < end) // пока старт меньше конца(читай пока не середина строки)
{
        t = *start; //сохраняем в буфер левый символ
        *start = *end; //записываем в левый символ правый символ
        *end = t; //в правый символ записываем содержимое буфера
// ну как обычный пузырек
        start++; // и просто смещаем указатель слева на один символ вправо
        end--; // и справа на один символ влево
}
Gravity
 Аватар для Gravity
556 / 550 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
08.09.2009, 00:45     Реверсирование строк #4
Наверное, автора смущает то, что к элементам строки обращаются по адресам. Думаю, с обычной индексацией было бы понятнее.

Добавлено через 18 минут
Собстно, вот:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <cstring>
int main()
{
    char str[] = "Goodbye, cruel world. I'm leaving you today", tmp;
    int i, j;
 
    std::cout << "Исходная строка: " << str << std::endl;
    for(i = 0, j = strlen(str)-1; i < j; i++, j--) {
        tmp = str[i];
        str[i] = str[j];
        str[j] = tmp;
    }
    std::cout << "Результат после реверсирования: " << str << std::endl;
    std::cin.get();
    return 0;
}
Monte-Cristo
 Аватар для Monte-Cristo
2807 / 1372 / 30
Регистрация: 07.03.2009
Сообщений: 4,446
08.09.2009, 01:01     Реверсирование строк #5
Цитата Сообщение от M128K145 Посмотреть сообщение
str[i] ^= str[len - i - 1] ^= str[i] ^= str[len - i - 1];
Ууу... я понимаю, что минимализм - это хорошо. Но через дополнительную перменную будет и быстрее и проще.. да и ТС будет понятней.
ISergey
Maniac
Эксперт С++
 Аватар для ISergey
1345 / 878 / 51
Регистрация: 02.01.2009
Сообщений: 2,642
Записей в блоге: 1
08.09.2009, 01:16     Реверсирование строк #6
проще так:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <algorithm>
 
int main(){
 
    char str[] = "string";
    std::reverse(str, str + strlen(str));
    std::cout << str << std::endl;
    return 0;
}
mirso
524 / 342 / 17
Регистрация: 05.04.2009
Сообщений: 709
08.09.2009, 01:46     Реверсирование строк #7
Цитата Сообщение от Monte-Cristo Посмотреть сообщение
Но через дополнительную перменную будет и быстрее и проще..
Цитата Сообщение от ISergey Посмотреть сообщение
проще так
или так
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
int main()
{
char str[] = "reverse";
size_t i = 0;
        
  while( str[i] ) std::cout << str[strlen(str) - ++i];         
       
return 0;
}
ISergey
Maniac
Эксперт С++
 Аватар для ISergey
1345 / 878 / 51
Регистрация: 02.01.2009
Сообщений: 2,642
Записей в блоге: 1
08.09.2009, 02:07     Реверсирование строк #8
mirso, э не.. исходная строка у вас не меняется..
Golovastik
 Аватар для Golovastik
11 / 11 / 0
Регистрация: 25.05.2009
Сообщений: 435
08.09.2009, 20:12  [ТС]     Реверсирование строк #9
Что-то я не могу понять вот эту строку:
C++
1
while(start < end)
Ведь смотрите, строка Россия - щедрая душа, занимает 20 символов+нулевой символ окончания = 21.
Теперь происходит такое условие: "Пока 21(тоесть start) < 20(end)".
Как может 21 быть меньше 20,ведь тогда цикл прекратится сразу.
Как это понимать?
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9382 / 5432 / 916
Регистрация: 25.07.2009
Сообщений: 10,428
08.09.2009, 20:28     Реверсирование строк #10
Цитата Сообщение от Golovastik Посмотреть сообщение
Что-то я не могу понять вот эту строку:
C++
1
while(start < end)
Ведь смотрите, строка Россия - щедрая душа, занимает 20 символов+нулевой символ окончания = 21.
Теперь происходит такое условие: "Пока 21(тоесть start) < 20(end)".
Как может 21 быть меньше 20,ведь тогда цикл прекратится сразу.
Как это понимать?
1. strlen возвращает длинну строки без завершающего нуля.
2.
C
1
2
3
4
char *s = "Россия - щедрая душа";
char *start = s; /* то же, что start = &s[0]; то есть Р*/
char *end = s + strlen(s) - 1; /* тоже, что end = &s[strlen(s) - 1];  */
/* *start == 'P'; *end == 'a'; */
а дальше - пока указатель на начало меньше указателя на конец строки, поменять местами то, на что они указывают, start увеличить, end уменьшить, то есть на втором проходе start указывает на второй символ, end - на предпоследний...
M128K145
Эксперт C++
 Аватар для M128K145
8276 / 3495 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
08.09.2009, 20:46     Реверсирование строк #11
Golovastik, грубо говоря происходит следующее(сразу скажу что и start, и end проходят всего половину строки)

Р|о|с|с|и|я| |-| |щ|е|д|р|а|я| |д|у|ш|а
s|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|e
*|s|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|e|*
*|*|s|*|*|*|*|*|*|*|*|*|*|*|*|*|*|e|*|*
*|*|*|s|*|*|*|*|*|*|*|*|*|*|*|*|e|*|*|*
*|*|*|*|s|*|*|*|*|*|*|*|*|*|*|e|*|*|*|*
*|*|*|*|*|s|*|*|*|*|*|*|*|*|e|*|*|*|*|*
*|*|*|*|*|*|s|*|*|*|*|*|*|e|*|*|*|*|*|*
*|*|*|*|*|*|*|s|*|*|*|*|e|*|*|*|*|*|*|*
*|*|*|*|*|*|*|*|s|*|*|e|*|*|*|*|*|*|*|*
*|*|*|*|*|*|*|*|*|s|e|*|*|*|*|*|*|*|*|*
где положение s - start, а e - end на каждой итерации
Golovastik
 Аватар для Golovastik
11 / 11 / 0
Регистрация: 25.05.2009
Сообщений: 435
08.09.2009, 22:32  [ТС]     Реверсирование строк #12
Наконец-то прояснилось. Последний вопрос.
Скажите, почему так:
C++
1
2
3
4
    
t = *start;
*start = *end;
*end = t;
А не так:
C++
1
2
3
t = &(*start);
*start = *end;
*end = &t;
Добавлено через 21 минуту
Можно ли написать просто так:
C++
1
2
3
4
5
6
7
8
9
while(start < end)
{
    
    *start = *end;
    *end = start;
    
    start++;
    end--;
}
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9382 / 5432 / 916
Регистрация: 25.07.2009
Сообщений: 10,428
08.09.2009, 22:32     Реверсирование строк #13
Цитата Сообщение от Golovastik Посмотреть сообщение
Наконец-то прояснилось. Последний вопрос.
Скажите, почему так:
C++
1
2
3
4
    
t = *start;
*start = *end;
*end = t;
А не так:
C++
1
2
3
t = &(*start);
*start = *end;
*end = &t;
t - переменная типа char, а start и end - указатели на переменную типа char. Унарный оператор * - разыменовывание указателя. Суть в следующем: временной переменной t присваивается значение, взятое по адресу start, после чего это значение меняется на то, на которое указывает end, в свою очередь значение, находящиеся по адресу end меняется на значение переменной t. Выражение &(*start) читалось бы примерно так: адрес того, на что указывает start. То есть масло масленное
M128K145
Эксперт C++
 Аватар для M128K145
8276 / 3495 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
08.09.2009, 22:43     Реверсирование строк #14
&(*start) эквивалентен start и содержит в себе указатель на всю строку.
*start - содержит в себе указатель на конкретный элемент. Чтобы убедится в этом я всегда советую прибегать к практике, в данном случае к печати. Вот подставь этот код
C++
1
2
3
4
5
6
7
8
9
    while(start < end)
    {
        cout<<start<<'\n'<<*start<<'\n';
        t = *start;
        *start = *end;
        *end = t;
        start++;
        end--;
    }
и посмотри как он отработает. Сразу станет все ясно
mirso
524 / 342 / 17
Регистрация: 05.04.2009
Сообщений: 709
08.09.2009, 23:33     Реверсирование строк #15
Цитата Сообщение от ISergey Посмотреть сообщение
mirso, э не.. исходная строка у вас не меняется..
пнял. испрафлюсь.

Golovastik, методов реверсии много
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
 
int main()
{
std::string s = "abracadabra";
size_t i = 1;
    
      std::cout << s << std::endl;
    // - a b r a c a d a b r a -   
  while ( s[i] ) 
  {
    s.insert( 0, 1, s[i] );
    s.erase ( ++i, 1 ); 
  } // - a r b a d a c a r b a -  
      std::cout << s << std::endl;    
 
system( "pause" );       
return 0;
}
Golovastik
 Аватар для Golovastik
11 / 11 / 0
Регистрация: 25.05.2009
Сообщений: 435
08.09.2009, 23:55  [ТС]     Реверсирование строк #16
А это, это что-то новенькое, не растолкуете что это делается:

C++
1
2
 s.insert( 0, 1, s[i] );
 s.erase ( ++i, 1 );
mirso
524 / 342 / 17
Регистрация: 05.04.2009
Сообщений: 709
09.09.2009, 00:01     Реверсирование строк #17
Golovastik,
Цитата Сообщение от Golovastik Посмотреть сообщение
что это
ты и сам можешь посмотреть
C++
1
2
3
4
5
6
7
  while ( s[i] ) 
  {
    s.insert( 0, 1, s[i] );
    std::cout << s << std::endl;
    s.erase ( ++i, 1 ); 
    std::cout << s << std::endl << std::endl; 
  }
вставка и удаление

что бы лучше заметить разницу сделай так(вставь пробел)
C++
1
std::string s = " abracadabra";
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.12.2009, 18:12     Реверсирование строк
Еще ссылки по теме:

Используя функцию копирования строк, организуйте конкатенацію и копирование строк в четвертый массив, содержащий полные имена C++
Запросить название учебного заведения, специальность и номер группы. записав их в массив из 3 строк. Подсчитать длины каждой строк C++
C++ Вводится массив строк текста с неизвестным заранее количеством строк
Программа для поиска соответствие строк, учитывая регистр, в текстовом файле с 10000+ строк C++
C++ Упорядочить по росту сумм элементов строк строки той матрицы, у которой больше нулевых строк

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
^Tecktonik_KiLLeR
 Аватар для ^Tecktonik_KiLLeR
1144 / 426 / 19
Регистрация: 23.06.2009
Сообщений: 6,147
Завершенные тесты: 1
12.12.2009, 18:12     Реверсирование строк #18
Цитата Сообщение от mirso Посмотреть сообщение
int main()
{
char str[] = "reverse";
size_t i = 0;
while( str[i] ) std::cout << str[strlen(str) - ++i];
return 0;
}
как переделать что бы функция возвращала?

Добавлено через 9 минут
усё решено!
Yandex
Объявления
12.12.2009, 18:12     Реверсирование строк
Ответ Создать тему
Опции темы

Текущее время: 22:36. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru