Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "word_container.h"
- #include <fstream>
- #include <sstream>
- #include <cctype>
- #include <ostream>
- #include <iterator>
- #include <algorithm>
- #include <iomanip>
- #include <exception>
- Word_Container::Word_Container(std::string& file_name, std::string& in_argument, int number)
- : text_document{file_name}, argument{in_argument}, words{}, longest_word_length{0}, longest_number{0}, number{number}
- {
- Read_Words();
- }
- bool Word_Container::Check_Word(std::string &ord)
- {
- bool prev = false; //Är förgående karaktär en bokstav? False om första är '-'
- // Klar
- // Kommentar: om ni har en funktion som returnerar en bool kan ni
- // göra return-satsen direkt i if-satsen istället.
- if (ord.back() == '-') // Får ej avslutas med '-'
- return false;
- if (ord.size() < 3) // Måste var större än 2
- return false;
- // Klar
- // Komplettering: onödigt att gå igenom hela ordet för att se om det
- // är gilltigt. Så fort ni hittar något som är ogilltigt behöver ni
- // inte kolla mer. Kolla under "Non-modifying sequence operations"
- // i algorithm och se om ni hittar något som kan hjälpa er med detta
- return all_of(ord.begin(), ord.end(), [&prev](char c)
- {
- if(isalpha(c))
- {
- prev = false;
- return true;
- }
- else if ((c == '-') && !prev)
- {
- prev = !prev;
- return true;
- }
- return false;
- });
- }
- void Word_Container::Read_Words()
- {
- std::ifstream infil(text_document);
- if (!infil)
- throw std::invalid_argument("Not a valid file in this path");
- //Gör en lista med strängar av ord
- std::vector<std::string> content{ (std::istream_iterator<std::string>(infil) ),
- (std::istream_iterator<std::string>() ) };
- infil.close();
- // Klar
- // Komplettering: Ni bör inte göra kopior av alla strängar, kan bli
- // mycket ineffektivt om de är långa. Detta gäller på fler ställen i
- // filen.
- //Iterera över varje ord i vectorn och "tvättar" dem
- std::for_each(content.begin(), content.end(), [&](std::string &ord)
- {
- // Klar
- // Komplettering: onödigt att ni letar med find_first_not_of
- // respektive last 2-3 gånger för samma ord.
- // Raderar alla giltliga tecken framför orden
- ord.erase(0,ord.find_first_not_of("\"\'("));
- // Letar upp sista tecknet innan giltliga sluttecken kommer, tar sedan bort de giltliga teckena
- ord.erase(ord.find_last_not_of("\"!?;,:).\'")+1,ord.find_last_of("\"!?;,:).\'"));
- // Tar bort 's om det finns
- // Klar
- // Komplettering: 's får endast förekomma i slutet av ordet
- // efter att giltigt skräp tagits bort
- if((*(ord.end()-2) == '\'') && (*(ord.end()-1) == 's')) // Om den ej hittar sub-stringen returnerar den std::string::npos
- {
- ord.erase(ord.end()-2,ord.end());
- }
- // Nu är ordet "tvättat" och vi kan göra en if sats om ordet är giltligt.
- if(Check_Word(ord))
- {
- // Snyggt!
- transform(ord.begin(),ord.end(), ord.begin(),::tolower); //Till små bokstäver
- words.push_back(ord);
- }
- });
- // Klar
- // Komplettering: ni försöker hitta ett maximum här, kolla i
- // algorithm om det finns någon funktion som kan hjälpa er med
- // det
- auto biggest = std::max_element(words.begin(), words.end());
- if (biggest != words.end())
- longest_word_length = (*biggest).length();
- }
- // Klar
- // Komplettering: operator[] i map slår upp eller lägger till
- // element. Använd den istället för att själva kolla om elementet
- // finns
- void Word_Container::Make_Map(std::map<std::string, int> &final)
- {
- std::for_each(words.begin(), words.end(), [&final, this](std::string &str)
- {
- if (std::to_string(++final[str]).length() > longest_number)
- longest_number = std::to_string(final[str]).length();
- });
- }
- // Klar
- // Komplettering: Utskriften av siffrorna ska anpassas efter längsta
- // siffran. Vad skulle hända om vi har fler än 100 av samma ord?
- void Word_Container::Print()
- {
- if (argument == "-a")
- {
- std::map<std::string, int> final;
- Make_Map(final);
- std::for_each(final.begin(), final.end(), [this](const std::pair<std::string,int> &str)
- {
- std::cout.width(longest_word_length);
- std::cout << std::fixed << std::left << str.first << " " << std::right << std::setw(longest_number) << str.second << '\n';
- });
- }
- else if (argument == "-f")
- {
- std::map<std::string, int> final;
- Make_Map(final);
- std::vector<std::pair<std::string,int>> v;
- std::copy(final.begin(), final.end(),std::back_inserter<std::vector<std::pair<std::string,int>>>(v));
- std::sort(v.begin(), v.end(),[](const std::pair<std::string,int> &lhs, const std::pair<std::string,int> &rhs) {
- if (lhs.second != rhs.second)
- {
- return lhs.second > rhs.second;
- }
- return lhs.first < rhs.first;
- });
- std::for_each(v.begin(), v.end(), [&v, this]( std::pair<std::string,int> &str)
- {
- std::cout.width(longest_word_length);
- std::cout << std::fixed << std::right << str.first << " " << std::right << std::setw(longest_number) << str.second << '\n';
- });
- }
- else if (argument == "-o")
- {
- int antal_alpha = 0;
- std::for_each(words.begin(), words.end(), [&antal_alpha, this](std::string &str)
- {
- if(signed(str.length()) < number-antal_alpha)
- {
- std::cout << str << " ";
- antal_alpha += str.length() + 1;
- }
- else
- {
- std::cout << "\n" << str << " ";
- antal_alpha = str.length() + 1;
- }
- });
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement