PDA

Просмотр полной версии : Программа


Hantet
26.05.2010, 20:41
Задали по программированию задачку, с виду ну очень простая, но никак не подойти к ней правильно :(



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



Я сразу попробовал так:


#include <iostream>
#include <string.h>
#include <stdio.h>
#include <conio.h>

using namespace std;

void main()
{
char *str1; //весь текст
char *str2; //сюда записываются предложения (по очереди)
char *str3; //искомое слово
unsigned int i,next=0;
scanf("%s", &str1);
scanf("%s", &str3);
for(i=0;i<strlen(str1);i++)
{
strcat(str2, str1[i]); //дописываем в str2 (предложение) букву
if(str1[i] == '.')
{
while(strstr(str2, str3)) //ищем вхождения
next++;
printf("%s (%i)", str2, next); //вывод предожения и кол-во повторений слова
next = 0; //обнуляем кол-во повторений слова
str2 = ""; //обнуляем текущее предложение
}
}
getch(); //ждём нажатия Enter
}



Компилятор ругается:


strcat: невозможно преобразовать параметр 2 из 'char' в 'const char *'


к тому же, если в тексте сделать пробел, то в переменную запишется только текст до пробела.

Буду очень благодарен за помощь, программу кровь из носа надо написать :(

Astellar
28.05.2010, 18:55
Ну вот опять-двадцать пять. Ограничения на инструментарий-то какие? С++ и STL использовать можно?

Konctantin
28.05.2010, 20:07
Ну если на то пошло то можно и язык другой использовать:

static void Main(string[] args)
{
string text = "В отношении надежности протоколов более низкого, чем TCP, уровня сделаны весьма скромные запросы. TCP предполагает, что он может получить простой, (TCP, TCP)потенциально ненадежный сервис для своих датаграмм со стороны протоколов нижнего уровня. В принципе, протокол TCP должен быть работоспособен на большом наборе коммуникационных систем, начиная с кабельных соединений и кончая сетями с переключением пакетов или электрических цепей";
string searchText = "TCP";

foreach (string str in text.Split('.'))
{
int count = 0;
foreach (string t in str.Split(' '))
{
if (t.Contains(searchText))
++count;
}
Console.WriteLine(@"{0} - [{1}]", str, count);
}
Console.ReadLine();
}

или еще проще

static void Main(string[] args)
{
string text = "В отношении надежности протоколов более низкого, чем TCP, уровня сделаны весьма скромные запросы. TCP предполагает, что он может получить простой, (TCP, TCP)потенциально ненадежный сервис для своих датаграмм со стороны протоколов нижнего уровня. В принципе, протокол TCP должен быть работоспособен на большом наборе коммуникационных систем, начиная с кабельных соединений и кончая сетями с переключением пакетов или электрических цепей";
string searchText = "TCP";

foreach (string str in text.Split('.'))
{
int count = str.Split(' ').Where(n => n.Contains(searchText)).Count();
Console.WriteLine(@"{0} - [{1}]", str, count);
}

Console.ReadLine();
}

Astellar
28.05.2010, 21:01
Не совсем катит. Что будет для чисел вида 1.2345? А также для вопросительных и восклицательных предложений :)

Konctantin
28.05.2010, 23:39
Ну это уже условия, суть то одна.

Astellar
29.05.2010, 00:15
А вот нет, суть ой какая разная будет, если условия учесть. А их надо учитывать. Вот более правильный вариант, использующий регулярные выражения. И почему никто о них не вспоминает, когда текст обработать надо?
#include <regex>
#include <iostream>

// just a short name to use
typedef std::tr1::sregex_token_iterator tokenizer;

int main(int argc, char* argv[])
{
// to show russian text correctly
setlocale(LC_ALL, "rus_rus.1251");

// sample text with different types of delimiters
const std::string text = "Это наше предложение номер 1!!!!\n" \
"А это - номер два, так ведь?!\t\t " \
"Ну и, конечно же, с числами 3.1415 и 2^10... " \
"И заодно проверим прямую речь: \"Ты почто боярыню обидел, смерд?\".";

// a pattern to split nearly any text into sentences
// note that we preserve all odd spaces, etc.
const std::tr1::regex text_to_sent_p("([^.?!]|\\.\\d+|[.?!]+\")+[.?!]+");

// your input word must be wrapped into regex
// btw, we can even search for multiple words at once
const std::tr1::regex input_str_p("номер");

const tokenizer end; int word_count = 0;
for (tokenizer i(text.begin(), text.end(), text_to_sent_p); i != end; ++i)
{
std::string sentence((*i).str());
for (tokenizer j(sentence.begin(), sentence.end(), input_str_p); j != end; ++j)
++word_count;

std::cout << sentence << " " << word_count;

word_count = 0;
}

return 0;
}

Немного пояснений: во-первых, регистр букв учитывается при поиске слова, а во-вторых, ищется именно вхождение слова в предложение (т.е. в слове Пятница будет например найдено слово Пятниц).