Допомога - Пошук - Користувачі - Календар
Программа
XJedi FORUM: Online lightsaber fighting game > Всяка всячина > Кантіна > Web, Hard & Soft
Nikooz
Помогите доделать прогу, плз)
Задача: открыть текстовый файл и посчитать:
-кол-во линий
-кол-во предложений
-кол-во слов
-кол-во символов
-вывести на экран в каждом 5м слове 5й(или 1й, если не выйдет 5й) символ.

Сделал первые 4, не могу придумать, как заставить его выписывать 5й символ из каждого 5го слова...
my code:


Заранее спасибо!
Malfurion
Не помню уже по синтаксису, но логическая цепь для построения тела:
1)[Програма собирает все слова и называет их "1";"2";..."n";]
2)[Прямым перебором в матрицу записывается каждый 5 номер, тоесть надо дописать функцию, которая бы взяла число номеров до "n" и скомпилировала каждое в целые числа 1,2,3...n; дальше записала бы каждый кратный 5-ти во вторую матрицу, где бы компилировались обратно в знаки]
3)[Опять же перебором матрицы берет каждый элемент матрицы(тоесть каждое слово, названое "5","10"..."k") и отсчитала бы в них 5 символ, который бы записывала в отдельный файл, или выводила на экран]

Минус цепи: Программа не будет смотреть на 5 символ, буква этот или нет, а значит есть вероятность того, что может попасть в список и точка с запятой и "левая" буква.
Sphinx
int flag,flag2;
char tempC;

flag = 0;
flag2 = 0;
tempC = '';

Вносим изменения в функцию подсчета слов.
if((c==' ') || (c=='.'))
{
wo++;
flag++;
if(flag == 4)
{
flag = 0;
flag2 = 0;
(тут открываем посимвольно новый цикл, записывая каждый следующий символ в tempc и наращиваем flag2 и когда доходим до 5го проверяем, что это за символ. C++ каменный век!)
for(;flag2<5;flag2++)
{
tempC = (сам напишешь чему);
if(tempC == ' ' || tempC == '.')
break;
}
if(tempC==' ' || tempC=='.')
printf( с ); (не помню синтаксиса)
else
printf(tempC);
}
}

Код серьезно не рассматривал так что сможешь опитимизировать по своему.

З.Ы. В C# все задачи выполняются в 3 строчки ^^.
Sphinx
По просьбе лентяев второй алгоритм решения


int flag = 0; //переменная-счетчик для 5го слова
int flag2 = 0; // переменная счетчик для 5го символа
char tempC = ''; // временная переменная для сохранения 1го символа 5го слова
bool timer = false; //переменая ключ для наращивания flag2

while (!feof(file))
{
c=fgetc(file);



//Вывод 5го символа с проверкой.
-----------------------------------
if(flag==4)
{
tempC = c;
flag=0;
timer = true;
}

if(timer == true)
{
flag2++;
}

if( (c == ' ' || c == '.') && flag == 0 && flag2<4)
{
printf(tempC);
flag2 = 0;
timer = false;
}

if(flag==0 && flag2 == 4)
{
printf( c );
flag2 = 0;
timer = false;
}
-------------------------------------

if((c!='\0') && (c!='\n') && (c!='\t') && (c!='\r') && (c!=EOF))
{
ch++;
}

if(c=='\n')
{
ln++;
}

if(c=='.')
{
se++;
}

if((c==' ') || (c=='.'))
{
wo++;
flag++;
}
}
Kol-yan
По твоему коду много замечаний, поэтому решил свой писать)
Во-первых, если ты уже написал "using namespace std", то не использовать стандартную библиотеку и STL просто грешноad.gif
Во-вторых, код надо как-то разбивать на блоки, чтобы он был более читаемый. Когда функция main() это ФункцияКотораяДелаетВсеСразуКучей() , то что-то понять очень сложно)
В-третьих, надо комментировать, а то спустя какое-то время уже и сам ниче не поймешь)

Например, код программы, которая считает кол-во букв и слов в тексте я себе представляю как-то так, инструкциями дополни на свое усмотрение:

#include <iostream>
#include <fstream>

bool IsSeparator(char symbol);

int main (int argc, const char * argv[])
{  
    std::string path;
    std::ifstream filestr;

    while(!filestr.is_open()) //пытаемся открыть файл, пока не введем правильный путь
    {
        std::getline(std::cin, path);
        filestr.open (path.c_str(), std::fstream::out);
    }

    char curSymbol;
    int symbols = 0, words = 0, symbol_count = 0;
    while(filestr.good()) //пока из файла можем считать - считываем
    {
        filestr.get(curSymbol);
        std::cout<< curSymbol;

        if(IsSeparator(curSymbol)) //определяем буква это или какой-то разделитель
        {
            if(symbol_count>0)  //если перед этим уже встречались буквы, то это конец слова.
                                //Добавляем к счетчику слов и обнуляем счетчик букв текущего слова
            {
                symbol_count = 0;
                words++;
            }
        }
        else //если это буква, то добавляем к счетчику букв и счетчику текущего слова.
        {
            symbol_count++;
            symbols++;
        }
    }
    std::cout<< "words: " << words << std::endl << "symbols: " << symbols << std::endl;
    return 0;
}

bool IsSeparator(char symbol)
{
    char separators[] = {'\n', '\t', ' ', '.', ',', '!', '?', '\0'}; //список символов, которые мы будем считать разделителями
    for (int i = 0; separators[i]!='\0'; i++)
    {
        if(symbol == separators[i])
            return true;
    }
    return false;
}


Вот вокруг этого можно уже накручивать оставшуюся часть задания.

На счет пятого задания. Там все тоже самое, просто несколько дополнительных счетчиков добавить. Но я бы вообще отошел от этого и воспользовался регулярными выражениями. Для обработки строк ничего удобнее нет - пусть сперва кажется чем-то дремучим, но на самом деле разобраться можно быстро. Разве что сложность может вызвать выбор интерпретатора и его подключение к проекту. Они есть разные, в разных библиотеках, в Qt есть, в Boost... На последнем и остановимся, как на самом популярном - Boost.Regex.
Сами выражения можно проверять и онлайн.
Собственно код будет выглядеть так для твоего пятого задания(с двумя решениями, так как условие неоднозначное - что если в пятом слове меньше пяти букв?)

#include <iostream>
#include <boost/regex.hpp>

int counter = 0;

void FindWordsByPattern(std::string s, std::string pattern);
void PrintWords (boost::smatch result);

int main (int argc, const char * argv[])
{
    std::string inputString;
    std::getline(std::cin, inputString);
    
    std::cout << "Search only words with 5+ symbols:" << std::endl;
    FindWordsByPattern(inputString, "[\\w+]{5,}");  // ищем все слова содержащие больше 5-и символов и в
                                                    // каждом 5-м из найденных печатаем 5-й символ
    counter = 0;
    
    std::cout << "Search all words(if size < 5 then print first symbol):" << std::endl;
    FindWordsByPattern(inputString, "\\w+"); // ищем все слова и печатаем в каждом 5-м слове 5-й(если нету, то 1-й) символ
    
    return 0;
}

void FindWordsByPattern(std::string s, std::string pattern)
{
    boost::regex exp(pattern); //собственно регулярно выражение
    
    boost::sregex_iterator it(s.begin(), s.end(), exp);
    std::for_each(it, boost::sregex_iterator(), PrintWords); //для всех найденных вхождений вызываем PrintWords
}
void PrintWords (boost::smatch result)
{
    counter++;
    if (counter == 5)
    {
        counter = 0;
        int symbol_index = (result.str().size() < 5) ? 0 : 4;
        std::cout << "Word: " << result.str() << "; Letter: "<< result.str()[symbol_index]<<std::endl;
    }
}


Как-то так _a1.gif
Удачи в учебе!
Nikooz
Большущее спасибо за помощь!) Особенно Kol-yan 'у! Благодаря твоим программам я придумал, как решить свою задачу более простым способом х)
.
Invision Power Board © 2001-2025 IPS , Inc.