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

ф-ция реверса строки - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 33, средняя оценка - 4.94
igor001
8 / 3 / 1
Регистрация: 12.02.2013
Сообщений: 68
14.05.2013, 10:51     ф-ция реверса строки #1
был вчера на собеседовании, попросили написать ф-цию реверса строки (поменять местами 1й и последний символы, 2й и предпоследний и т.д.), но ф-ция должна принимать параметром указатель на char т.е. на начало строки и все. я там немного тупанул но написал, вот хочу узнать есть ли решение получше моего.
вот код (писал в Embarcadero RAD Studio (Borland)):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//ф-ция принимает указатель на массив char с символом окончания строки '\0'
//и производит реверс полученного массива
void TForm1::reverce(char *str)
{
    char* end_str = &str[0];
 
    while (*end_str != '\0') ++end_str;
    
    char  buf;
    while (end_str > str)
    {
        --end_str;
        buf      = *str;
        *str     = *end_str;
        *end_str = buf;
        ++str;  
    }
}
кто захочет проверить, выносим кнопку, лабел и эдит на форму и в ивент на клик кнопки пишем:
C++
1
2
3
4
5
AnsiString str = Edit1->Text.c_str();
 
    reverce(str.c_str());
 
    Label1->Caption = str;
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.05.2013, 10:51     ф-ция реверса строки
Посмотрите здесь:

Функция реверса строки C++
C++ Операторная ф-ция
C++ Глобальная ф-ция getline
C++ Какая ф-ция в VC++ определяет длину строки???
C++ ф-ция с throw
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
14.05.2013, 14:47     ф-ция реверса строки #21
Цитата Сообщение от igor001 Посмотреть сообщение
C++
1
while (--end_str > str)
на пустой строке - неопределённое поведение
сравниваемые указатели должны указывать на элементы одного массива
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
igor001
8 / 3 / 1
Регистрация: 12.02.2013
Сообщений: 68
14.05.2013, 15:51  [ТС]     ф-ция реверса строки #22
Цитата Сообщение от ninja2 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void revers(char* str)
{
    string s1;
    string s2;
    string result;
    int i(0);
    for(;i<strlen(str)/2;i++)
        s1+=str[i];
    for(;i<strlen(str);i++)
        s2+=str[i];
    for(i=s2.size()-1;i>=0;i--)
        result+=s2[i];
    //cout <<"result= "<<result<<endl;
    for(i=s1.size()-1;i>=0;i--)
        result+=s1[i];
 
    strcpy(str,result.c_str());
}
}

ты хоть проверял этот код? запускал его? ты осознаешь что в нем много лишних и бесполезных действий, понимаешь что минимум один цикл и строка явно лишние??? ты понимаешь что вопрос стоял о улучшении написанной мною ф-ции а не о преобразовании мотоцикла в инвалидное кресло?
1. уже говорилось о том что нельзя использовать какие-либо ф-ции
2. зачем тебе s1?... блин да ну на... я даже не буду пытаться это разбирать.

Добавлено через 8 минут
Цитата Сообщение от accept Посмотреть сообщение
на пустой строке - неопределённое поведение
сравниваемые указатели должны указывать на элементы одного массива
вполне определенное, проверял, прога пашет, ошибок не выдает. строка или массив это последовательный контейнер, т.е. элементы в памяти размещены последовательно, при сравнении указателей, в случае пустой строки, указатель end_str указывает на область памяти перед 1м эл-том соответственно в цикл прога не заходит. хотя незнаю что будет если указатель str будет изначально указывать на 0ю область памяти... мб вылетит ошибка во время операции --end_str
vxg
Модератор
 Аватар для vxg
2660 / 1671 / 156
Регистрация: 13.01.2012
Сообщений: 6,219
14.05.2013, 15:54     ф-ция реверса строки #23
Цитата Сообщение от igor001 Посмотреть сообщение
мб вылетит ошибка во время операции
не вылетит. вы ведь не разыменовываете указатель
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
14.05.2013, 15:58     ф-ция реверса строки #24
igor001, можно Ваш код ещё ужать
C++
1
2
3
4
5
6
7
8
9
10
11
12
void reverse(char *str)
{
    char* end_str = str;
    while (*++end_str);
    
    while (--end_str > str)
    {
       register char  buf  = *str;
       *str++   = *end_str;
       *end_str = buf;
    }
}
vxg
Модератор
 Аватар для vxg
2660 / 1671 / 156
Регистрация: 13.01.2012
Сообщений: 6,219
14.05.2013, 16:00     ф-ция реверса строки #25
Цитата Сообщение от Tulosba Посмотреть сообщение
while (*++end_str);
вот эта штука может глюкнуть на нулевой строке (выйдет за пределы и получит доступ к памяти)
igor001
8 / 3 / 1
Регистрация: 12.02.2013
Сообщений: 68
14.05.2013, 16:07  [ТС]     ф-ция реверса строки #26
Цитата Сообщение от Tulosba Посмотреть сообщение
igor001, можно Ваш код ещё ужать
C++
1
2
3
4
5
6
7
8
9
10
11
12
void reverse(char *str)
{
    char* end_str = str;
    while (*++end_str);
    
    while (--end_str > str)
    {
       register char  buf  = *str;
       *str++   = *end_str;
       *end_str = buf;
    }
}
действительно, не думал что цикл while (*++end_str); "поймет" когда остановиться, читал Страуструпа, там было что-то подобное, только для ф-ции копирования, кажется было приблизительно так while (*out++ = *in++);
но на счет переноса обьявления переменной в цикл не соглашусь, ведь т.к. она локальная, не будет ли она после каждой итерации уничтожаться?

Добавлено через 2 минуты
Цитата Сообщение от vxg Посмотреть сообщение
вот эта штука может глюкнуть на нулевой строке (выйдет за пределы и получит доступ к памяти)
только что проверил, вродь норм
vxg
Модератор
 Аватар для vxg
2660 / 1671 / 156
Регистрация: 13.01.2012
Сообщений: 6,219
14.05.2013, 16:12     ф-ция реверса строки #27
Цитата Сообщение от igor001 Посмотреть сообщение
не будет ли она после каждой итерации уничтожаться
будет, но это же не объект. накладных расходов не будет.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
14.05.2013, 16:13     ф-ция реверса строки #28
Цитата Сообщение от vxg Посмотреть сообщение
вот эта штука может глюкнуть на нулевой строке (выйдет за пределы и получит доступ к памяти)
давайте добавим тогда в самое начало:
C++
1
if( !*str ) return;
Только не говорите мне, что надо ещё и на 0 сам указатель проверить
vxg
Модератор
 Аватар для vxg
2660 / 1671 / 156
Регистрация: 13.01.2012
Сообщений: 6,219
14.05.2013, 16:14     ф-ция реверса строки #29
Цитата Сообщение от igor001 Посмотреть сообщение
только что проверил, вродь норм
вы не правы. я собрал в билдере с включенным кодгвардом он сказал доступ к участку за пределами. в рантайме конечно это не приводит к жесткой ошибке но зачем оно надо то? фактически вы начинаете проверку со второго символа. а если там не ноль оно так и побежит...

Добавлено через 40 секунд
Цитата Сообщение от Tulosba Посмотреть сообщение
на 0
имеется ввиду не s = 0 а s = ""
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
14.05.2013, 16:15     ф-ция реверса строки #30
Цитата Сообщение от igor001 Посмотреть сообщение
не будет ли она после каждой итерации уничтожаться?
т.к. это обычная POD-переменная на стеке - ничего злобного не случится.
vxg
Модератор
 Аватар для vxg
2660 / 1671 / 156
Регистрация: 13.01.2012
Сообщений: 6,219
14.05.2013, 16:16     ф-ция реверса строки #31
подставьте вот это и увидите в дебаге что первый символ который проверяет эта функция в строке 1234 будет равен 2
C++
1
2
3
4
5
    while (true)
    {
        char c = *++end_str;
        if (!c) break;
    }
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
14.05.2013, 16:18     ф-ция реверса строки #32
Цитата Сообщение от vxg Посмотреть сообщение
имеется ввиду не s = 0 а s = ""
Я понял. Поэтому и предложил вариант, который предложил, и сказал про нулевой указатель.
При нулевом указателе еще одно условие добавить придется:
C++
1
if( !str || !*str ) return;
igor001
8 / 3 / 1
Регистрация: 12.02.2013
Сообщений: 68
14.05.2013, 16:19  [ТС]     ф-ция реверса строки #33
Цитата Сообщение от Tulosba Посмотреть сообщение
т.к. это обычная POD-переменная на стеке - ничего злобного не случится.
так будет она уничтожаться после каждой итерации или нет. если да, то получается если в строке 100 символов, то 100 раз будет выделена и освобождена память для этой переменной, что не есть хорошо.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
14.05.2013, 16:21     ф-ция реверса строки #34
Цитата Сообщение от igor001 Посмотреть сообщение
так будет она уничтожаться после каждой итерации или нет.
Что такое стек Вы понимаете? А что такое POD-тип? Накладных расходов не будет.
vxg
Модератор
 Аватар для vxg
2660 / 1671 / 156
Регистрация: 13.01.2012
Сообщений: 6,219
14.05.2013, 16:22     ф-ция реверса строки #35
Цитата Сообщение от Tulosba Посмотреть сообщение
Поэтому и предложил вариант
на мой взгляд проверять со второго символа все равно как-то противоестественно если можно сделать одну из ваших проверок просто частью штатного цикла.
Цитата Сообщение от igor001 Посмотреть сообщение
то 100 раз будет выделена и освобождена память для этой переменной
она не будет выделяться так как вы это представляете. программа просто будет захватывать часть стека 100 раз. это совершенно не накладно. "захватывать" это просто слово. программа просто будет знать что в стеке лежит ваше число.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
14.05.2013, 16:24     ф-ция реверса строки #36
Цитата Сообщение от igor001 Посмотреть сообщение
не будет ли она после каждой итерации уничтожаться?
нет она указывает на адрес ячейки которую нельзя уничтожить. Можно токо с помощью delete убить.
igor001
8 / 3 / 1
Регистрация: 12.02.2013
Сообщений: 68
14.05.2013, 16:25  [ТС]     ф-ция реверса строки #37
Цитата Сообщение от vxg Посмотреть сообщение
на мой взгляд проверять со второго символа все равно как-то противоестественно если можно сделать одну из ваших проверок просто частью штатного цикла.

она не будет выделяться так как вы это представляете. программа просто будет захватывать часть стека 100 раз. это совершенно не накладно. "захватывать" это просто слово. программа просто будет знать что в стеке лежит ваше число.
ясн, спс за разъяснение. получается простые типы данных типо int, char в цикле обьявлять не накладно в отличии от объектов
vxg
Модератор
 Аватар для vxg
2660 / 1671 / 156
Регистрация: 13.01.2012
Сообщений: 6,219
14.05.2013, 16:26     ф-ция реверса строки #38
да. в некоторых случаях я и объекты не брезгую в цикл засовывать
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
14.05.2013, 16:26     ф-ция реверса строки #39
Цитата Сообщение от ninja2 Посмотреть сообщение
Можно токо с помощью delete убить.
Вызывать delete для переменных на стеке нельзя.

Добавлено через 15 секунд
Цитата Сообщение от vxg Посмотреть сообщение
на мой взгляд проверять со второго символа все равно как-то противоестественно если можно сделать одну из ваших проверок просто частью штатного цикла.
согласен.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.05.2013, 16:35     ф-ция реверса строки
Еще ссылки по теме:

C++ ф-ция
C++ Рандомная ф-ция rand()
C++ Параметризованная ф-ция класса

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

Или воспользуйтесь поиском по форуму:
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
14.05.2013, 16:35     ф-ция реверса строки #40
Цитата Сообщение от Tulosba Посмотреть сообщение
Вызывать delete для переменных на стеке нельзя.
А с начала стека можно?

А чо нельзя ошибка будет? Или оно половину удалит, а половину оставит?
Yandex
Объявления
14.05.2013, 16:35     ф-ция реверса строки
Ответ Создать тему
Опции темы

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