Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный платный хостинг на базе Windows 2008

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Чемпионы рейтинга экспертов в этой рассылке

_Ayl_
Статус: Студент
Рейтинг: 1414
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 1298
∙ повысить рейтинг »
Micren
Статус: Бакалавр
Рейтинг: 1162
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И ПО / Программирование / C/C++

Номер выпуска:1433
Дата выхода:01.12.2009, 09:00
Администратор рассылки:Dr_Andrew, Старший модератор
Подписчиков / экспертов:676 / 183
Вопросов / ответов:1 / 1
IRC-канал по теме:#C

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



Вопрос № 174551:

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

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

Отправлен: 26.11.2009, 08:46
Вопрос задал: Jekaiseburga, Посетитель
Всего ответов: 1
Страница вопроса »


Отвечает Micren, Бакалавр :
Здравствуйте, Jekaiseburga.
Так это можно сделать при помощи STL. Microsoft Visual C++/Visual Studio 2008.
Самое главное прокомментировано.
Программа.
Код:
#include <iostream>
#include <iomanip>
#include <valarray>
#include <locale>
#include <limits>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

// Тип - вектор для хранения строк
typedef vector<wstring> string_vector;

int menu();
void addStrings(string_vector& strings);
void showStrings(const wstring& message,const string_vector& strings);
void findMaxWord(const string_vector& strings);

int main()
{
locale::glob al(locale("russian_russia.866"));
string_vector strings;
while(true)
{
switch(menu())
{
case 0:
return 0;
case 1:
addStrings(strings);
break;
case 2:
showStrings(L"Имеются следующие строки:",strings);
break;
case 3:
findMaxWord(strings);
break;
}
}
return 0;
}

// Выводит меню
int menu()
{
while(true)
{
wcout<<L"Сделайте свой выбор:"<<endl
<<L"1 - Добавление строк"<<endl
<<L"2 - Показать строки"<<endl
<<L"3 - Поиск самого длинного слова в строке"<<endl
<<L"0 - Выход"<<endl;
wint_t choice=_getwche();
wcout<<endl;
switch(choice)
{
case L'0':
case L'1':
case L'2':
case L'3':
return choice-L'0';
default:
wcout<<L"Будьте внимательней"<<endl;
}
}
}

// Добавляет строки к вектору
void addStrings(string_vector& strings)
{
wcout<<L"Вводите строки(пустая строка для завершения):"<<endl;
while(true)
{
wstring str;
getline(wcin,str);
if(str.empty())
{
return;
}
strings.push_back(str);
}
}

// Выводит строки на stdout
void showStrings(const wstring& message,const string_vector& strings)
{
wcout<<message<<endl;
string_vector::size_type i=0,size=strings.size();
streamsize width=static_cast<streamsize>(log10(static_cast<double>(size))+1);
while(i<size)
{
wcout<<setw(width)<<i+1<<L" - \""<<strings[i]<<L'"'<<endl;
++i;
}
}

// Ищет все слова с максимальной длиной в строке
string_vector maxWord(const wstring& str)
{
// Результат будет здесь
string_vector result;

// Итераторы на начало и конец
wstring::const_iterator it=str.begin(),end=str.end();

// Найденная максимальная длина слова
wstring::size_type maxLength=0;

// Этот адаптер для того, чтоб использовать функцию iswspace() в качестве предиката
static pointer_to_unary_function<wint_t,int> wsPredicate=ptr_fun(iswspace);

// Пока не конец строки
while(it!=end)
{
// Ищем начало слова
wstring::const_iterator beginWord=find_if(it,end,not1(wsPredicate));
// Ищем конец слова
wstring::const_iterator endWord=find_if(beginWord,end,wsPredicate);

// Если не пусто
if(beginWord!=endWord)
{
// Наше слово
wstring word(beginWord,endWord);
// Его длина
wstring::size_type wordSize=word.size();
// Если нашли более длинное
if(wordSize>maxLength)
{
// Очистим результат
result.clear();
// И у становим новую длину
maxLength=wordSize;
}
// Если нашли с такой же длиной
if(wordSize==maxLength)
{
// Сохраним
result.push_back(word);
}
}
it=endWord;
}
return result;
}

// Ищет максимальное слово в заданной строке
void findMaxWord(const string_vector& strings)
{
string_vector::size_type size=strings.size();
if(!size)
{
wcout<<L"Список пуст"<<endl;
return;
}
string_vector::size_type strNo;
wcout<<L"Введите номер строки:";
wcin>>strNo;
if(wcin.fail())
{
wcout<<L"Неверный ввод"<<endl;
wcin.clear();
wcin.ignore(numeric_limits<streamsize>::max(),L'\n');
return;
}
wcin.ignore(numeric_limits<streamsize>::max(),L'\n');
if(strNo>0 && strNo<size+1)
{
string_vector words=maxWord(strings[strNo-1]);
if(words.size())
{
showStrings(L"Найдены следующие слова(слово) с максимальной длиной:",words);
}
else
{
wco ut<<L"Нет слов в выбранной строке"<<endl;
}
return;
}
else
{
wcout<<L"Неверный номер строки"<<endl;
}
}

Пример работы:
Код:
Сделайте свой выбор:
1 - Добавление строк
2 - Показать строки
3 - Поиск самого длинного слова в строке
0 - Выход
1
Вводите строки(пустая строка для завершения):
Как известно, с одним оператором try
можно связывать несколько операторов catch.
Именно такой вариант используется чаще всего.
Однако каждый оператор catch должен перехватывать
отдельный тип исключительной ситуации

Сделайте свой выбор:
1 - Добавление строк
2 - Показать строки
3 - Поиск самого длинного слова в строке
0 - Выход
2
Имеются следующие строки:
1 - "Как известно, с одним оператором try"
2 - "можно связывать несколько операторов catch."
3 - "Именно такой вариант используется чаще всего."
4 - "Однако каждый оператор catch должен перехватывать
5 - "отдельный тип исключительной ситуации"
Сделайте свой выбор:
1 - Добавление строк
2 - Показать строки
3 - Поиск самого длинного слова в строке
0 - Выход
3
Введите номер строки:1
Найдены следующие слова(слово) с максимальной длиной:
1 - "оператором"
Сделайте свой выбор:
1 - Добавление строк
2 - Показать строки
3 - Поиск самого длинного слова в строке
0 - Выход
3
Введите номер строки:2
Найдены следующие слова(слово) с максимальной длиной:
1 - "операторов"
Сделайте свой выбор:
1 - Добавление строк
2 - Показать строки
3 - Поиск самого длинного слова в строке
0 - Выход
3
Введите номер строки:3
Найд ены следующие слова(слово) с максимальной длиной:
1 - "используется"
Сделайте свой выбор:
1 - Добавление строк
2 - Показать строки
3 - Поиск самого длинного слова в строке
0 - Выход
4
Будьте внимательней
Сделайте свой выбор:
1 - Добавление строк
2 - Показать строки
3 - Поиск самого длинного слова в строке
0 - Выход
3
Введите номер строки:4
Найдены следующие слова(слово) с максимальной длиной:
1 - "перехватывать"
Сделайте свой выбор:
1 - Добавление строк
2 - Показать строки
3 - Поиск самого длинного слова в строке
0 - Выход
3
Введите номер строки:5
Найдены следующие слова(слово) с максимальной длиной:
1 - "исключительной"


По Вашей просьбе добавил пример без STL.
Код:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <loc ale.h>
#include <string.h>
#include <math.h>
#include <ctype.h>

struct string_array
{
char** data;
size_t count;
string_array()
:data(0)
,count(0)
{}
};

int menu();
void addStrings(string_array& strings);
void showStrings(const char* const message,const string_array& strings);
void findMaxWord(const string_array& strings);
void delArray(string_array& strings);

int main()
{
setlocale(LC_ALL,"russian");

string_array strings;

while(true)
{
switch(menu())
{
case 0:
delArray(strings);
return 0;
case 1:
addStrings(strings);
break;
case 2:
showStrings("Имеются следующие строки:",strings);
break;
case 3:
findMaxWord(strings);
break;
}
}
return 0;
}

