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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 27, средняя оценка - 4.67
Golovastik
11 / 11 / 0
Регистрация: 25.05.2009
Сообщений: 435
#1

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

08.09.2009, 00:08. Просмотров 3561. Ответов 17
Метки нет (Все метки)

Всем добрый вечер! Как всегда, практикуюсь по книжным примерам. Вот дошёл до темы реверсирования строк, то есть расположения букв в обратном порядке. Столкнулся с таким кодом, и не ясен стал цикл,то есть как именно происходит замена букв в нём?
Если кто может, подскажите,если не сложно? Не ясен сам цикл, и строка перед ним: 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;
 
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.09.2009, 00:08
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Реверсирование строк (C++):

Реверсирование строк - C++
Нужно отсортировать строки по алфавиту и вывести в файл реверсированные строки. #include &quot;stdafx.h&quot; #include &lt;fstream&gt; #include...

Реверсирование - C++
Помогите пожалуйста! Задача Реверсировать число и увеличить его в 2 раза.

Самая длинная общая подпоследовательность строк/ НОП строк (Динамическое программирование) - C++
Доброго времени суток. Помогите пожалуйста разобраться с алгоритмом НОП строк. Суть алгоритма. Необходимо найти самую длительную...

По некоторому количеству строк (не более N) найти пары строк с общим словом - C++
По некоторому количеству строк (не более N) найти пары строк с общим словом. помогите, пожалуйста. слишком быстро перескочили и со...

Вводится массив строк текста с неизвестным заранее количеством строк - C++
1)Вводится массив строк текста с неизвестным заранее количеством строк.Ввод текста заканчивается, если введенная строка текста будет равна...

Реализовать функцию перемещения строк, принимающую в качестве параметров два вектора строк - C++
Подскажите насколько правильно решена задача. условие: Напишите функцию MoveStrings, которая принимает два вектора строк, source и...

17
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
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--;//указатель на конец назад
}
1
M128K145
Эксперт С++
8289 / 3509 / 143
Регистрация: 03.07.2009
Сообщений: 10,706
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--; // и справа на один символ влево
}
1
Gravity
562 / 556 / 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;
}
1
Monte-Cristo
2789 / 1375 / 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];
Ууу... я понимаю, что минимализм - это хорошо. Но через дополнительную перменную будет и быстрее и проще.. да и ТС будет понятней.
0
ISergey
Maniac
Эксперт С++
1375 / 886 / 52
Регистрация: 02.01.2009
Сообщений: 2,661
Записей в блоге: 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;
}
1
mirso
525 / 343 / 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;
}
1
ISergey
Maniac
Эксперт С++
1375 / 886 / 52
Регистрация: 02.01.2009
Сообщений: 2,661
Записей в блоге: 1
08.09.2009, 02:07 #8
mirso, э не.. исходная строка у вас не меняется..
0
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,ведь тогда цикл прекратится сразу.
Как это понимать?
0
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,778
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 - на предпоследний...
0
M128K145
Эксперт С++
8289 / 3509 / 143
Регистрация: 03.07.2009
Сообщений: 10,706
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 на каждой итерации
1
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--;
}
0
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,778
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. То есть масло масленное
0
M128K145
Эксперт С++
8289 / 3509 / 143
Регистрация: 03.07.2009
Сообщений: 10,706
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--;
    }
и посмотри как он отработает. Сразу станет все ясно
0
mirso
525 / 343 / 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;
}
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.09.2009, 23:33
Привет! Вот еще темы с ответами:

Найти количество строк в максимальном множестве попарно непохожих строк заданной матрицы - C++
Мир всем, помогите понять суть задания: &quot;Две строки матрицы назовем похожими, если совпадают множества чисел встречающихся в этих...

Программа для поиска соответствие строк, учитывая регистр, в текстовом файле с 10000+ строк - C++
Уважаемые форумчане, прошу у вас помощи я неделю в поисках. Мне нужна программа или код для поиска слов, очень похожую на расширение Pearls...

Найти сумму всех чётных строк матрицы и отсортировать элементы нечётных строк по возрастанию - C++
1.Задана матрица целых чисел.Найти сумму всех четных строк матрицы и отсортировать элементы не четных строк по возрастанию.

Перестановка строк матрицы по возрастанию среднего значения строк - C++
Разработать программу для перестановки строк матрицы таким образом, чтобы средние значения по строкам возрастали от первой строки к...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
08.09.2009, 23:33
Ответ Создать тему
Опции темы

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