powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибки в функции реверса каждого слова строки
25 сообщений из 151, страница 2 из 7
Ошибки в функции реверса каждого слова строки
    #38564557
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stutИдем по символах строки до пробела/конца. Если находим маркируем как n и меняем предыдущие символы в обратном порядке. Потом маркируем начало след. Слова m=n+1, и находим следующий пробел (n=i) и меням местами буквы
Алгоритм правильный. ОК.

Смотрим код:
stut
Код: plaintext
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.
30.
31.
#include <iostream>
#include <string.h>
using namespace std;

char *reverse (char *line)
{
    int n, m=0;
    int l=strlen(line);

    for (int i=0; i<l; i++) 
    {
        if ((char)line[i]==' ' || (char)line[i]=='\0')
        {
            n=i;
            int d=(n-1);
            for (int j=m; j<(n-m-1)/2; j++) 
            {
                line[j++]=line[d--];
            }
            m=n+1;
        }
    }

    return line;
}

int main()
{
  cout << reverse ("Hello world hello world")<< endl;
  return 0;
}



---уже даже так переделал и ничего не помагает там d-переменная была лишняя и надо было другую итерационную- j

Какой физический смысл у значения (n-m-1)/2 ? Половина длины слова (примерно, см. ниже).
А m и n - начало и конец слова относительно начала всей строки.
Т.е. у вас j содержит смещение от начала всей строки, а условие окончания цикла сравнивает его с длиной слова j<(n-m-1)/2. Сравнивать нужно также со смещением от начала строки, что-то вроде этого:
Код: plaintext
1.
for (int j=m; j < m + (n-m-1)/2; j++) 



Теперь по поводу половины длины слова.
Т.к. m - начало слова, m - последний символ слова, то длина слова = n - m + 1. Соответственно половина = (n - m + 1)/2, а не (n - m - 1)/2
Т.е. цикл будет такой:
Код: plaintext
1.
for (int j=m; j < m + (n - m + 1)/2; j++) 



Как поправите эти ошибки - возвращайтесь.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564564
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для для слов с нечётным числом букв средня буква остаётся на месте. Всё просто.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564597
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stut
Код: plaintext
1.
2.
3.
4.
            for (int j=m; j<(n-m-1)/2; j++) 
            {
                line[j++]=line[d--];
            }



1. j увеличивается на 2 за один проход. Вот как у тебя происходит
Код: plaintext
1.
2.
3.
4.
5.
6.
            for (int j=m; j<(n-m-1)/2; j = j + 1) 
            {
                line[j]=line[d];
                j = j + 1;
                d = d - 1;
            }



2. Это не обмен букв
Код: plaintext
1.
                line[j++]=line[d--];
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564627
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonДля для слов с нечётным числом букв средня буква остаётся на месте. Всё просто.
При условии что вы эту среднюю букву правильно находите
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564706
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Школьная задачка с информатики. 8-й класс первая четверть. И что мы здесь вообще
делаем, господа.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564756
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonШкольная задачка с информатики. 8-й класс первая четверть. И что мы здесь вообще
делаем, господа.
Двоечников спасаем. Уже третья четверть, а он еще не решил
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564764
stut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,m-начало слова; n-1-конец (слово ворд в строке 6;10). Тогда середина (m+n-1)/2 (тогда середина ворда-8-которая не меняется. А если бы слово было на букву короче тогда-7,5=7 как целое тогда меняется лиш первая буква выходит за середину надо брать (m+n)/2 ). Можно j и не брать ибо я беру относительно начала строки. И когда я ввел j-ничего не поменялось. Ошибка может быть что как раз за пределы слов все эти изменение происходят ибо програма при запуске виснет. А почему j увеличивается на двое не понятно что применение инкремента в индексе невозможно? пк под рукою нет потому проверить не могу?// у меня вообще инф. не было в таком класе, тем более С, и это мне нужно как раз не для школы и не только не для школы.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564782
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stutне для школы и не только не для школы
Это утверждение эквивалентно утверждению "не для школы и для школы"
stut,m-начало слова; n-1-конец (слово ворд в строке 6;10). Тогда середина (m+n-1)/2 (тогда середина ворда-8-которая не меняется.
Что ж вы все время эту -1 пихаете?
Предлагагаю вам рассмотреть случай, когда m=6, n=7, т.е. длина 2. Тогда середина будет 6 по вашей формуле.
А теперь цикл
Код: plaintext
1.
for (int j=6; j<6; j++) 


Сколько итераций будет выполнено?
Надеюсь вам не нужен ПК и компилятор чтобы ответить на этот вопрос?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564786
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ага, все, заработался я.
n это не последний символ, а последний + 1.
Тогда формула верная. Простите меня :)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564795
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyТогда формула верная
Рано покаялся. :)
Все равно (m+n-1)/2 не верная формула.
Если m=6, n=8, то середина будет все равно 6 по этой формуле, а должна быть 7.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564807
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stut А почему j увеличивается на двое не понятно что применение инкремента в индексе невозможно?
Знаки препинания ставить надо, а то поток сознания какой-то.

Почему два раза: я тебе красным выделил почему.

stutприменение инкремента в индексе невозможно?
Возможно. То что невозможно - не скомпилируется.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564811
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stutmayton,m-начало слова; n-1-конец (слово ворд в строке 6;10). Тогда середина (m+n-1)/2 (тогда середина ворда-8-которая не меняется. А если бы слово было на букву короче тогда-7,5=7 как целое тогда меняется лиш первая буква выходит за середину надо брать (m+n)/2 ). Можно j и не брать ибо я беру относительно начала строки. И когда я ввел j-ничего не поменялось. Ошибка может быть что как раз за пределы слов все эти изменение происходят ибо програма при запуске виснет. А почему j увеличивается на двое не понятно что применение инкремента в индексе невозможно? пк под рукою нет потому проверить не могу?// у меня вообще инф. не было в таком класе, тем более С, и это мне нужно как раз не для школы и не только не для школы.
Когда работаешь со строками - придерживайся принципов:

1) Символы нумеруются с нуля. Работаем не с байтами а с сущностями char, wchar, TCHAR.... e.t.c. Такой-же берём API.
2) Берём стандартные функции. Они оттестированы и дают хотя-бы адекватный error_state в случае ошибок. В них
также по меньший риск получить vulnerability чем в твоих самодельных функциях.
3) Строки заканчиваются всегда '\0'. Если где-то не заканчиваются - то это не строки.
4) При ВСЕХ строковых операциях с диапазонами - берут полуоткрытый интервал вида [m;n).
Тоесть yourstring.substring(m,n) означает что нужно взять под-строку с m- позиции включительно по n- позицию
не включая хвост. Альтернативный вариант n- задаёт длину подстроки.
5) Большая часть функций (99.9%) которые хотят модифицируют строку - должны работать с аргументом как immutable/const. Для упрощения return используй шаблон std::string. Тоесть аргумент - не изменять. Возвращай изменённую строку как новую сущность.

Возможные споры о performance имеют место, но их надо обсуждать отдельно. Это как раз (0.1%) тех самых редких случаев.
В некоторых случаях например можно вообще строку не изменять а возвращать особый итератор который делает
fetch символов в реверсном порядке и т.п.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564908
stut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
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.
30.
#include <iostream>
#include <string.h>
using namespace std;

char *reverse (char *line)
{
    int n, m=0;
    int l=strlen(line);

    for (int i=0; i<l; i++)
    {
        if ((char)line[i]==' ' || (char)line[i]=='\0')
        {
            n=i;
            int d=(n-1);
            for (int j=m; j<(n+m)/2; j++)
            {
                line[j]='a';
            }
        }
        m=n+1;
    }
    return line;
}

int main()
{
  cout << reverse ("Hello world hello world")<< endl;
  return 0;
}