int menu()
{
while(true)
{
printf("Сделайте свой выбор:\n"\
" 1 - Добавление строк\n"\
"2 - Показать строки\n"\
"3 - Поиск самого длинного слова в строке\n"\
"0 - Выход\n"\
":");
int choice=_getche();
printf("\n");
switch(choice)
{
case '0':
case '1':
case '2':
case '3':
return choice-'0';
default:
printf("Будьте внимательней\n");
}
}

}

#pragma warning(disable:4996 4800)

void getString(char** str)
{
char* result=0;
const size_t BufferSize=512;
char buffer[BufferSize];
bool not_eos=true;
while(not_eos)
{
char* ptr=fgets(buffer,BufferSize,stdin);
if(ptr)
{
size_t len=strlen(ptr);
if(!(not_eos=ptr[len-1]!='\n'))
{
ptr[len-1]='\0';
--len;
}
if(result)
{
len+=strlen(result)+1;
char* newPtr=(char*)realloc(resu lt,len);
if(newPtr)
{
result=newPtr;
strcat(result,ptr);
}
else
{
printf("Невозможно выделить память\n");
return;
}
}
else
{
result=(char*)malloc(len+1);
if(result)
{
strcpy(result,ptr);
}
else
{
printf("Невозможно выделить память\n");
return;
}
}

}
else
{
printf("Ошибка ввода");
return;
}
}
*str=result;
}

void addStrings(string_array& strings)
{
printf("Вводите строки(пустая строка для завершения):\n");
while(true)
{
char* str=0;
getString(&str);
if(!(str && strlen(str)))
{
return;
}
size_t newSize=strings.count+1;
char** newPtr;
if(strings.data)
{
newPtr=(char**)realloc(strings.data,sizeof(char**)*newSize);
}
else
{
newPt r=(char**)malloc(sizeof(char**)*newSize);
}
if(newPtr)
{
strings.data=newPtr;
strings.count=newSize;
strings.data[newSize-1]=str;
}
else
{
printf("Невозможно выделить память\n");
}
}
}

void showStrings(const char* const message,const string_array& strings)
{
printf("%s\n",message);
char* const* const dataPtr=strings.data;
char* const* const end=dataPtr+strings.count;
size_t width=strings.count?(size_t)log10((double)strings.count)+1:0;
for(size_t i=0;i<strings.count;++i)
{
printf("%*u - \"%s\"\n",width,i+1,strings.data[i]);
}
}

void delArray(string_array& strings)
{
if(strings.data)
{
for(size_t i=0;i<strings.count;++i)
{
free(strings.data[i]);
}
free(strings.data);
strings.data=0;
strings.count=0;
}
}

const char* find_if(const char* it,bool (predicate)( char))
{
if(it)
{
while(*it && !predicate(*it))
{
++it;
}
}
return it;
}

bool isNotWS(ch ar ch)
{
return !isspace(ch);
}

bool isWS(char ch)
{
return isspace(ch);
}

void findMaxWord(const string_array& strings)
{
if(!strings.count)
{
printf("Нет строк\n");
return;
}
size_t numStr;
printf("Введите номер строки:");
scanf("%u",&numStr);
if(--numStr<strings.count)
{
size_t maxLength=0;
const char* pos=0;
const char* ch=strings.data[numStr];
while(*ch)
{
const char* beginWord=find_if(ch,isNotWS);
const char* endWord=find_if(beginWord,isWS);
if(beginWord!=endWord)
{
size_t wordSize=endWord-beginWord;
if(wordSize>maxLength)
{
maxLength=wordSize;
pos=beginWord;
}
}
ch=endWord;
}
if(pos)
{
printf("Самое длинное слово:");
for(size_t i=0;i<maxLength;++i)
{
putch(pos[i]);
}
printf("\n") ;
}
else
{
printf("Слов нет\n");
}
}
else
{
printf("Нет такой строки\n");
}
}

Ответ отправил: Micren, Бакалавр
Ответ отправлен: 26.11.2009, 12:22

Оценка ответа: 5

Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 256954 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:
  • Вам помогли? Пожалуйста, поблагодарите эксперта за это!


    Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2009, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2009.6.12 от 30.11.2009

    В избранное