Advertisement
perjespersson

CC-fil

Apr 11th, 2019
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.69 KB | None | 0 0
  1. #include "word_container.h"
  2. #include <fstream>
  3. #include <sstream>
  4. #include <cctype>
  5. #include <ostream>
  6. #include <iterator>
  7. #include <algorithm>
  8. #include <iomanip>
  9. #include <exception>
  10.  
  11.  
  12. Word_Container::Word_Container(std::string& file_name, std::string& in_argument, int number)
  13.   : text_document{file_name}, argument{in_argument}, words{}, longest_word_length{0}, longest_number{0}, number{number}
  14.   {
  15.     Read_Words();
  16.   }
  17.  
  18. bool Word_Container::Check_Word(std::string &ord)
  19. {
  20.   bool prev = false;   //Är förgående karaktär en bokstav? False om första är '-'
  21.  
  22.   // Klar
  23.   // Kommentar: om ni har en funktion som returnerar en bool kan ni
  24.   // göra return-satsen direkt i if-satsen istället.
  25.   if (ord.back() == '-')      // Får ej avslutas med '-'
  26.     return false;
  27.  
  28.   if (ord.size() < 3)           // Måste var större än 2
  29.     return false;
  30.  
  31.   // Klar
  32.   // Komplettering: onödigt att gå igenom hela ordet för att se om det
  33.   // är gilltigt.  Så fort ni hittar något som är ogilltigt behöver ni
  34.   // inte kolla mer.  Kolla under "Non-modifying sequence operations"
  35.   // i algorithm och se om ni hittar något som kan hjälpa er med detta
  36.   return all_of(ord.begin(), ord.end(), [&prev](char c)
  37.   {
  38.     if(isalpha(c))
  39.     {
  40.       prev = false;
  41.       return true;
  42.     }
  43.     else if ((c == '-') && !prev)
  44.     {
  45.       prev = !prev;
  46.       return true;
  47.     }
  48.     return false;
  49.   });
  50. }
  51.  
  52. void Word_Container::Read_Words()
  53. {
  54.   std::ifstream infil(text_document);
  55.   if (!infil)
  56.     throw std::invalid_argument("Not a valid file in this path");
  57.  
  58.   //Gör en lista med strängar av ord
  59.   std::vector<std::string> content{ (std::istream_iterator<std::string>(infil) ),
  60.                                     (std::istream_iterator<std::string>()    ) };
  61.   infil.close();
  62.  
  63.   // Klar
  64.   // Komplettering: Ni bör inte göra kopior av alla strängar, kan bli
  65.   // mycket ineffektivt om de är långa. Detta gäller på fler ställen i
  66.   // filen.
  67.  
  68.   //Iterera över varje ord i vectorn och "tvättar" dem
  69.   std::for_each(content.begin(), content.end(), [&](std::string &ord)
  70.   {
  71.       // Klar
  72.       // Komplettering: onödigt att ni letar med find_first_not_of
  73.       // respektive last 2-3 gånger för samma ord.
  74.  
  75.       // Raderar alla giltliga tecken framför orden
  76.       ord.erase(0,ord.find_first_not_of("\"\'("));
  77.  
  78.       // Letar upp sista tecknet innan giltliga sluttecken kommer, tar sedan bort de giltliga teckena
  79.       ord.erase(ord.find_last_not_of("\"!?;,:).\'")+1,ord.find_last_of("\"!?;,:).\'"));
  80.  
  81.       // Tar bort 's om det finns
  82.  
  83.       // Klar
  84.       // Komplettering: 's får endast förekomma i slutet av ordet
  85.       // efter att giltigt skräp tagits bort
  86.       if((*(ord.end()-2) == '\'') && (*(ord.end()-1) == 's')) // Om den ej hittar sub-stringen returnerar den std::string::npos
  87.       {
  88.         ord.erase(ord.end()-2,ord.end());
  89.       }
  90.  
  91.       // Nu är ordet "tvättat" och vi kan göra en if sats om ordet är giltligt.
  92.       if(Check_Word(ord))
  93.       {
  94.         // Snyggt!
  95.         transform(ord.begin(),ord.end(), ord.begin(),::tolower);    //Till små bokstäver
  96.         words.push_back(ord);
  97.       }
  98.   });
  99.     // Klar
  100.     // Komplettering: ni försöker hitta ett maximum här, kolla i
  101.     // algorithm om det finns någon funktion som kan hjälpa er med
  102.     // det
  103.     auto biggest = std::max_element(words.begin(), words.end());
  104.     if (biggest != words.end())
  105.       longest_word_length = (*biggest).length();
  106. }
  107.  
  108. // Klar
  109. // Komplettering: operator[] i map slår upp eller lägger till
  110. // element. Använd den istället för att själva kolla om elementet
  111. // finns
  112. void Word_Container::Make_Map(std::map<std::string, int> &final)
  113. {
  114.   std::for_each(words.begin(), words.end(), [&final, this](std::string &str)
  115.   {
  116.     if (std::to_string(++final[str]).length() > longest_number)
  117.       longest_number = std::to_string(final[str]).length();
  118.   });
  119. }
  120.  
  121. // Klar
  122. // Komplettering: Utskriften av siffrorna ska anpassas efter längsta
  123. // siffran. Vad skulle hända om vi har fler än 100 av samma ord?
  124. void Word_Container::Print()
  125. {
  126.   if (argument == "-a")
  127.   {
  128.     std::map<std::string, int> final;
  129.     Make_Map(final);
  130.  
  131.     std::for_each(final.begin(), final.end(), [this](const std::pair<std::string,int> &str)
  132.     {
  133.       std::cout.width(longest_word_length);
  134.       std::cout << std::fixed << std::left << str.first << " " << std::right << std::setw(longest_number) << str.second << '\n';
  135.     });
  136.   }
  137.  
  138.   else if (argument == "-f")
  139.   {
  140.     std::map<std::string, int> final;
  141.     Make_Map(final);
  142.  
  143.     std::vector<std::pair<std::string,int>> v;
  144.  
  145.     std::copy(final.begin(), final.end(),std::back_inserter<std::vector<std::pair<std::string,int>>>(v));
  146.  
  147.     std::sort(v.begin(), v.end(),[](const std::pair<std::string,int> &lhs, const std::pair<std::string,int> &rhs) {
  148.         if (lhs.second != rhs.second)
  149.       {
  150.         return lhs.second > rhs.second;
  151.       }
  152.             return lhs.first < rhs.first;
  153.      });
  154.  
  155.  
  156.      std::for_each(v.begin(), v.end(), [&v, this]( std::pair<std::string,int> &str)
  157.      {
  158.        std::cout.width(longest_word_length);
  159.        std::cout << std::fixed << std::right << str.first << " " << std::right << std::setw(longest_number) << str.second << '\n';
  160.      });
  161.    }
  162.  
  163.    else if (argument == "-o")
  164.    {
  165.      int antal_alpha = 0;
  166.      std::for_each(words.begin(), words.end(), [&antal_alpha, this](std::string &str)
  167.      {
  168.         if(signed(str.length()) < number-antal_alpha)
  169.         {
  170.           std::cout << str << " ";
  171.           antal_alpha += str.length() + 1;
  172.         }
  173.         else
  174.         {
  175.           std::cout << "\n" << str << " ";
  176.           antal_alpha = str.length() + 1;
  177.         }
  178.       });
  179.     }
  180.   }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement