0

I am trying to make a program which takes a text file with words and letters with which it outputs the longest word it can create with the letters you provided.

This is the code:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <unordered_set>
#include <cstring>
#include <chrono>

using namespace std;
using namespace std::chrono;

bool can_make (string word, unordered_set<char> letters);

int main (int argc, char* argv[]) {
    fstream dict_file(argv[1]);
    unordered_set<char> letters;
    unordered_set<string> words;
    string word;
    size_t max_len = 0;

    for (int i = 2; i < argc; i++) {
        for (int j = 0; j < strlen(argv[i]); j++) {
            letters.insert(argv[i][j]);
        }
    }

    while (getline(dict_file, word)) {
        if (word.length() > max_len && can_make(word, letters)) {
            words.clear();
            max_len = word.length();
            words.insert(word);
        } else if (word.length() == max_len && can_make(word, letters)) {
            words.insert(word);
        }
    }
    dict_file.close();

    auto start = high_resolution_clock::now();

    cout << "Words: ";
    for (string word : words) {
        cout << word << " ";
    }

    cout << "\n" << endl;
    auto stop = high_resolution_clock::now(); 
    auto duration = duration_cast<microseconds>(stop - start);
    cout << "Time elapsed: " << (duration.count()) << " microseconds" << endl;
    cout << endl;

    return 0;
}

bool sort_func (string first, string second) {
    return first.length() > second.length();
}

bool can_make (string word, unordered_set<char> l) {
    for (char i : word) {
        if (l.find(i) == l.end()) return false;
    }
    return true;
}

I want to make the code as fast as possible, and the only thing that is taking a long time is the file reading. Is there a way to read a file faster?

Sencres
  • 3
  • 1
  • 2
    Code Review might be a better place, but a few things. Pass by reference, not copy. Reserve space for your `unodered_set`s – ChrisMM Apr 09 '20 at 16:49
  • Maybe you could use some kind of buffering or try to process the data while you haven't finished reading the file or use two threads(one for reading and one for processing the data) – dan1st Apr 09 '20 at 16:50
  • you could read the whole file at once and only then split the lines. – 463035818_is_not_an_ai Apr 09 '20 at 16:56
  • Are you _sure_ can_make is not taking the time ? – Jeffrey Apr 09 '20 at 16:58
  • Thank you for the comments! I will modify my code and see how it performs. – Sencres Apr 09 '20 at 16:59
  • That and passing the unordered set by value. – Jeffrey Apr 09 '20 at 17:01
  • @JeffreysupportsMonica I put a timer before and after the file reading and the difference was from 400-500 microseconds to 0-1 microseconds so I'm sure that can_make is not taking the time – Sencres Apr 09 '20 at 17:01
  • 1
    Don't trust time readings below a few milliseconds on PC hardware running a Desktop OS.They're not built for reliable time. – user4581301 Apr 09 '20 at 17:14
  • 1
    https://stackoverflow.com/questions/5166263/how-to-get-iostream-to-perform-better – rustyx Apr 09 '20 at 18:07
  • related to @idclev463035818 -- consider slurp() (search on-line 'c++ slurp' ) ... my version reads the whole file into a stringstream. Once there, all read operations are from ram. – 2785528 Apr 09 '20 at 19:03

0 Answers0