powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибки в функции реверса каждого слова строки
151 сообщений из 151, показаны все 7 страниц
Ошибки в функции реверса каждого слова строки
    #38563644
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.
#include <iostream>
#include <string.h>
using namespace std;

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

    while (*line!='\0') {
    for (int i=0; i<l; i++) {if ((char)line[i]==' ') {
    n=i;
    int d=i+n-m;
    for (i=m; i<n; i++) {
    line[i]=line[d--];
    }
    m=n+1;
    }
    }
    return line;
}

int main()

    {
    cout << reverse ("Hello world hi russia")<< endl;
    return 0;
}


---компилятор выдает что чтото из скоюками в мейне:
Код: plaintext
1.
2.
3.
\tttt\main.cpp||In function 'char* reverse(char*)':|
\tttt\main.cpp|24|error: a function-definition is not allowed here before '{' token|
\tttt\main.cpp|27|error: expected '}' at end of input|
||=== Build finished: 2 errors, 0 warnings ===|
Кроме того там надо добавить пробел в конце строки что передается в определение функции, и потом конечно ее удалить при ретурне? Да и не знаю вообще ли правильный замысел по сути?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563656
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В ф-и reverse "{" - 5 штук, "}" - 4 штуки.

Если бы вы применяли хотя бы зачатки форматирования кода, то вы бы это увидели даже не компилируя.
Пишите каждый оператор на отдельной строке.
После открывающей { делайте отступ вложенного текста на 4 пробела.
Перед закрывающей } возвращайтесь на предыдущий уровень отступа, так что } по вертикали выровнена с оператором к которому она относится.

Например:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
char *reverse (char *line)
{
    int n, m=0;
    int l=strlen(line);

    while (*line!='\0') {
        for (int i=0; i<l; i++) {
            if ((char)line[i]==' ') {
                n=i;
                int d=i+n-m;
                for (i=m; i<n; i++) {
                    line[i]=line[d--];
                }
                m=n+1;
            }
        }
        return line;
    }
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563688
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Остаётся лишь добавить, что многие современные редакторы и IDE делают такое форматирование автоматически.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563689
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stut,

Ну, и предвосхищая дальнейшие вопросы,

функция должна быть объявлена так:

Код: plaintext
1.
char* reverse (const char *line);



и переписана,

либо сигнатура оставлена такой, как есть, но при вызове нужно выделять доп. буфер.

В существующем виде функция не должна компилироваться нормальным компилятором,
а если и скомпилируется, то завершится аварийно в процессе работы.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563702
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как она вообще работает? При реверсе слова надо доходить только до половины
иначе будет "двойной реверс". Тоесть никакого эффекта.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563706
stut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
\tttt\main.cpp||In function 'char* reverse(const char*)':|
\tttt\main.cpp|14|error: assignment of read-only location '*(line + ((unsigned int)i))'|
\tttt\main.cpp|19|error: invalid conversion from 'const char*' to 'char*'|
\tttt\main.cpp|24|error: a function-definition is not allowed here before '{' token|
\tttt\main.cpp|27|error: expected '}' at end of input|
||=== Build finished: 4 errors, 0 warnings ===|
---Такие ошибки появляются после добавление---const--то есть дело лиш утрудняется.Да и ошибки 24 и 27-срок к чему, как и разрешыть? Хотя главный вопрос что в общем сделать чтобы код скомпилировался и запустился?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563717
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.
#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=i+n-m;
    for (i=m; i<(n-m)/2; i++) {
    line[i]=line[d--];
    }
    m=n+1;
    }

    return line;
}

int main()

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



Модератор: Пользуйся тегом SRC...

Да после удаление одной из закрывающихся скобок компилится но при запуске зависает?
Да и смену слова до лиш до середины поменяли?
Можеш там вайл лишний? Надо наверное написать через ОR--if line[i]==' ' || line[i]=='\0?Тогда пробел не надо в конце добавлять? То есть тогда код упрощается даже очень а не работает?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563752
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stutМожеш там вайл лишний?
Нет, там другая ошибка. Проходи его пошагово, смотри значения всех переменных на каждом
шагу, рисуй на листочке бумаги как изменяется строка.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563755
stut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,
да вы уже подскажите (это какой то там +.-1 или синтаксис не тот),
ибо это задание сейчас для меня не актуально,
хотя дело хочется довести до конца,
ибо где то на 80% задача сделана,
и подобных решений не встречал,
хотя такой замысел у меня касательно такого задание был
уже давно когда стыкнулся с такой задачей,
да и здесь чистая алгоритмизация от а до я.
До бумажки и рисование вряд ли дойдет сейчас.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563763
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stutэто задание сейчас для меня не актуально,
хотя дело хочется довести до конца,
Вот когда станет актуально, тогда и доведёшь. Как - я уже подсказал: пошаговым выполнением
с контролем переменных и рисованием на бумажке.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563768
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stut, это вопрос чести. Ты не можешь бесконечно просить других за тебя что-то делать.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563774
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
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563775
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stut---Такие ошибки появляются после добавление---const--то есть дело лиш утрудняется.Да и ошибки 24 и 27-срок к чему, как и разрешыть? Хотя главный вопрос что в общем сделать чтобы код скомпилировался и запустился?

А кто тебе говорил, что достаточно будет ТОЛЬКО добавить const ?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563781
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
#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

Ты скобочки-то не забыл добавить ?
Может, переусердствовал, убираючи ?

Модератор: Я добавил скобочки....
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563803
stut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ne rabotaet dalee, doballyay ne dobavlyay skobki?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563819
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivфункция должна быть объявлена так:


Код: plaintext
1.
char* reverse (const char *line);





только хотел написать )

stut, а зачем вы делаете приведение ? сейчас сам проверю, пока не понятно
Код: plaintext
1.
((char)line[i]==' '
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563821
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне вообще ваша функция не нравится, она не самая красивая. Нужно провести декомпозицию задачи.
1.Реверс одного слова
2.Определить что слово закончилось и есть ли следующее
3. Цикл по массиву указателей на строку
4. вывод
5. Пока не понятно и не нравится названия переменных(l выглядит как единица), непонятно где и что вы храните.

Через 1 час 20 минут попробую переписать.
Вы сами её делали ?

Кстати, откройте пока K&R главу 5.11. Там рассказывается про argc и argv, задачи чем-то похожи. Или посмотрить код функции echo, может сами сделаете пока меня тут не будет, и старшие товарищи спят
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563822
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonstut, это вопрос чести. Ты не можешь бесконечно просить других за тебя что-то делать.


простите, не заметил сразу :(

значит не буду помогать, извините stut, и вообще искать самому ошибки интересно ! отлично проведённое время, вы ведь будете разбирать алгоритм, а не какую-нибудь ерунду!
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563829
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я уже решил вашу задачу. Делайте её быстрее пожалуйста, я хочу выложить сюда свою версию. Правда я написал код заново, ваш мне совсем не нравится. У меня получилось 10 строчек примерно, правда мне интересно как прокомментируют один мой ход один, потому решайте же быстрее stut ! У вас получится )
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563830
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё оказалось даже проще чем я думал
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563831
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563836
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не то, сейчас исправлю
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38563841
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отличный пример, мне очень нравится ))) Переделал !
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564185
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПравда я написал код заново, ваш мне совсем не нравится.
Вы прямо уже как настоящий программист стали :)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38564456
stut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понимаю что там у вас получилось лиш консоль видно. Мне сейчас это не так надо. Если бы получалось не делал бы тему на форуме. Вам может не нравится но здесь не надо знать никакие указатели и т.д. Идея проста. Идем по символах строки до пробела/конца. Если находим маркируем как n и меняем предыдущие символы в обратном порядке. Потом маркируем начало след. Слова m=n+1, и находим следующий пробел (n=i) и меням местами буквы. И т.д. может так первый цыкл for-не вяжется с каждым отдельным словом. Может m-я не определяю в нужном блоке. Может лайн меняется во влож. цыкле но не выходет из него хотя было бы то же самое что без реверса?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #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
Ошибки в функции реверса каждого слова строки
    #38565317
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.
32.
33.
34.
35.
36.
37.
38.
#include <iostream>
#include <string.h>
using namespace std;

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


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

            }
            m=n+1;
        }

    }
    return tmp;
}

int main()
{
  cout << reverse("Hello world hi russia");
  return 0;
}
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565362
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
32.
33.
34.
35.
36.
37.
38.
39.
#include <cstring>
#include <iostream>

// реверс последовательности символов, заданной полуоткрытым диапазоном [b, e)
char* reverse(char *b, char *e) {
    char* h = b;
    for(; b < --e; ++b) {
        char t = *b;
        *b = *e;
        *e = t;
    }
    return h;
}

// реверс каждого слова последовательности, слово ограничено одним или несколькими "пробелами"
char* reverse_each_word_of_sentence(char s[]) {
    char* h = s;
    while(*h) {
        // съедаем ведущие пробелы
        while( *h && isspace(*h) )
            h += 1;
        // сохраняем начало слова
        char *b = h;
        // продвигаемся по последовательности пока не встретим пробелы
        while( *h && !isspace(*h) )
            h += 1;
        // слово ограничено двумя указателями b и h, причем h не входит
        // реверс слова
        reverse(b, h);
    }
    return s;
}

int main(int argc, char *argv[])
{
    char s[] = "  \t abc \t efgh klmno  \t";
    std::cout << reverse_each_word_of_sentence(s);
    return 0;
}


вывод
Код: plaintext
1.
  	cba 	 hgfe onmlk  	
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565406
stut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
A что значит for(; b<--e;++b) там ведь h-вводится. И что там начальное в цыкле fоr-и почему b должно быть меньше и от е точнее еще на 1 уменьшенное. Почему в двох параметрах идет речь о пре-крементах. И самое главное: что значит возвратить h он же b равен. И иак это влияет на использование в функции реверса в строке?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565417
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stutИ что там начальное в цыкле fоr-и почему b должно быть меньше и от е точнее еще на 1 уменьшенное.
Потому что автор немного отступил от своего же описания
Анатолий Широковсобственно реверсирование слова
Тут reverse(char *b, char *e) переворачивает последовательность символов с пробелом (или нулем) в конце, т.е. "e" указывает не на последнюю букву слова, а на символ за ней, поэтому хитрость с "--e" нужна чтобы этот последний символ не трогать.
stutИ самое главное: что значит возвратить h он же b равен.
b меняется и в конце h != b
stutИ иак это влияет на использование в функции реверса в строке?
В данном конкретном случае никак, h тут вообще лишний. Можно тип функции сделать void и убрать char* h = b; и return h;
Такой подход классический для работы со строками чтобы удобно было комбинировать несколько функций в одном выражении. Например сравнить два перевернутых слова
Код: plaintext
1.
if(strsmp(reverse(a, b), reverse(c,d)) > 0)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565422
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наконец-то я могу выложить свой способ :) Я написал его вчера, и не исправил его полностью, то есть там есть ещё что-то кроме указателей. Сейчас буду править

Код: 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.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
//Это полный реверс одной строки в Си (те она имеет '\0')
void reverse(const char* word, int lenght)//начальный байт памяти, количество байт для считывания
//(с учётом того что ещё один байт конце строки).
//тут вы можете пределать по желанию
//количество байт идёт на входе, ибо функция эта общего вида
{
	--lenght;
	while (lenght >= 0)
	{
		printf("%c", *(word + lenght));
		lenght--;
	}
}

void reverse_each_word(const char* word)//принимает указатель на начало строки
{
	int lenght = 0;
	//определил длину всей строки
	while (*(word + lenght) != '\0')
	{
		++lenght;
	}
	//то что выше можно заменить strlen, веротятно
	
	int global_cur = 0;//глобальный текущий указатель на элемент строки
	int w_cur_lenght = 0;//длина текущего слова
	int w_cur_start = 0;//указатель на текущее слово
	while (global_cur <= lenght)//иду по всей строке
	{
		if (*(word + global_cur) == ' ' || global_cur==lenght)//если пробел или конец строки
		{
			reverse(word + w_cur_start, w_cur_lenght);//вывожу реверс текущей строки
			printf(" ");//печатаю пробел, кстати тут немного неккоректно в конце, выведется лишний пробел
			w_cur_lenght = 0;//обнуляю длину текущего слова
			w_cur_start = global_cur + 1;//указатель на новое слово
		}
		else
		{
			++w_cur_lenght;//увеличиваю длину текущего слова
		}
		++global_cur;//увеличиваю глобальный индексатор
	}
}

int main()
{
	printf("\n");
	reverse_each_word("Hello world");
	printf("\n");
	return 0;
}
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565424
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_T,
а Анатолий Широков уже видимо сделал всё на указателях ..


Анатолий Широков// реверс последовательности символов, заданной полуоткрытым диапазоном [b, e)

Хороший комментарий
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565483
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryНаконец-то я могу выложить свой способ :)
Ты не ту задачу решил. Близко к исходной, но не ту.
Задача стояла "функция реверса каждого слова строки", а ты сделал вывод каждого слова наоборот.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565491
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_Tфункция реверса каждого слова строки

т.е. чтобы я перезаписывал в память для этой-же строки значение её реверса?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565498
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryDima_Tфункция реверса каждого слова строки

т.е. чтобы я перезаписывал в память для этой-же строки значение её реверса?
да, записать реверс поверх исходного слова.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565534
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, она не возвращает значение, даже неявно не возвращает, и вчера про это думал целый день. Решил её не переделывать. Мне показалось что для данной задачи лучше читать память по другому, нежели менять значение строки.

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

Будущий алгоритм напоминает мне часы. Шестерни точнее. Я хочу вставлять эту строку в паззл и толкать её, там где будут отдельные слова, будут шестерни, я кручу строку по кругу и всё становится на свои места. И всё равно должен быть алгоритм ещё лучше.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565541
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565547
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Я не отступал от своего комментария

// реверс последовательности символов, заданной полуоткрытым диапазоном [b, e)

Где ты нашел отступление? b входит, e не входит в полуоткрытый диапазон.

stut,

Идея реверса состоит в движении двух указателей b и e на встречу друг другу, а обмен имеем смысл пока указатель на начало b меньше указателя на конец e. В силу того, что e не входит в диапазон и рассматривается как терминатор последовательности мы сначала его уменьшаем на единицы, а только потом обращаемся к содержимому.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565562
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

круто, рисуй ещё...
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565567
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryНаконец-то я могу выложить свой способ :) Я написал его вчера, и не исправил его полностью, то есть там есть ещё что-то кроме указателей. Сейчас буду править

Код: plaintext
1.
2.
//Это полный реверс одной строки в Си (те она имеет '\0')
void reverse(const char* word, int lenght)//начальный байт памяти, количество байт для считывания



Когда ты придумываешь имена для функций в С++ - нужно их наполнять смыслом. Это никакой не реверс.
Это по смыслу - printReverse() или reversePrint().
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565574
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий ШироковDima T,

Я не отступал от своего комментария

// реверс последовательности символов, заданной полуоткрытым диапазоном [b, e)

Где ты нашел отступление? b входит, e не входит в полуоткрытый диапазон.
я про твою исходную постановку задачи 15586620
Анатолий Широковпопробуй разбивать задачу на подзадачи: поиск слов и собственно реверсирование слова
Как мне показалось эта небольшая нестыковка вызвала непонимание.

Комментарий полностью соответствует тому что функция делает. Тут я ничего против не писал.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565577
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Да, вроде, все понятно, слово можно задать полуоткрытым диапазоном, а можно открытым. Все равно это будет реверс слова.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565579
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryя кручу строку по кругу и всё становится на свои места
Это тебе не поможет (насколько я понял твои картины) по кругу это так
abc => bca => cab => abc

Изобретай шестерню другой системы
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565613
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут еще до кучи можно поднять вопрос скорости.
Раз уж мы в общем случае должны скопировать аргумент в буфер, то было бы логично вместо копирования и последующего реверса по месту делать копирование одновременно с реверсом.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565626
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TSashaMercuryя кручу строку по кругу и всё становится на свои места
Это тебе не поможет (насколько я понял твои картины) по кругу это так
abc => bca => cab => abc

Изобретай шестерню другой системы
В перспективе - это PPM архиватор.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565779
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще я должен сказать, что вы все подходите к решению проблемы недостаточно масштабно. Нет размаха....

Как надо это делать?

Составить словарь всех слов, с их реверсами.

Выделить в тексте слова, найти по словарю и заменить на реверс.

Вещь как надо...
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565816
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Словарь? Опять Стебелёк нужен.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38565849
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и без лексера и парсера не обойтись.
А то как составить синтаксическое дерево слов?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568292
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Анатолий Широков
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
// реверс последовательности символов, заданной полуоткрытым диапазоном [b, e)
char* reverse(char *b, char *e) {
    char* h = b;
    for(; b < --e; ++b) {
        char t = *b;
        *b = *e;
        *e = t;
    }
    return h;
}



допустим:
Код: plaintext
1.
char* temp="Hello".



Я пытался сделать следующее:
Код: plaintext
1.
reverse(temp,temp+4)



Не могу понять в чём проблема. Мне кажется я что-то упустил или забыл.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568295
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И почему-то адрес с которого начинается "Hello" всегда заканчивался 8.Хотя это может быть совпадение
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568297
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryНе могу понять в чём проблема. Мне кажется я что-то упустил или забыл.
Конкретнее надо писать что именно не получается. Тут телепатов нет.

Как минимум ты неверно вызываешь reverse(), т.к. указатель конца надо не НА последний, а ЗА последний символ, т.е.
Код: plaintext
1.
reverse(temp,temp+5);
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568304
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Происходит проблема с доступом к памяти. Адрес конца не принципиален, отрезок в любом случае сужается. Дело не в этом, пусть будет инверс в подстроке
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568308
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПроисходит проблема с доступом к памяти.
Ты вышел за пределы строки и обратился по адресу где нет реальной памяти.
Смотри пошагово с какими параметрами ты reverse() вызываешь.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568324
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы уверены наверняка что дело в этом ?В том что я выхожу за пределы памяти для строки "Hello" ?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568333
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury
Код: plaintext
1.
char* temp="Hello".


Не заметил сразу, тут косяк, у тебя "Hello" это массив констант и писать туда нельзя.
Объявляй как свой массив:
Код: plaintext
1.
char temp[]="Hello";
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568353
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryВы уверены наверняка что дело в этом ?В том что я выхожу за пределы памяти для строки "Hello" ?
Я наверняка уверен что не обладаю телепатическими способностями. Учись информативно свои вопросы задавать. Примерно так
авторЗапускаю код
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
char* reverse(char *b, char *e) {
    char* h = b;
    for(; b < --e; ++b) {
        char t = *b;
        *b = *e;
        *e = t;
    }
    return h;
}

