Консультация № 189339
11.05.2016, 13:18
0.00 руб.
11.05.2016, 13:31
0 2 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:

Задание:
Дана строка, содержащая текст на естественном языке. Напишите
функцию, создающую новую строку, в которой все слова из старой строки следуют в
обратном порядке и разделены одним знаком пробела. Исходная строка может
содержать различные знаки-разделители (пробелы, запятые, точки и т.п.). Полный
набор знаков-разделителей передается функции при ее вызове.


Программа:
[code h=200]
#include "stdafx.h"
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

bool isDelimiter(char c, char *str)//Ограничитель
{
for (; *str; )
{
if (*str == c)
return 1;
str++;
}
return 0;
}

char *transpose(char *str, char *sym)
{
int length = strlen(str);//Длина строки
int n = -1;
char *c = &str[length - 1], *begin = c, *end = c,
*nstr = new char[length + 1];
cout << (*c) << endl;
while (c >= str)
{
while (isDelimiter(*c, sym) && c >= str)
begin--, end--, c--;
while (!isDelimiter(*c, sym) && c >= str)
{
begin--;
c--;
}
begin++;
char *b = begin;
while (b <= end)
{
nstr[++n] = *b;
b++;
}
nstr[++n] = ' ';
end = begin = c;
}
nstr[n] = '\0';
return nstr;
}

int main()
{
setlocale(LC_ALL, "Russian");
char *s = "Hello, World!} Example test";
char sep[] = " .,:;?!()[]{}";
char *c1 = transpose(s, sep);
cout << c1 << endl;
system("pause");
return 0;
}
[/code]

Можете рассказать, что мы делаем в функции transpose
и для чего на ф-ция ограничитель: isDelimiter???

Обсуждение

давно
Посетитель
7438
7205
11.05.2016, 14:01
общий
это ответ
Здравствуйте, Посетитель - 399158!
Комментарии в коде
Функция isDelimiter - не ограничитель, а ищет символ, переданный первым параметром,
в строке, переданной вторым параметром.
Используется для определения, является ли очередной символ разделителем или буквой
[code h=200]
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

bool isDelimiter(char c, char *str)//поиск символа c в строке str
{
for (; *str; )
{
if (*str == c)
return 1; //найдено - вернем 1
str++;
}
return 0; //не найдено - 0
}

char *transpose(char *str, char *sym)
{
int length = strlen(str); //длина исходной строки
int n = -1; //здесь будет длина результирующей строки
char *c = &str[length - 1]; //сквозной указатель от конца строки к ее началу
char *begin = c; //указатель на начало слова в строке
char *end = c; //указатель на конец слова
char *nstr = new char[length + 1]; //новая результирующая строка, ее длина не больше исходной
// cout << (*c) << endl; //это лишнее

while (c >= str) //начинаем с конца строки, пока не дойдем до ее начала
{
while (isDelimiter(*c, sym) && c >= str)
begin--, end--, c--;//пропускаем разделители
while (!isDelimiter(*c, sym) && c >= str)
{
begin--; //для букв ищем начало слова, end указывает на конец слова
c--;
}
begin++; //вернем на позицию начала слова, т.е. проскочили на разделитель перед словом
char *b = begin; //указатель на начало слова, можно было написать char *b = begin+1; (предыдущая команда не нужна)
while (b <= end) //копируем слово в новую строку от начала слова до конца
{
nstr[++n] = *b; //одновременно считаем лина строки-результата
b++;
}
nstr[++n] = ' '; //разделяем пробелом
end = begin = c; //готовимся к поиску нового слова
}
nstr[n] = '\0'; //завершающий 0 в строку-результат
return nstr; //вернем адрес новой строки
}

int main()
{
setlocale(LC_ALL, "Russian");
char *s = "Hello, World!} Example test";
char sep[] = " .,:;?!()[]{}";
char *c1 = transpose(s, sep);
cout << c1 << endl;
delete (c1); //не забывать освобождать память!
system("pause");
return 0;
}[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
11.05.2016, 14:04
общий
Адресаты:
Да и указатель b - лишний, вполне можно было обойтись begin
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа