2015-05-01 4 views
1

Я написал программу для хранения текстового файла в векторе символов.Подсчет вхождений слова в вектор символов

#include<iostream> 
#include<fstream> 
#include <algorithm> 
#include<vector> 
using namespace std; 

int main() 
{ 
    vector<char> vec; 
    ifstream file("text.txt"); 

    if(!file.eof() && !file.fail()) 
    { 
     file.seekg(0, std::ios_base::end); 
     std::streampos fileSize = file.tellg(); 
     vec.resize(fileSize); 

     file.seekg(0, std::ios_base::beg); 
     file.read(&vec[0], fileSize); 
    } 

    int c = count(vec.begin(), vec.end(), 'U'); 
    cout << c; 
    return 0; 
} 

Я хочу считать появление «USER» в текстовом файле, но с использованием счета я могу рассчитывать только количество символов. Как я могу подсчитать количество вхождений «USER» в вектор символа?

Например text.txt

USERABRUSER#$$* 34 USER ABC RR IERUSER 

Затем счетчик "USER" является 4. Слова могут быть только в верхнем регистре.

+1

Определите, что вы подразумеваете под словом. Кроме того, ваш IO не совсем прав: более идиоматично тестировать с помощью 'file.is_open()' после открытия; что более важно, 'file.read', скорее всего, не удастся, так как способ вычисления размера не будет работать на платформах, отличных от Unix. –

+0

Я обновил вопрос. –

ответ

3

std::string имеет функцию find члена, который будет искать вхождение одной строки внутри другой. Вы можете использовать это, чтобы рассчитывать вхождений что-то вроде этого:

size_t count(std::string const &haystack, std::string const &needle) { 
    auto occurrences = 0; 
    auto len = needle.size(); 
    auto pos = 0; 

    while (std::string::npos != (pos = haystack.find(needle, pos))) { 
     ++occurrences; 
     pos += len; 
    } 
    return occurrences; 
} 

Например:

int main() { 
    std::string input{ "USERABRUSER#$$* 34 USER ABC RR IERUSER" }; 

    std::cout << count(input, "USER"); 
} 

... производит выход 4.

+0

Это решает проблему, но мне предложили использовать вектор символов и функцию подсчета .... Но спасибо в любом случае ... –

2

Это, как я хотел бы сделать это:

#include <fstream> 
#include <sstream> 
#include <iostream> 
#include <unordered_map> 
#include <string> 

using namespace std; 

int main() { 
    unordered_map<string, size_t> data; 
    string line; 
    ifstream file("text.txt"); 
    while (getline(file, line)) { 
     istringstream is(line); 
     string word; 
     while (is >> word) { 
     ++data[word]; 
     } 
    } 

    cout << data["USER"] << endl; 
    return 0; 
} 
+0

Хотя это (по крайней мере, возможно) соответствует вопросу, как первоначально было опубликовано, оно не соответствует редактируемому вопросу. В любом случае, это потенциально довольно неэффективно, сохраняя большое количество данных, для которых он не имеет реального использования. Это примерно эквивалентно ответу: «Сколько детей в классе этого учителя?» проведя перепись всей страны, а затем проверив, сколько из этих людей находится в рассматриваемом классе. –

+0

Ваша аналогия неверна. Я не увеличиваю размер данных, которые необходимо обработать. Мы обрабатываем один и тот же объем данных (т. Е. Файл), однако я делаю больше работы за элемент, чем вы. Мое решение позволяет легче отвечать на дополнительные вопросы и является более общим решением. Невозможно добавить какое-либо значение в OP, но может быть полезным для других, которые пытаются ответить на аналогичную проблему и должны запрашивать обработанный набор данных более чем на одно слово. В любом случае, если OP не хочет сохранять результаты в unordered_map, он может удалить функциональность и продолжить свою работу. –

0

Давайте попробуем еще раз. Опять же, вектор не нужен. Это то, что я считал бы самым идиоматическим способом C++. Он использует метод std::stringfind() для многократного поиска подстроки по порядку до тех пор, пока не будет достигнут конец строки.

#include <fstream> 
#include <iostream> 
#include <string> 

int main() { 
    // Read entire file into a single string. 
    std::ifstream file_stream("text.txt"); 
    std::string file_contents(std::istreambuf_iterator<char>(file_stream), 
     std::istreambuf_iterator<char>()); 

    unsigned count = 0; 
    std::string substr = "USER"; 
    for (size_t i = file_contents.find(substr); i != std::string::npos; 
     i = str.find(substr, i + substr.length())) { 
     ++count; 
    } 
} 
+0

проверить обновленный вопрос –

Смежные вопросы