int _tmain(int argc, _TCHAR* argv[])
{
	char* temp="Hello";
	reverse(temp,temp+4);
	return 0;
}


Получаю ошибку "Unhandled exception at 0x004113e0 in Reverse.exe: 0xC0000005: Access violation writing location 0x00415740."
на строке
Код: plaintext
1.
      *b = *e;
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568372
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо, извините за плохую постановку вопроса.
Но я ведь не писал const char*. Почему он константный ?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568379
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryХорошо, извините за плохую постановку вопроса.
Но я ведь не писал const char*. Почему он константный ?

По жизни он константный.
Более того, если бы ты пользовался более другим композитором, у тебя бы это даже не скомпилировалось.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568382
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryХорошо, извините за плохую постановку вопроса.
Но я ведь не писал const char*. Почему он константный ?

Вообще странно...
Вроде бы последняя версия VC, должны были они там уже отключить эту фичу...
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568399
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryХорошо, извините за плохую постановку вопроса.
Но я ведь не писал const char*. Почему он константный ?
ты написал chаr* temp - компилятор тебе выдал 4 байта под этот указатель. Вот эти 4 байта и меняй как хочешь. Например temp = NULL
char temp[]="Hello" это ты просишь выделить тебе 6 байт под массив и записать туда {'H', 'e', 'l', 'l', 'o', 0} тут ты имеешь полное право менять содержимое этого массива
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568404
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПочему он константный ?
потому что компилятор разместил строку "Hello" в области памяти помеченной как read-only, поэтому попытка туда что либо записать вызывает ошибку. Подробнее узнаешь когда доберешься до изучения устройства виртуальной памяти.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568465
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryХорошо, извините за плохую постановку вопроса.
Но я ведь не писал const char*. Почему он константный ?

Это компромисс на который пошел Страуструп, чтобы обеспечить компилируемость старого Си-шного кода.

Пишешь

Код: plaintext
1.
char* hello = "Hello";



Подразумеваешь

Код: plaintext
1.
const char* hello = "Hello";



Ведь "Hello" это строковая константа, которая будешь размещена в read-only сегменте и изменять которую ты не имеешь право.

Вообщем, приобрети "Дизайн и эволюция языка С++" Страуструпа, ее сейчас переиздали. Много интересного узнаешь почему та или иная языковая конструкция выглядит так или иначе.

Удачи!
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568482
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широков,

Не надо мозг парить неофиту заумными книгами.

Я вообще ее не читал никогда, думаю, немного потерял. Все, что там написано, вполне очевидно.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568494
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЯ вообще ее не читал никогда, думаю, немного потерял. Все, что там написано, вполне очевидно.

Ильюша, иди в жопу. Это отлична книга. Если ты что-то не читал это не повод для гордости. "Я понятно объясняю?" (c)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568533
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, действительно очень хорошая книга, многое приходит в порядок послее ее прочтения.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568536
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PPS. Книга совсем не заумная, написана очень простым располагающим к чтению языком.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568595
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_PPS. Книга совсем не заумная, написана очень простым располагающим к чтению языком.

Ребята, я всё понимаю. Светило, и вообще, Страустрап -- наша фсё!
Но по тематике С++ (и не только) для меня лично есть дофига книг, которые я хочу прочитать.
И данная -- далеко не самая полезная. Меня лично она вообще не интересует -- книга в виде
биллетристики, о том, "как я сделал это". Он сделал хорошо, я всё это и так знаю. Детали мне не иснтересны,
я 80% их и так знаю.


Хотя...
Пожалуй, я хотел бы одну вещь выяснить. А именно, как в С++ попали шаблоны.
Ну да попали -- и попали, наплевать, как. В итоге получилось что получилось, другого не будет.

Но ЕМУ то это всё зачем?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568664
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Толик. Вдохни глубоко. А-то скипетр власти оттягивает руку...
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568679
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonТолик. Вдохни глубоко. А-то скипетр власти оттягивает руку...

Все в порядке, он уже понял свою ошибку. А ты что, хотел Илью забанить, да? ;-)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568696
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНо ЕМУ то это всё зачем?
Беллетристика очень помогает разложить по полочкам.
SashaMercury видно что нуждается как раз в этом, ибо технических деталей уже нахватался, но пока все вместе не состыковал.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568699
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий ШироковmaytonТолик. Вдохни глубоко. А-то скипетр власти оттягивает руку...

Все в порядке, он уже понял свою ошибку. А ты что, хотел Илью забанить, да? ;-)
На неужели? А в чём была его ошибка?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568743
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonАнатолий Широковпропущено...


Все в порядке, он уже понял свою ошибку. А ты что, хотел Илью забанить, да? ;-)
На неужели? А в чём была его ошибка?

Ну как же, решил права покачать на правах старшего - типа он де лучше знает кому и что читать. Но он так больше не будет. Простим его.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568949
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вышел с телефона, неудобно цитировать, потому спрошу так.
Исходя из каких логических соображний, или как это помогло совместимости с Си ?
Я читал в КиН что объявление выше аналогично char temp[].
Спасибо что вы советуете книги, я выписывают их на последнюю страницу тетради по Си. Когда изучу КиН начну читать алг тр для программиста и одну книгу по Си параллельно..
И еще, в последнее-время я мало думал. Но вопрос по реверсу так и остался. Есть ли другой, радикально черный цвет для решения данной задачи ?

Всем спасибо за ответы C:
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568958
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КиР*
Не знаю почему не так написал выше
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568994
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

Читай внимательно. Ты перепутал. Они говорили, что нет разницы между char s[] и char* s когда это формальные параметры функции

K&R5.3
...

As formal parameters in a function definition,
char s[];
and
char *s;
are equivalent; we prefer the latter because it says more explicitly that the variable is a pointer


а при объявлении это две разных сущности:

K&R5.5
....
There is an important difference between these definitions:
char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */



SashaMercuryЕсть ли другой, радикально черный цвет для решения данной задачи ?


О чем ты пытаешься спросить? "Ты не умничай, пальцем покажи"
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38568997
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, вспомнил, я ошибся насчет КиР. Вы правы !
Пересматривал 12 стульев недавно, и запомнилась фраза про радикально черный-цвет усов :D
Есть ли другой метод ? Я не хочу идти даже до половины строки для реверса, я хочу сделать это в 10 раз быстрее и не в лоб. Как ? Это возможно ?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569004
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще. Моя функция rev_each_word выше читает память по другому, и делает printf. Как написать функцию kat которая будет принимать имя функции rev_each_word , и записывать в строку все printf от нее ?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569015
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЯ не хочу идти даже до половины строки для реверса
чудес не бывает, нужен алгоритм.
Предложи алгоритм как перевернуть последовательность из 5 элементов меньше чем за 2 действия, при этом за один шаг менять можно только любые два.
12345hello
Вышеописанные алгоритмы (<=> значит обменять значения)
Шаг 1. [1] <=> [5]
Шаг 2. [2] <=> [4]
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569023
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryда, вспомнил, я ошибся насчет КиР. Вы правы !
Пересматривал 12 стульев недавно, и запомнилась фраза про радикально черный-цвет усов :D
Есть ли другой метод ? Я не хочу идти даже до половины строки для реверса, я хочу сделать это в 10 раз быстрее и не в лоб. Как ? Это возможно ?

конечно возможно с помощью оптического процессора - один квант и отражение от зеркала дает реверс.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569033
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сейчас, как я понял, для реверса нужно n/2 итераций по две замены в каждой, кстати, может быть быстрее 1 итерация с n заменами сразу, но не суть. Возможно для n= 10^20 f e существует другой алгоритм
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569038
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня уже закрываются глаза..завтра буду читать про квант.
Спасибо всем C: Спокойных выходных :)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569043
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryИ еще. Моя функция rev_each_word выше читает память по другому, и делает printf. Как написать функцию kat которая будет принимать имя функции rev_each_word , и записывать в строку все printf от нее ?
Можно, но это очень нездоровый путь, т.к. писать выведенное надо будет в другое место (другой массив), проще сразу писать в другой массив.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569051
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryзавтра буду читать про квант.
Так мы тебя лет на ...дцать потеряем

Вот тебе пища для размышлений на выходные :) Изучай рекурсию
Код: 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.
#include <stdio.h>

char* reverse(char *b) {
    char* h = b;

	char* e = b;
	while(*e != 0 && *e != ' ') e++;
	if(*e != 0) reverse(e + 1);

    for(; b < --e; ++b) {
        char t = *b;
        *b = *e;
        *e = t;
    }
    return h;
}

int _tmain(int argc, _TCHAR* argv[])
{
	char temp[]="Hello world" ;
	printf("%s\n", temp);
	reverse(temp);
	printf("%s\n", temp);

	return 0;
}


Красиво, но неэффективно с точки зрения производительности.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569133
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryСейчас, как я понял, для реверса нужно n/2 итераций по две замены в каждой, кстати, может быть быстрее 1 итерация с n заменами сразу, но не суть. Возможно для n= 10^20 f e существует другой алгоритм


Как бы меньше чем за O(N) не получится.
N или N/2.

Это конечно хорошо бы формально доказать, но так навскидку вполне очевидно.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569157
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

что здесь формально доказывать, что нужно (int)(N/2) обменов? Как ни крути, O(N)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569192
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут не обойтись без гипотезы Пуанкаре
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569193
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий ШироковMasterZiv,

что здесь формально доказывать, что нужно (int)(N/2) обменов? Как ни крути, O(N)

Да, что нужно N/2 обменов.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569194
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На ограниченном множестве {X} можно построить дешифратор
и минимизировать его. Какой будет O(n) - Х.З.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569198
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНа ограниченном множестве {X} можно построить дешифратор
и минимизировать его. Какой будет O(n) - Х.З.
Кстати, а если n операций запустить параллельно в n потоках, то сложность такого алгорима будет уже О(1) или все-таки еще О(n)? Что там математика про распараллеливание говорит?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569204
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Теория алгоритмов эту тему не рассматривает. Но есть IMHO
смежные области, которые смотрят в Сети-Петри, Марковские процессы и прочее.

P.S. И еще IMHO это экстенсивное развиние It. Поэтому неправославно.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569401
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

сам запуск N/2 потоков имеет сложность O(N)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38569415
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivКак бы меньше чем за O(N) не получится.
N или N/2.

Это конечно хорошо бы формально доказать, но так навскидку вполне очевидно.
Реверс за О(1):
Код: plaintext
1.
2.
LDMIA r9!, {r0-r7}
STMDB r9!, {r0-r7}


Правда заработает только на армах .
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570022
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Анатолий Широков
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
// реверс последовательности символов, заданной полуоткрытым диапазоном [b, e)
char* reverse(char *b, char *e) {
    char* h = b;
    for(; b < --e; ++b) {
        char t = *b;
        *b = *e;
        *e = t;
    }
    return h;
}



Я вновь вернулся к вашему коду. Переписал его по своему.
Алгоритм хороший.
а)Но мне не понравилось что интервал полузакрытый, я понимаю что вы вероятнее всего сделали это для Си-строк, чтобы не учитывать конец строки автоматом. Но всё же, мне кажется лучше функция реверса для закрытого участка байт.
б)У K&R тоже реализация через for, но мне кажется while будет красивее, ибо в коде

Код: plaintext
1.
for(; b < --e; ++b) 



легче допустить ошибку.

Хотя, опять таки это вероятно мне легче допустить ошибку, а для остальных в сообществе это очевидно. Потому в корректности данного комментария я не уверен. И потому это просто моё мнение C:

в) обратил внимание на участок кода в for
Код: plaintext
1.
char t = *b;


те фактически я постоянно объявляю новую переменную t, мне кажется что объявление лучше сделать выше. До цикла.

В связи с моими наблюдениями я решил переписать код(точнее я написал его до вас, а потом посмотрел как сделали вы, но ничего не работало из константного массива символом, и мне пришлось более детально разобрать и ваш и мой код)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
//реверс закрытого промежутка байт [start,end]
void reverse(char* start, char* end) //адрес первого и последнего байта
{
	char temp = 'a'; /*1*/
	while (start<=end)
	{
		char temp = *start;
		*start = *end;
		*end = temp;
		++start; 
		--end;
	}
} 



1. Как лучше инициализировать объект char ? (я знаю что все элементы надо/желательно инициализировать)

Сейчас попробую кое-что сделать, позже выложу.

Заключение: Рассуждения выше, ни в коем случае не есть критика вашего кода. Ибо я понимаю, что вы написали чтобы помочь, и не стремясь к идеалам по качеству кода. Но тем не менее мне интересно имеют ли мои комментарии право на жизнь, либо они идут от того что я пока слишком слабо понимаю Си.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570030
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PS Ошибка выше. Забыл убрать char temp в цикле

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
//реверс закрытого промежутка байт [start,end]
void reverse(char* start, char* end) //адрес первого и последнего байта
{
	char temp = 'a'; /*1*/
	while (start<=end)
	{
		temp = *start;
		*start = *end;
		*end = temp;
		++start; 
		--end;
	}
} 
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570032
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
next PS.
Лишняя итерация while(start<=end)

Надо так.
//реверс закрытого промежутка байт [start,end]
void reverse(char* start, char* end) //адрес первого и последнего байта
{
char temp = 'a'; /*1.1-1.2*/
while (start<end)
{
char temp = *start;
*start = *end;
*end = temp;
++start;
--end;
}
}
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570035
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryPS Ошибка выше. Забыл убрать char temp в цикле
Правильнее оставить его в цикле. Как выше писали не надо давать переменной область видимости больше чем это требует алгоритм.

И инициализация (= 'a') не имеет никакой полезной нагрузки, просто будут выполнены бесполезные действия.

Твой код работать будет, но лучше так написать
Код: plaintext
1.
2.
3.
4.
5.
6.
void reverse(char* start, char* end) //адрес первого и последнего байта
{
	while (start<end)
	{
		char temp = *start;
...
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570077
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_TПравильнее оставить его в цикле. Как выше писали не надо давать переменной область видимости больше чем это требует алгоритм.


Но я ведь постоянно обновляю новую переменную, постоянно прошу компилятор выделить для неё память ?Или нет ? Я понимаю что лучше объявлять переменную в месте её первого использования, но мне казалось что когда диалог доходит до циклов, это правило немного меняется, и переменную лучше объявить перед началом цикла.

Dima_TИ инициализация (= 'a') не имеет никакой полезной нагрузки, просто будут выполнены бесполезные действия.


Понимаю Вас. Но может в дальнейшем при поиске ошибок я бы увидел что в какой переменной char всегда хранится 'a', и я подумал бы тогда, я ведь не инициализировал её, в том смысле я бы знал что при объявлении переменных типа char по дефолту будет 'a'(всегд буду инициализировать переменные при объявлении определённым числом/кодом). Может быть это излишки.


Дописал функцию принимающую указатель на начало строки и делающую инверсию каждого слова в строке.
Код: 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.
32.
33.
34.
35.
36.
37.
38.
39.
//реверс закрытого промежутка байт [start,end]
void reverse(char* start, char* end) //адрес первого и последнего байта
{
	while (start<end)
	{
		char temp = *start;
		*start = *end;
		*end = temp;
		++start; 
		--end;
	}
} 

void reverse_each_word(char* start)//указатель на начало строки
{
	char* range_s = start;
	char* range_e = start;

	while (*start)//иду по всей строке
	{	
		if (*start == ' ')
		{
			reverse(range_s, range_e-1);
			range_s = start + 1;
		}
		else
		{
			++range_e;
		}
		++start; //иду к следующему элементу строки
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	char test[] = "Hello world";
	reverse_each_word(test);
	printf("%s", test);
}



Теперь нужно внимательно изучить код Анатолия Широкова и ваш
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570100
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryDima_TПравильнее оставить его в цикле. Как выше писали не надо давать переменной область видимости больше чем это требует алгоритм.


Но я ведь постоянно обновляю новую переменную, постоянно прошу компилятор выделить для неё память ?Или нет ?
Нет. Компилятор сам "догадывается" что не надо выделять память каждый раз. Если посмотреть во что компилируются оба варианта то видно что там одно и тоже (при отладке правая кнопка "go to disassembly")

Выделение памяти под локальные переменные происходит в момент компиляции, в код вписывается что-то типа "использовать 20ю ячейку стэка под переменную temp", а сам код делает примерно следующее
Код: plaintext
1.
2.
3.
char temp = *start; // записать *start в 20ю ячейку стека
*start = *end;
*end = temp; // записать в *end из 20й ячейки стека


т.е. в процессе выполнения никаких операций по выделению/освобождению памяти не происходит. Точнее при старте программы выделяется память под стек и далее используется под все локальные переменные.
Компилятор просто собирает код так чтобы в 20ю ячейку ничего не было записано пока используется переменная temp. Отсюда также вытекает что объявив temp за циклом ты запрещаешь использовать 20ю ячейку на протяжении выполнения всей функции.

В общем пока не заморачивайся. Будешь следить за выделением/освобождением памяти когда явно будешь использовать выделение памяти calloc(), malloc(), new и т.д.

SashaMercury... при поиске ошибок я бы увидел что в какой переменной char всегда хранится 'a', и я подумал бы тогда, я ведь не инициализировал её...
Инициализируй лучше нулем.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570105
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В твоей функции reverse_each_word() лишняя переменная range_e
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570115
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_TВ твоей функции reverse_each_word() лишняя переменная range_e


Спасибо, и ещё одна ошибка была. Исправил

Код: 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.
//реверс закрытого промежутка байт [start,end]
void reverse(char* start, char* end) //адрес первого и последнего байта
{
	while (start<end)
	{
		char temp = *start;
		*start = *end;
		*end = temp;
		++start; 
		--end;
	}
} 
//реверс строки с указанного байта
void reverse_each_word(char* current)//указатель на стартовый байт для реверса
{
	char* range_s = current;
	while (*current)//иду по всей строке
	{	
		if (*current == ' ' || *(current+1)=='\0')
		{
			reverse(range_s, current-1);
			range_s = current + 1;
		}
		++current; //иду к следующему элементу строки
	}
}
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570119
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryСпасибо, и ещё одна ошибка была. Исправил
Уверен что все ошибки исправил?
Смотри внимательно что в результате получается.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570127
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Угу(
Но так уже мне не нравится, не так красиво как раньше. Пока не додумался как обойтись без этой доп проверки, и подглядывать не хочу. Вечером ещё подумаю
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
//реверс строки с указанного байта
void reverse_each_word(char* current)//указатель на стартовый байт для реверса
{
	char* range_s = current;
	while (*current)//иду по всей строке
	{	
		if (*current == ' ')
		{
			reverse(range_s, current-1);
			range_s = current + 1;
		}
		else if (*(current + 1) == '\0')
		{
			reverse(range_s, current);
		}
		++current; //иду к следующему элементу строки
	}
}
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570136
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не нашёл что-то "go to disassembly" . В контекстном меню при отладке смотрел. Видимо так смотрел.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570142
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во время выполнения, когда на брейкпоинте остановится - правая кнопка на коде
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570184
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Допустим алфавит состоит из 23 символов. Берём словарь по 4 байта, получаем 23^4 записей. В словаре будет два атрибута, значение и реверс. Делаем классический реверс но уже используя этот словарь. Допустим реверс идёт для текста длиной n. Как мне рассчитать n, для которой данный алгоритм будет давать прирост по времени хотя бы в два раза по сравнению с классическим алгоритмом ?

Если я создам словарь для 2 байт, как мне считывать по два байта ? Создать свой тип данных ?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570186
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_TВо время выполнения, когда на брейкпоинте остановится - правая кнопка на коде


Окей, понял :)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570205
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чтобы сделать реверс из n символов нужно сделать n операций.

Саш. Мир полон замечательных и интересных алгоритмов. Тебе
не хочется обсудить что нибудь другое?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570245
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЧтобы сделать реверс из n символов нужно сделать n операций.

Саш. Мир полон замечательных и интересных алгоритмов. Тебе
не хочется обсудить что нибудь другое?

Да, парень явно завис, зациклился видимо...
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570247
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryДопустим алфавит состоит из 23 символов. Берём словарь по 4 байта, получаем 23^4 записей. В словаре будет два атрибута, значение и реверс. Делаем классический реверс но уже используя этот словарь. Допустим реверс идёт для текста длиной n. Как мне рассчитать n, для которой данный алгоритм будет давать прирост по времени хотя бы в два раза по сравнению с классическим алгоритмом ?

Если я создам словарь для 2 байт, как мне считывать по два байта ? Создать свой тип данных ?
Про словарь это шутка была. Со словарем всегда будет медленнее.
Общий размер строки никак не повлияет на скорость, т.к. меняется только алгоритм реверса одного слова. Разбор на слова у тебя остается в обоих случаях.
Поиск в словаре тоже требует некоторых вычислений.

Этот алгоритм самый эффективный, есть только один способ попытаться ускорить: реализовать этот код на ассемблере, т.е. в командах процессора. Вполне возможно компилятор создал не самый идеальный код. Но тут надо сначала хорошенько ассемблер поизучать. Оно тебе надо?

maytonСаш. Мир полон замечательных и интересных алгоритмов.
+100500

SashaMercury, поищи себе задачку посложнее. Только эту допили чтоб reverse_each_word() покомпактнее была.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38570942
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЭтот алгоритм самый эффективный, есть только один способ попытаться ускорить: реализовать этот код на ассемблере, т.е. в командах процессора. Вполне возможно компилятор создал не самый идеальный код. Но тут надо сначала хорошенько ассемблер поизучать.

Это ты глубоко заблуждаешься.
Почему-то все думают, что ассемблер-- такой волшебный язык, на котором всё сразу автоматом начинает работать быстрее.

Даже если этот алгоритм записать в виде одной машинной комманды, его стоимость не изменится -- O(n) как было, так и будет.
Потому что для ревёрса слова in-place надо переместить n символов слова, для ревёрса слова с копированием в другой буфер, надо скопировать те же n символов слова.

Стоимости алгоритмов всегда считаются относительно кол-ва выполнения одной базовой операции.
Операция выбирается в зависимости от сущности алгоритма и цели оптимизации.

Стоимость данного алгоритма неизменна независимо от того, сколько машинных комманд ушло на программирование этого алгоритма.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38571112
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivDima TЭтот алгоритм самый эффективный, есть только один способ попытаться ускорить: реализовать этот код на ассемблере, т.е. в командах процессора. Вполне возможно компилятор создал не самый идеальный код. Но тут надо сначала хорошенько ассемблер поизучать.

Это ты грубоко ошибаешся.
Почему-то все думают, что ассемблер-- такой волшебный язык, на котором всё сразу автоматом начинает работать быстрее.

Даже если этот алгоритм записать в виде одной машинной комманды, его стоимость не изменится -- O(n) как было, так и будет.

Не надо к словам придираться.
1. Стоимость алгоритма величина условная, предназначенная для сравнения эффективности различных алгоритмов (не реализаций). Поэтому в данном случае стоимость алгоритма не изменится: O(n) как было, так и будет.
2. Код (реализация алгоритма) возможно будет работать быстрее созданного компилятором если написать на асме.

PS Ассемблер я немного знаю и не утверждал что всё сразу автоматом ускорится. Современные компиляторы достаточно эффективны и надо постараться написать так чтоб быстрее работало. Если заметил - я написал "возможно".
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38571280
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Если написать на ассемблере, операций не станет меньше, и они не станут быстрее.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38571284
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ладно, я предлагаю уже прикрыть тему...
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38571300
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Dima_TТолько эту допили чтоб reverse_each_word() покомпактнее была.


К сожалению приходится заниматься порой всякой фигней, вместо того чтобы заниматься программированием ( Как же я хочу заниматься только программированием и математикой, и не заниматься на учебе/работе другой фигней. Потому не всегда получается быстро отвечать.

Пять минут назад(снова в душе, что за душ у меня такой ) я подумал об этой задаче буквально 5 секунд и понял как ее допилить. Компилятора сейчас нет (на этой машине), но мне кажется что код ниже будет работать C: Причём до этого я ни секунды не думал со вчерашнего дня именно о том как её допилить, думал про рекурсию, но не про это. Удивляюсь, правильная мысль пришла буквально сразу. Такой код вероятно:

Код: 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.
//реверс закрытого промежутка байт [start,end]
void reverse(char* start, char* end) //адрес первого и последнего байта
{
	while (start<end)
	{
		char temp = *start;
		*start = *end;
		*end = temp;
		++start; 
		--end;
	}
} 

//реверс строки с указанного байта
void reverse_each_word(char* current)//указатель на стартовый байт для реверса
{
	char* range_s = current;
	while (*current)//иду по всей строке
	{	
		if (*(current+1) == ' ' || *(current + 1) == '\0')
		{
			reverse(range_s, current);
			range_s = current + 1;
		}
		++current; //иду к следующему элементу строки
	}
}



mayton, MasterZiv, Dima_T
нет не завис. Мне кажется что это фундаментальная задача, и такое долгое понимание того что необходимо n операций для реверса n байт даёт мне более глубокое понимание работы основной массы архитектур машин. Я каждый день ставил под сомнение этот алгоритм, и я не нашёл как по другому. Наверное нужна другая логика работы системы, например добавить градиент(к архитектуре машины) который будет показывать в какую сторону читать память.

В любом случае, все ваши комментарии и мои размышления за это время дали результат в виде того что фундамент на котором я стою теперь более устойчив. Спасибо.

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

Главный вывод:Хотеть не вредно, необходимо искать оптимальные решения для каждой задачи исходя из архитектуры машины, и ставить под сомнения каждый алгоритм. Нужно искать оптимальное решение всегда.
Побочный/повторный вывод: указатели чудо C:
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38571360
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПобочный/повторный вывод: указатели чудо C:добро пожаловать в семью :)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38571362
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury...Такой код вероятно:
Так уже хорошо. До компилятора доберешься, маленькую ошибку исправь и завязывай с этой задачей. Ищи следующую :)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38571433
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

зачем ты переписал мой идеальный reverse? :D зачем ты переписал reverse_each_word, если предложенная мной реализация гибче (пробелы, табуляторы и другие вайтспейсы могут разделять слова в неограниченном количестве стоять перед и после)?

хороший совет на будущее, ищи идеал, но используй для этого качественные критерии. ты переписал реверс даже не уточнив критерии, которые ты хочешь улучшить в своей реализации, а это, извини, ребячество. но у тебя все впереди.

еще учти, что полуоткрытые диапазоны это основа стандартных алгоритмов стандартной библиотеки алгоритмов. с ними ты будешь сталкиваться на каждом углу.

удачи!
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38571821
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury ...
Код: 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.
//реверс закрытого промежутка байт [start,end]
void reverse(char* start, char* end) //адрес первого и последнего байта
{
	while (start<end)
	{
		char temp = *start;
		*start = *end;
		*end = temp;
		++start; 
		--end;
	}
} 

//реверс строки с указанного байта
void reverse_each_word(char* current)//указатель на стартовый байт для реверса
{
	char* range_s = current;
	while (*current)//иду по всей строке
	{	
		if (*(current+1) == ' ' || *(current + 1) == '\0')
		{
			reverse(range_s, current);
			range_s = current + 1;
		}
		++current; //иду к следующему элементу строки
	}
}





Гениально. (я без сарказма). Давно бы так.

SashaMercurymayton, MasterZiv, Dima_T
нет не завис. Мне кажется что это фундаментальная задача,


Есть задачи и гораздо более фундаментальные.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38572344
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Dima_Tмаленькую ошибку исправь

Вчера про это кстати подумал, и даже сначала так написал, а потом решил что можно оставить как раньше. Должно быть так
Код: plaintext
1.
range_s = current + 2;



egorych, спасибо C: Как-будто бы в мафиозный клан попал :D (я такую фразу слышал в фильмах про итальянских мафиози вроде :DDD)

Анатолий Широков,
мне просто хотелось сделать это самому ;) Ваш код и код Дмитрия с рекурсией я разберу более детально позднее. Сегодня хочу разобрать следующую главу K&R.


MasterZivЕсть задачи и гораздо более фундаментальные.


Надеюсь доберусь и до них :)

Всем спасибо :)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38574968
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широковеще учти, что полуоткрытые диапазоны это основа стандартных алгоритмов стандартной библиотеки алгоритмов

Почему именно полуоткрытые ? Закрытый интервал более читаем, так наверное. Неужели из-за индексации массивов с нуля ?
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38575093
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

потому, что это позволяет естественно использовать открытый конец как специальное сигнальное значение. Это позволяет использовать лаконичные интерфейсы, и облегчает реализацию циклов.

В возникших вопросах "А можно пример? Можно разъяснить подробнее?" советую разобраться самому (попробовать реализовать некоторые алгоритмы из stl на отрезках, например), это может дать более твердое понимание.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38575102
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

вообще многие вопросы которые вы задаете, стоило бы обсуждать лет 7-10 назад. Сегодня в них лучше разбираться самому, все это уже везде разжевано, расписано, рассказано. С каждым годом кол-во усваиваемой студентами информации возрастает (было время когда в "ВУЗе" учили умножать). Вы же идете против этого процесса.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38575226
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дайте ссылку где это обсосано. Обоснование от вас не услышал.
Студенты тупеют духовно, и потому умнеть в плане мат/прог не могут по дефолту. Основная часть.
Актуальность вопросов 7-10 лет ? Я рад что вы такого высокого мнение о вопросах ;) Спасибо за комментарий ;)
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38575238
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryДайте ссылку где это обсосано. Обоснование от вас не услышал.
Студенты тупеют духовно, и потому умнеть в плане мат/прог не могут по дефолту. Основная часть.
Актуальность вопросов 7-10 лет ? Я рад что вы такого высокого мнение о вопросах ;) Спасибо за комментарий ;) Ссылку ищите сами. Не надо плохо думать о студентах. Те которых я знаю, вполне достойные трудолюбивые люди. Пожалуйста.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38575262
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо, поищу. Может быть вы правы и я ошибаюсь
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38575305
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПочему именно полуоткрытые ? Закрытый интервал более читаем, так наверное. Неужели из-за индексации массивов с нуля ?
На закрытом диапазоне нельзя без костылей выразить пустой диапазон.
А на полуоткрытом - элементарно, указав два одинаковых индекса.
...
Рейтинг: 0 / 0
Ошибки в функции реверса каждого слова строки
    #38575882
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда уже какое-то противоречие [5,5) с одной стороны 5 принадлежит, а с другой нет. Если уж проблема в этом, то логичней выглядит полностью открытый промежуток (5,5)
...
Рейтинг: 0 / 0
151 сообщений из 151, показаны все 7 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ошибки в функции реверса каждого слова строки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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