Guest User

Untitled

a guest
Jun 24th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.72 KB | None | 0 0
  1. /*
  2. * Тестовая программа для чтения файла с неприводимыми многочленами.
  3. */
  4.  
  5. #include <cassert>
  6. #include <cstdio>
  7. #include <cstdlib>
  8. #include <exception>
  9. #include <fstream>
  10. #include <iostream>
  11. #include <locale> // for isspace, isdigit etc.
  12. #include <map>
  13. #include <string>
  14. #include <vector>
  15. using namespace std;
  16.  
  17. const char * const FILENAME = "polys.txt";
  18.  
  19. /* --- Misc ---------------------------------------------------------------- */
  20.  
  21. /*
  22. * Skip spaces in string 's' starting from 'pos'.
  23. * Return the position of the first non-space char.
  24. * If no non-space char was found, return 's.size()'.
  25. */
  26. size_t skipspaces(const string & s, size_t pos = 0){
  27. assert(pos >= 0);
  28. size_t l = s.size();
  29. while (pos < l && isspace(s[pos])) ++pos;
  30. return pos;
  31. }
  32.  
  33. /* --- Polynom classes ----------------------------------------------------- */
  34.  
  35. class SyntaxError: public exception {
  36. public:
  37. SyntaxError(const string & message_): message(message_) { }
  38. virtual const char * what() const throw() { return message.c_str(); }
  39. virtual ~SyntaxError() throw() { }
  40. private:
  41. string message;
  42. };
  43.  
  44. class Poly {
  45. friend ostream & operator <<(ostream & output, const Poly & poly);
  46.  
  47. public:
  48. enum Stat {
  49. REDUCIBLE,
  50. IRREDUCIBLE,
  51. PRIMITIVE,
  52. };
  53.  
  54. Poly(Stat stat_): stat(stat_) { }
  55.  
  56. bool is_irreducible() const {
  57. return stat >= IRREDUCIBLE;
  58. }
  59. bool is_primitive() const {
  60. return stat >= PRIMITIVE;
  61. }
  62.  
  63. /*
  64. * Распарсить строку, содержащую коэффициенты многочлена.
  65. * Символы считываются из 's', начиная с позиции 'pos'.
  66. *
  67. * Коэффициенты в строке должны разделяться запятыми.
  68. * Пробелы вокруг запятых допускаются.
  69. * Пробелы в позиции pos допускаются.
  70. * Однако пустая строка или строка из одних пробелов
  71. * будет считаться ошибкой.
  72. *
  73. * Представление шестнадцатеричными цифрами A-F не допускается, только 0-9.
  74. * Возвращаемое значение - место в строке, где закончился разбор.
  75. */
  76. size_t parse(int q, const string & s, size_t pos = 0){
  77. assert(pos >= 0);
  78. const size_t l = s.size();
  79.  
  80. /*
  81. * Пропускаем начальные нули, чтобы не захламлять массив
  82. * лишней информацией.
  83. */
  84. bool skip_zeroes = true;
  85. vector<int> new_vec;
  86.  
  87. pos = skipspaces(s, pos);
  88. if (pos == l)
  89. throw SyntaxError("Empty string is not a polynom, dude!");
  90.  
  91. for (;;) {
  92. size_t pos2 = pos;
  93. while (pos2 < l && isdigit(s[pos2])) ++pos2;
  94.  
  95. if (pos == pos2) {
  96. /* atoi doesn't consider empty string to mean 0 */
  97. if (!skip_zeroes)
  98. new_vec.push_back(0);
  99. }
  100. else {
  101. int v = atoi(s.substr(pos, pos2 - pos).c_str());
  102. if (v < 0) {
  103. /* Глупая проверка, так как использовали isdigit выше */
  104. throw SyntaxError("Polynom coeffs must't be negative.");
  105. }
  106. else if (v >= q) {
  107. throw SyntaxError("Polynom coeff must be less than 'q'.");
  108. }
  109.  
  110. if (skip_zeroes) {
  111. if (v != 0){
  112. new_vec.push_back(v);
  113. skip_zeroes = false;
  114. }
  115. }
  116. else
  117. new_vec.push_back(v);
  118. }
  119.  
  120. pos = skipspaces(s, pos2);
  121. if (pos == l)
  122. /* Конец строки - конец разбора */
  123. break;
  124. if (s[pos] != ',')
  125. /* Не запятая - конец разбора */
  126. break;
  127.  
  128. /*
  129. * Иначе пропускаем запятую и последующие пробелы
  130. * и разбираем следующий коэффициент.
  131. */
  132. pos = skipspaces(s, pos+1);
  133. }
  134.  
  135. vec.swap(new_vec);
  136. return pos;
  137. }
  138.  
  139. private:
  140. Stat stat;
  141. vector<int> vec;
  142. };
  143.  
  144. ostream & operator <<(ostream & output, const Poly & poly){
  145. vector<int>::const_iterator it = poly.vec.begin();
  146. const vector<int>::const_iterator end = poly.vec.end();
  147. if (it != end)
  148. output << *it++;
  149. for (; it != end; ++it)
  150. output << ',' << *it;
  151. return output;
  152. }
  153.  
  154. /* --- main ---------------------------------------------------------------- */
  155.  
  156. typedef map<int, vector<Poly> > Polys;
  157.  
  158. bool read(Polys & all_polys){
  159. ifstream input(FILENAME);
  160. int lineno = 1;
  161. /*
  162. * То, что обозначалось буквой q не лекциях.
  163. * 0 - недействительное значение.
  164. */
  165. int q = 0;
  166. vector<Poly> * polys = 0;
  167.  
  168. try {
  169. string line;
  170. for (; getline(input, line); ++lineno){
  171. const size_t l = line.size();
  172.  
  173. if (l == 0)
  174. /* Проверяем заранее, чтобы не напороться на грабли, проверяя line[0]. */
  175. continue;
  176.  
  177. if (line[0] == '#')
  178. /* comment */
  179. continue;
  180.  
  181. if (line[0] == '>'){
  182. /* primitive poly */
  183.  
  184. if (q == 0)
  185. throw SyntaxError("Field size (q) directive is missing");
  186. polys->push_back(Poly(Poly::PRIMITIVE));
  187. if (polys->back().parse(q, line, 1) != l){
  188. /* Строка разобрана не до конца */
  189. throw SyntaxError("");
  190. }
  191. continue;
  192. }
  193.  
  194. if (line[0] == '['){
  195. if (l < 4 || line[1] != 'F')
  196. throw SyntaxError("");
  197.  
  198. size_t i = 2;
  199.  
  200. size_t i2 = i;
  201. while (i2 < l-1 && isdigit(line[i2])) ++i2;
  202. if (i == i2)
  203. throw SyntaxError("");
  204.  
  205. q = atoi(line.substr(i, i2 - i).c_str());
  206. if (q <= 0)
  207. throw SyntaxError("q must be positive");
  208.  
  209. if (line[i2] != ']')
  210. throw SyntaxError("");
  211. if (skipspaces(line, i2+1) != l)
  212. throw SyntaxError("");
  213.  
  214. polys = &( all_polys[q] );
  215. continue;
  216. }
  217.  
  218. /*
  219. * Проверяем здесь, не пустая ли это строка.
  220. * Poly.parse() в этом случае выдаст ошибку,
  221. * а мы пустые строки в файле допускаем (и пропускаем).
  222. */
  223. size_t i = skipspaces(line, 0);
  224. if (i == l)
  225. /* Skip empty string */
  226. continue;
  227.  
  228. if (q == 0)
  229. throw SyntaxError("Field size (q) directive is missing");
  230. polys->push_back(Poly(Poly::IRREDUCIBLE));
  231. if (polys->back().parse(q, line, i) != l)
  232. /* Строка разобрана не до конца */
  233. throw SyntaxError("");
  234. }
  235. }
  236. catch(SyntaxError & e){
  237. cerr << "Syntax error at line " << lineno << ": " << e.what() << '\n';
  238. return false;
  239. }
  240. return true;
  241. }
  242.  
  243. void write(const Polys & polys){
  244. Polys::const_iterator it = polys.begin();
  245. const Polys::const_iterator end = polys.end();
  246. for (; it != end; ++it){
  247. cout << "[F" << it->first << "]\n";
  248. vector<Poly>::const_iterator it2 = it->second.begin();
  249. const vector<Poly>::const_iterator end2 = it->second.end();
  250. for (; it2 != end2; ++it2){
  251. if (it2->is_primitive())
  252. cout << "> ";
  253. else
  254. cout << " ";
  255. cout << *it2 << '\n';
  256. }
  257. }
  258. }
  259.  
  260. int main(int argc, char ** argv){
  261. Polys polys;
  262. if (!read(polys))
  263. return 1;
  264. write(polys);
  265. return 0;
  266. }
Add Comment
Please, Sign In to add comment