---даже так- не работает - то есть дело не в замене букв.
Выходит что код после первого ФО не работает вообще
Ибо был сместил m=n+1; на скобку ниже и возвратило первоначальную строку. Хотя теперь
даже это не идет.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564921
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stut, сделай reverse только для 1 слова. И оттестируй.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564967
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Там есть и другие ошибки.
Но основная здесь (об этом еще master_ziv в самом начале намекал):
Код: plaintext
1.
cout << reverse ("Hello world hello world")<< endl;


Функция пытается модифицировать строковый литерал, который скорее всего readonly - и крашится.

вместо этого должно быть так:
Код: plaintext
1.
2.
3.
char* tmp = reverse(strdup("Hello world hello world"));
cout << tmp<< endl;
free(tmp);


Т.е. копируем строку во временную переменную, там выполняем реверс, а потому удаляем временную переменную.

Остальные ошибки (из очевидных):
1) Условие line[i]=='\0' никогда не выполнится т.к. условие цикла i<l. Должно быть i<=l, иначе последнее слово не найдется.
2) m=n+1 присваивает мусор, т.к. n содержит верное значение только внутри if
Перенести внутрь if.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565067
stut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так бы сразу что рид-онли. Но думаю эту темпоральную переменную как раз в функции надо и использовать. Ей присваивать измененные значение лайна а потом возвращать в конце функции. Если добавить ваш кусок то работает. Даже без free(temp). Ибо для этого надо еще какую то библиотеку подключать. Хотя мой вариант разворота слова работает лиш до середине слова?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565077
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stutДаже без free(temp). Ибо для этого надо еще какую то библиотеку подключать.

предвижу, что вскоре здесь на форуме появится пилотная реализацию и функции free от stut-a.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565079
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широковпредвижу, что вскоре здесь на форуме появится пилотная реализацию и функции free от stut-a.
Зачем? Без нее же "работает" :)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565081
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stut,

Используйте класс std::string из C++ для работы со строками, тогда не надо будет выделять и освобождать временный буфер.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565095
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий ШироковstutДаже без free(temp). Ибо для этого надо еще какую то библиотеку подключать.

предвижу, что вскоре здесь на форуме появится пилотная реализацию и функции free от stut-a.
И malloc с "хвостиками"...
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565115
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может лучше так
Код: plaintext
1.
2.
char tmp[] = "Hello world hello world";
cout << reverse(tmp)<< endl;


Зачем грузить студента лишними подробностями если он основное не понимает?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565119
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы даже так упростил
Код: plaintext
1.
2.
3.
4.
char tmp[] = "Hello world hello world";
cout << tmp<< endl;
reverse(tmp);
cout << tmp<< endl;

[/quot]
Кому-то изначальная запись фигня, а кому-то по неопытности может мозг взорвать.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565129
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TМожет лучше так
Код: plaintext
1.
2.
char tmp[] = "Hello world hello world";
cout << reverse(tmp)<< endl;



Зачем грузить студента лишними подробностями если он основное не понимает ?
Я с этим согласен.
strdup был использован, т.к. инициализировать массив можно только литералом, а если строка например передана в качестве аргумента char* то с массивом такое уже не проканает :)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565251
stut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может проще было создать после int m, n; int l=strlen(line); также char *temp--и выделить память tеmp=nеw chаr [l] потом -- иф лайн[i]==пробел то и темп[i] и т.д. ..темп[j]=лайн[d--]. Чуобы доходило до конечного знака в строке лутше написать i<l+1;// strdup- функция все же нестандартная.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565284
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stutstrdup- функция все же нестандартная
здрасте, стандартнее некуда

Но мысль выделять память в функции и возвращать ее имеет право на жизнь (хотя я бы так не делал).
Главное при вызове помнить что после всего надо освободить память.
...
Рейтинг: 0 / 0
25 сообщений из 151, страница 2 из 7
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибки в функции реверса каждого слова строки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]