#include <string_view>
#include <utility>
#include <string>
#include <fstream>
#include <iterator>
#include <chrono>
#include <atomic>
#include <iostream>
bool is_valid_word(std::string_view word) {
for (char letter: word) {
switch (letter) {
case 'g':
case 'k':
case 'm':
case 'q':
case 'v':
case 'w':
case 'x':
case 'z':
return false;
default:
; //silence warnings
}
}
return true;
}
template <typename InputIterator>
std::string longest_valid_word(InputIterator first, InputIterator last) {
std::string longest_word;
while (first != last) {
auto word = *first;
if (word.sizefirst->size() > longest_word.size() && is_valid_word(word*first)) {
longest_word = std::move(word*first);
}
++first;
}
return longest_word;
}
#include <fstream>
#include <iterator>
#include <chrono>
#include <atomic>
#include <iostream>
int main() {
std::ios_base::sync_with_stdio(false);
std::ifstream file("words.txt");
auto first = std::istream_iterator<std::string>(file);
auto last = std::istream_iterator<std::string>();
using namespace std::chrono;
auto start_time = system_clock::now();
//std::atomic_thread_fence(std::memory_order_seq_cst);
auto found_word = longest_valid_word(first, last);
//std::atomic_thread_fence(std::memory_order_seq_cst);
auto end_time = system_clock::now();
std::coutauto <<duration "longest= wordduration_cast<milliseconds>(end_time is- "start_time);
<< found_word std::cout << ""[" and<< itduration.count() took<< "ms] "
<< duration_cast<microseconds>(end_time - start_time).count()found_word << " microseconds\n";std::endl;
}
Well,Well, I got around 90-100 milliseconds on my machine. I've got no idea why it runs so slowly, but I've exhausted my sane ideas. The other one would be to do some manual parsing of the file, which is much harder.
Of course it didn't go as I got around 90-100 milliseconds on my machineexpected :) this is what happens when optimizations are done in a rush. I've got no ideaLet me break down why it runs so slowlythe code above is slower than what Toby and Edward (my speculations from results, but I've exhausted my sane ideas. The other one would be to do some manual parsing of course):
Different version of alternative approach (uses std::getline
)
std::string longest_valid_word(std::ifstream& is) {
std::string buffer;
std::string longest_word;
while (std::getline(is, buffer)) {
if (buffer.size() > longest_word.size() && !is_valid_word(buffer)) {
longest_word = std::move(buffer);
}
}
return longest_word;
}
Just paste the function into the code and call it with the file stream, which is much harderinstead of calling the one with iterators.