Advertisement
Guest User

Untitled

a guest
Jan 29th, 2015
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.66 KB | None | 0 0
  1. #define _CRT_SECURE_NO_DEPRECATE
  2.  
  3. #include <stdio.h>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <string>
  7. #include <fstream>
  8. #include <vector>
  9. #include <map>
  10. #include <set>
  11. #include <algorithm>
  12. #include <exception>
  13.  
  14. using namespace std;
  15.  
  16. class InvalidUsageException : public exception{
  17.     virtual const char* what() const throw() {
  18.         return "Invalid regular expression syntax";
  19.     }
  20. };
  21. class InvalidExpressionFileException : public exception{
  22.     virtual const char* what() const throw() {
  23.         return "Invalid expression file";
  24.     }
  25. };
  26. class RegularExpression{
  27.     static const int BEGIN_STATE = 1;
  28.     static const int NULL_STATE = 0;
  29.  
  30.     vector<bool> terminalState;
  31.     map <int, map<char, int> > nextState;
  32.     vector <vector <int> > epsEdges;
  33.     int stateNumber;
  34.  
  35.     int SecondAutIndex(int ind) {
  36.         return ind + stateNumber - 1;
  37.     }
  38.     void DfsEpsEdges(int st, set <int> &states) {
  39.         states.insert(st);
  40.         for (int i = 0, l = epsEdges[st].size(); i < l; ++i) {
  41.             int w = epsEdges[st][i];
  42.             if (states.find(w) == states.end())
  43.                 DfsEpsEdges(w, states);
  44.         }
  45.     }
  46.     void CopyAutStructure(const RegularExpression &that) {
  47.         for (map <int, map<char, int> >::const_iterator it = that.nextState.begin(), end = that.nextState.end(); it != end; it++)
  48.             for (map <char, int>::const_iterator it1 = (it->second).begin(), end1 = (it->second).end(); it1 != end1; it1++) {
  49.                 int from = it->first;
  50.                 int to = it1->second;
  51.                 char symb = it1->first;
  52.                 nextState[SecondAutIndex(from)][symb] = SecondAutIndex(to);
  53.             }
  54.  
  55.         epsEdges.resize(SecondAutIndex(that.stateNumber));
  56.         for (int i = 0, len = that.epsEdges.size(); i < len; ++i)
  57.             for (int j = 0, len2 = that.epsEdges[i].size(); j < len2; ++j)
  58.                 epsEdges[SecondAutIndex(i)].push_back(SecondAutIndex(that.epsEdges[i][j]));
  59.        
  60.         terminalState.resize(SecondAutIndex(that.stateNumber));
  61.         for (int i = 1; i < that.stateNumber; ++i)
  62.             terminalState[SecondAutIndex(i)] = that.terminalState[i];
  63.     }
  64.     bool TerminalMultistateQ(const set<int> &states){
  65.         for (set <int>::iterator it = states.begin(), end = states.end(); it != end; it++)
  66.             if (terminalState[*it])
  67.                 return true;
  68.         return false;
  69.     }
  70.    
  71.     bool ReserveCharacter(char c){
  72.         return c == '(' || c == ')'|| c == '+' || c == '*';
  73.     }
  74.     RegularExpression Parse(int l, int r, string &s) {
  75.         if (r - l == 1) {
  76.             if (!ReserveCharacter(s[l])) {
  77.                 return RegularExpression(s[l]);
  78.             }
  79.             else {
  80.                 throw InvalidUsageException();
  81.             }
  82.         }
  83.         if (!(s[l] == '(' && s[r - 1] == ')')){
  84.             throw InvalidUsageException();
  85.         }
  86.        
  87.         l++; r--;
  88.         if (s[l] == '+')
  89.             return +(Parse(l + 1, r, s));
  90.        
  91.         int opSymbPos = -1;
  92.         int balance = 0;
  93.         for (int i = l; i < r; ++i) {
  94.             if (balance < 0)
  95.                 throw InvalidUsageException();
  96.             if (balance == 0 && (s[i] == '+' || s[i] == '*')) {
  97.                 opSymbPos = i;
  98.                 break;
  99.             }
  100.             if (s[i] == '(') {
  101.                 balance++;
  102.             }
  103.             if (s[i] == ')') {
  104.                 balance--;
  105.             }
  106.         }
  107.  
  108.         if (opSymbPos == -1 || opSymbPos >= r) {
  109.             throw InvalidUsageException();
  110.         }
  111.         if (s[opSymbPos] == '+')
  112.             return Parse(l, opSymbPos, s) + Parse(opSymbPos + 1, r, s);
  113.         if (s[opSymbPos] == '*')
  114.             return Parse(l, opSymbPos, s) * Parse(opSymbPos + 1, r, s);
  115.         throw InvalidUsageException();
  116.     }
  117.  
  118.     void Unify(const RegularExpression &that){
  119.         CopyAutStructure(that);
  120.         epsEdges[BEGIN_STATE].push_back(SecondAutIndex(BEGIN_STATE));
  121.         stateNumber += that.stateNumber - 1;
  122.     }
  123.     void Concat(const RegularExpression &that) {
  124.         CopyAutStructure(that);
  125.  
  126.         for (int st = 0; st < stateNumber; ++st)
  127.         if (terminalState[st])
  128.             epsEdges[st].push_back(SecondAutIndex(BEGIN_STATE));
  129.  
  130.         for (int i = 0; i < stateNumber; ++i)
  131.             terminalState[i] = 0;
  132.  
  133.         stateNumber += that.stateNumber - 1;
  134.     }
  135.     void Star(){
  136.         for (int st = 0; st < stateNumber; ++st)
  137.         if (terminalState[st])
  138.             epsEdges[st].push_back(BEGIN_STATE);
  139.     }
  140. public:
  141.     RegularExpression(){
  142.         stateNumber = 2;
  143.         terminalState.resize(2);
  144.         epsEdges.resize(2);
  145.     }
  146.     RegularExpression(char symb){
  147.         stateNumber = 3;
  148.         terminalState.resize(3);
  149.         epsEdges.resize(3);
  150.         terminalState[2] = true;
  151.         nextState[BEGIN_STATE][symb] = 2;
  152.     }
  153.     RegularExpression(string str){
  154.         RegularExpression temp;
  155.  
  156.         try {
  157.             temp = Parse(0, str.size(), str);
  158.             *this = temp;
  159.         }
  160.         catch (const InvalidUsageException &e){
  161.             *this = RegularExpression();
  162.             throw e;
  163.         }
  164.     }
  165.  
  166.     vector < pair<int, string> > FindOccurences(string text){
  167.         vector <bool> isRegularOccurence(text.size());
  168.         vector <pair <int, string> > result;
  169.         for (int i = 0, l = text.length(); i < l; ++i){
  170.             set <int> states;
  171.             DfsEpsEdges(BEGIN_STATE, states);
  172.             int maxCorrectJ = -1;
  173.             for (int j = i; j < l; ++j) {
  174.                 set <int> newStates;
  175.                 char c = text[j];
  176.                 for (set <int>::iterator it = states.begin(), end = states.end(); it != end; it++){
  177.                     int w = *it;
  178.                     if (nextState[w][c])
  179.                         DfsEpsEdges(nextState[w][c], newStates);
  180.                 }
  181.                 states = newStates;
  182.                 if (TerminalMultistateQ(states))
  183.                     maxCorrectJ = j;
  184.                 newStates.clear();
  185.             }
  186.             bool isFine = false;
  187.             for (int j = i; j <= maxCorrectJ; ++j) {
  188.                 if (!isRegularOccurence[j])
  189.                     isFine = true;
  190.             }
  191.             if (isFine) {
  192.                 result.push_back(make_pair(i, text.substr(i, maxCorrectJ - i + 1)));
  193.                 for (int j = i; j <= maxCorrectJ; ++j)
  194.                     isRegularOccurence[j] = true;
  195.             }
  196.             states.clear();
  197.         }
  198.         return result;
  199.     }
  200.     bool Match(string str) {
  201.         vector <pair<int, string> > res = FindOccurences(str);
  202.         for (int i = 0, l = res.size(); i < l; ++i)
  203.             if (res[i].second == str)
  204.                 return true;
  205.         return false;
  206.     }
  207.  
  208.     RegularExpression operator*(const RegularExpression &that) {
  209.         RegularExpression res = *this;
  210.         res.Concat(that);
  211.         return res;
  212.     }
  213.     RegularExpression operator+(const RegularExpression &that) {
  214.         RegularExpression res = *this;
  215.         res.Unify(that);
  216.         return res;
  217.     }
  218.     RegularExpression operator+() {
  219.         RegularExpression res = *this;
  220.         res.Star();
  221.         return res;
  222.     }
  223. };
  224. class Menu{
  225.     static const int MAX_NUM = 10000;
  226.    
  227.     typedef vector < vector <pair<int, string> > > AnswerData;
  228.    
  229.     vector <RegularExpression> allRegExp;
  230.     vector <string> files;
  231.  
  232.     int AddNewDocument(string path) {
  233.         FILE * pFile;
  234.         pFile = fopen(path.c_str(), "r");
  235.         char fileText[MAX_NUM];
  236.         if (pFile == NULL){
  237.             throw InvalidExpressionFileException();
  238.         }
  239.         else{
  240.             string res = "";
  241.             while (fgets(fileText, MAX_NUM, pFile)) {
  242.                 res += string(fileText, fileText + strlen(fileText));
  243.             }
  244.             files.push_back(res);
  245.             return files.size();
  246.         }
  247.     }
  248.     AnswerData FindMaxAppearances(RegularExpression &reg) {
  249.         AnswerData occurences(files.size());
  250.         AnswerData answer(files.size());
  251.         for (int i = 0, l = files.size(); i < l; ++i)
  252.             occurences[i] = reg.FindOccurences(files[i]);
  253.         int maxVal = 0;
  254.         for (int i = 0, l = occurences.size(); i < l; ++i) {
  255.             if (maxVal < occurences[i].size())
  256.                 maxVal = occurences[i].size();
  257.         }
  258.         for (int i = 0, l = answer.size(); i < l; ++i) {
  259.             if (occurences[i].size() == maxVal)
  260.                 answer[i] = occurences[i];
  261.         }
  262.         return answer;
  263.     }
  264.     AnswerData FindLongestAppearances(RegularExpression &reg) {
  265.         AnswerData occurences(files.size());
  266.         AnswerData longestWords(files.size());
  267.         int maxVal = 0;
  268.         for (int i = 0, l = files.size(); i < l; ++i)
  269.             occurences[i] = reg.FindOccurences(files[i]);
  270.         for (int i = 0, l = occurences.size(); i < l; ++i) {
  271.             for (int j = 0, l2 = occurences[i].size(); j < l2; ++j){
  272.                 int p = occurences[i][j].second.size();
  273.                 if (p > maxVal)
  274.                     maxVal = p;
  275.             }
  276.         }
  277.         for (int i = 0, l = occurences.size(); i < l; ++i) {
  278.             for (int j = 0, l2 = occurences[i].size(); j < l2; ++j) {
  279.                 if (occurences[i][j].second.size() == maxVal) {
  280.                     longestWords[i].push_back(occurences[i][j]);
  281.                 }
  282.             }
  283.         }
  284.         return longestWords;
  285.     }
  286.     AnswerData FindAllAppearances(RegularExpression &reg) {
  287.         vector < vector <pair<int, string> > > allAppearances(files.size());
  288.         for (int i = 0, l = files.size(); i < l; ++i)
  289.             allAppearances[i] = reg.FindOccurences(files[i]);
  290.         return allAppearances;
  291.     }
  292.     AnswerData FindSuperRelevant() {
  293.         AnswerData answer(files.size());
  294.         for (int i = 0, l = files.size(); i < l; ++i) {
  295.             for (int j = 0, l2 = allRegExp.size(); j < l2; ++j) {
  296.                 vector < pair<int, string> > occurences = allRegExp[j].FindOccurences(files[i]);
  297.                 if (occurences.empty()) {
  298.                     answer[i].clear();
  299.                     break;
  300.                 }
  301.                 answer[i].push_back(occurences[0]);
  302.             }
  303.         }
  304.         return answer;
  305.     }
  306.     void PrintAnswer(AnswerData data) {
  307.         bool noRelDoc = true;
  308.         for (int i = 0, l = data.size(); i < l; ++i) {
  309.             if (data[i].empty()) continue;
  310.             cout << "Document " << i + 1 << ":" << endl;
  311.             for (int j = 0, l2 = data[i].size(); j < l2; ++j) {
  312.                 cout << data[i][j].first << ": " << data[i][j].second << endl;
  313.                 noRelDoc = false;
  314.             }
  315.         }
  316.         if (noRelDoc)
  317.             cout << "There are no relevant documents" << endl;
  318.     }
  319.     void PrintMenuDesc(){
  320.         cout << "1) Add new document to the list of documents" << endl;
  321.         cout << "2) Find max appearances" << endl;
  322.         cout << "3) Find longest appearance" << endl;
  323.         cout << "4) Find all documents" << endl;
  324.         cout << "5) Find super - relevant documents" << endl;
  325.         cout << "6) Exit" << endl;
  326.     }
  327. public:
  328.     void drive() {
  329.         PrintMenuDesc();
  330.        
  331.         char c;
  332.         while (cin >> c) {
  333.             try{
  334.                 if (c == '1') {
  335.                     cout << "Please insert path for document" << endl;
  336.                     string path;
  337.                     cin >> path;
  338.                     int num = AddNewDocument(path);
  339.                     cout << "Document number ";
  340.                     cout << num;
  341.                     cout << " added" << endl;
  342.                 }
  343.                 if (c == '2') {
  344.                     cout << "Please insert regular expression" << endl;
  345.                     string regularExpString;
  346.                     cin >> regularExpString;
  347.                     allRegExp.push_back(RegularExpression(regularExpString));
  348.                     PrintAnswer(FindMaxAppearances(RegularExpression(regularExpString)));
  349.                 }
  350.                 if (c == '3') {
  351.                     cout << "Please insert regular expression" << endl;
  352.                     string regularExpString;
  353.                     cin >> regularExpString;
  354.                     allRegExp.push_back(RegularExpression(regularExpString));
  355.                     PrintAnswer(FindLongestAppearances(RegularExpression(regularExpString)));
  356.                 }
  357.                 if (c == '4') {
  358.                     cout << "Please insert regular expression" << endl;
  359.                     string regularExpString;
  360.                     cin >> regularExpString;
  361.                     allRegExp.push_back(RegularExpression(regularExpString));
  362.                     PrintAnswer(FindAllAppearances(RegularExpression(regularExpString)));
  363.                 }
  364.                 if (c == '5') {
  365.                     PrintAnswer(FindSuperRelevant());
  366.                 }
  367.                 if (c == '6') {
  368.                     cout << "Goodbye" << endl;
  369.                     return;
  370.                 }
  371.                 PrintMenuDesc();
  372.             }
  373.             catch (const exception &e) {
  374.                 cout << e.what() << endl;
  375.                 PrintMenuDesc();
  376.             }
  377.            
  378.         }
  379.         PrintMenuDesc();
  380.     }
  381.     Menu(){}
  382. };
  383.  
  384. int main(int argc, char *argv[]) {
  385.     Menu menu;
  386.     menu.drive();
  387.     return 0;
  388. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement