Guest User

code

a guest
Nov 20th, 2011
1,054
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.11 KB | None | 0 0
  1. /*Рассматривается список поддиректорий и файлов некоторой директории в Linux, например:
  2. .
  3. ./download_client.sh
  4. ./random1000_queries_sport.txt
  5. ./times.txt
  6. ./site
  7. ./site/site_kz_domains_random1000_2011-07-26.txt
  8. ./site/site_ru_domains_top1000_2011-07-27.txt
  9. ./site/site_by_domains_top1000_2011-07-27.txt
  10. ./site/kz
  11. ./site/kz/random1000
  12. ./site/kz/random1000/site_kz_random1000_2011-07-16.xml
  13. ./site/ru
  14. ./site/ru/random1000
  15. необходимо этот список из одного формата преобразовать в другой формат.
  16. В первых двух строках даны названия входного и выходного формата. Обе строки из мно-
  17. жества «find», «python», «acm1», «acm2», «acm3», «xml». В последующих строках в формате,
  18. соответствующем входному формату из первой строки, описано дерево директорий.
  19. В частности, если перечислена
  20. какая-то поддиректория, то перечислены и все ее родительские директории вплоть до корневой,
  21. а также все ее поддиректории и файлы в них рекурсивно. Если есть элемент списка, у которого нет
  22. потомков в дереве, то это файл, иначе это директория. Соответственно, нет пустых директорий на
  23. нижнем уровне дерева. Все идентификаторы файлов и директорий — уникальные целые числа в
  24. диапазоне от 0 до (231􀀀1). Идентификатор корневой директории всегда равен 0. Идентификатор
  25. родительской вершины всегда меньше идентификатора дочерней вершины.
  26. Имена файлов и папок — непустые строки, состоящие из строчных и заглавных символов латин-
  27. ского алфавита, цифр, символов тире, подчеркивания и точки.
  28.  
  29. Формат «find»
  30. 13
  31. . 0
  32. ./download_client.sh 1
  33. ./random1000_queries_sport.txt 2
  34. ./times.txt 3
  35. ./site 4
  36. ./site/site_kz_domains_random1000_2011-07-26.txt 5
  37. ./site/site_ru_domains_top1000_2011-07-27.txt 6
  38. ./site/site_by_domains_top1000_2011-07-27.txt 7
  39. ./site/kz 8
  40. ./site/kz/random1000 9
  41. ./site/kz/site_kz_random1000_2011-07-16.xml 10
  42. ./site/ru 11
  43. ./site/ru/random1000 12
  44.  
  45. Формат «python»
  46. 13
  47. . 0
  48.     download_client.sh 1
  49.     random1000_queries_sport.txt 2
  50.     times.txt 3
  51.     site 4
  52.         site_kz_domains_random1000_2011-07-26.txt 5
  53.         site_ru_domains_top1000_2011-07-27.txt 6
  54.         site_by_domains_top1000_2011-07-27.txt 7
  55.         kz 8
  56.             random1000 9
  57.             site_kz_random1000_2011-07-16.xml 10
  58.         ru 11
  59.             random1000 12
  60.  
  61. Формат «acm1»
  62. В первой строке число n — общее количество файлов и директорий. Далее n строк. В i-й строке
  63. название файла или директории, пробел и идентификатор. Идентификаторы упорядочены по
  64. возрастанию. Далее еще n строк. В i-й строке вначале записано число k — количество детей
  65. вершины с i-м по порядку идентификатором. Затем еще k чисел через пробел — идентификаторы
  66. детей в порядке возрастания.
  67. 13
  68. . 0
  69. download_client.sh 1
  70. random1000_queries_sport.txt 2
  71. times.txt 3
  72. site 4
  73. site_kz_domains_random1000_2011-07-26.txt 5
  74. site_ru_domains_top1000_2011-07-27.txt 6
  75. site_by_domains_top1000_2011-07-27.txt 7
  76. kz 8
  77. random1000 9
  78. site_kz_random1000_2011-07-16.xml 10
  79. ru 11
  80. random1000 12
  81. 4 1 2 3 4
  82. 0
  83. 0
  84. 0
  85. 5 5 6 7 8 11
  86. 0
  87. 0
  88. 0
  89. 2 9 10
  90. 0
  91. 0
  92. 1 12
  93. 0
  94.  
  95. Формат «acm2»
  96. В первой строке число n — общее количество файлов и директорий. Далее n строк. В i-й строке
  97. название файла или директории, пробел и идентификатор. Идентификаторы упорядочены по
  98. возрастанию. Далее еще n строк. В i-й строке записан идентификатор родителя вершины с i-м
  99. идентификатором или 􀀀1, если это корневая вершина.
  100.  
  101. 13
  102. . 0
  103. download_client.sh 1
  104. random1000_queries_sport.txt 2
  105. times.txt 3
  106. site 4
  107. site_kz_domains_random1000_2011-07-26.txt 5
  108. site_ru_domains_top1000_2011-07-27.txt 6
  109. site_by_domains_top1000_2011-07-27.txt 7
  110. kz 8
  111. random1000 9
  112. site_kz_random1000_2011-07-16.xml 10
  113. ru 11
  114. random1000 12
  115. -1
  116. 0
  117. 0
  118. 0
  119. 0
  120. 4
  121. 4
  122. 4
  123. 4
  124. 8
  125. 8
  126. 4
  127. 11
  128.  
  129. Формат «acm3»
  130. В первой строке число n — общее количество файлов и директорий. Далее n строк. В i-й строке
  131. название файла или директории, пробел и идентификатор. Идентификаторы упорядочены по воз-
  132. растанию. Далее еще (n 􀀀 1) строка — описания ребер дерева. Каждое ребро описывается двумя
  133. идентификаторами вершин, записанными через пробел. Сначала записан меньший идентифика-
  134. тор, затем больший. Ребра выписаны в порядке возрастания первого идентификатора вершины,
  135. а при равенстве первых идентификаторов — в порядке возрастания второго идентификатора
  136. вершины.
  137. 13
  138. . 0
  139. download_client.sh 1
  140. random1000_queries_sport.txt 2
  141. times.txt 3
  142. site 4
  143. site_kz_domains_random1000_2011-07-26.txt 5
  144. site_ru_domains_top1000_2011-07-27.txt 6
  145. site_by_domains_top1000_2011-07-27.txt 7
  146. kz 8
  147. random1000 9
  148. site_kz_random1000_2011-07-16.xml 10
  149. ru 11
  150. random1000 12
  151. 0 1
  152. 0 2
  153. 0 3
  154. 0 4
  155. 4 5
  156. 4 6
  157. 4 7
  158. 4 8
  159. 4 11
  160. 8 9
  161. 8 10
  162. 11 12
  163.  
  164. Формат «xml»
  165. <dir name=’.’ id=’0’>
  166.   <file name=’download_client.sh’ id=’1’/>
  167.   <file name=’random1000_queries_sport.txt’ id=’2’/>
  168.   <file name=’times.txt’ id=’3’/>
  169.   <dir name=’site’ id=’4’>
  170.     <file name=’site_kz_domains_random1000_2011-07-26.txt’ id=’5’/>
  171.     <file name=’site_ru_domains_top1000_2011-07-27.txt’ id=’6’/>
  172.     <file name=’site_by_domains_top1000_2011-07-27.txt’ id=’7’/>
  173.     <dir name=’kz’ id=’8’>
  174.       <file name=’random1000’ id=’9’/>
  175.       <file name=’site_kz_random1000_2011-07-16.xml’ id=’10’/>
  176.     </dir>
  177.     <dir name=’ru’ id=’11’>
  178.       <file name=’random1000’ id=’12’/>
  179.     </dir>
  180.   </dir>
  181. </dir>
  182.  
  183. Сделал почти все, осталось сделать формат find. Не применял никакие структуры данных. Так как не имею опыта работы с ними.
  184. */
  185. #include <iostream>
  186. #include <string>
  187. #include <vector>
  188. #include <algorithm>
  189. using namespace std;
  190.  
  191. int numOfDir;
  192. string formats[6] = {"find", "python", "acm1", "acm2", "acm3", "xml"};
  193. string separates[6] = {"/", "    ", "", "", "", ""};
  194. string inSep;
  195. string outSep;
  196. vector<string> list;
  197. vector<int> strokeId;
  198. vector<string> folderNames;
  199. vector<int> folderId;
  200. vector<int> parentId;
  201. vector<string> elements;
  202. vector<int> depth;
  203. int inF;
  204. int outF;
  205.  
  206. int checkFormat( const string *);
  207. void getList();
  208. void getInfo();
  209. int findIdOfFolder(const string *);
  210. void displayList(int, int);
  211. void howManyChild(const int *, vector<int> &);
  212. void displayStat();
  213. void parFoldOut(int);
  214. void fixNI();
  215. void getStat();
  216. int compareIdFold(const string *, int);
  217. bool checkFoldExist(int);
  218. bool readXml(int *, int);
  219.  
  220. int main()
  221. {
  222.   string inFormat;
  223.   string outFormat;
  224.  
  225.   cin >> inFormat;
  226.   cin >> outFormat;
  227.   inF = checkFormat( &inFormat );
  228.   outF = checkFormat( &outFormat );
  229.  
  230.   if (inF != 5)
  231.     cin >> numOfDir;
  232.  
  233.  
  234.   inSep = separates[ inF ];
  235.   outSep = separates[ outF ];
  236.  
  237.   getList();
  238.   getInfo();
  239.   displayList(1, 0);
  240.  
  241.    
  242.   displayStat();  
  243.  
  244.  
  245.  
  246.   return 0;
  247. }
  248.  
  249. int checkFormat( const string *format )
  250. {
  251.   for (int i = 0; i < 6; i++ )
  252.     {
  253.       if (*format == formats[i])
  254.     return i;
  255.     }
  256.   return -1;
  257. }
  258.  
  259. void getList()
  260. {
  261.   string buff;
  262.   int id;
  263.   if (inF != 5)
  264.     {
  265.       cin >> ws;
  266.       for (int i = 0; i < numOfDir; i++)
  267.     {
  268.       if (inF == 1)
  269.         {
  270.           getline(cin, buff);
  271.           //      cout << buff << endl; // <-------------------------------
  272.           id = i;
  273.         }
  274.       else if (inF == 0 || inF == 2 || inF == 3 || inF == 4)
  275.         {
  276.           cin >> buff;
  277.           cin >> id;
  278.         }
  279.       list.push_back( buff );
  280.       strokeId.push_back( id );
  281.       if (inF == 4)
  282.         {
  283.           folderNames.push_back(".");
  284.           folderId.push_back(0);
  285.         }
  286.      
  287.     }
  288.     }
  289.   else
  290.     {
  291.       cin >> ws;
  292.       int beg = 0;
  293.       readXml(&beg, -1);
  294.     }
  295. }
  296.  
  297. void getInfo()
  298. {
  299.   size_t posE;
  300.   size_t posB;
  301.   string element;
  302.   string workFolder;
  303.   int currentId;
  304.   int depthStr;
  305.   for(int i = 0; i < numOfDir; i++)
  306.     {
  307.       posB = 0;
  308.       posE = 0;
  309.       if (inF == 0)
  310.     {
  311.       posE = list[ i ].find_last_of( "/" );
  312.       element = list[ i ].substr( posE+1 );
  313.     }
  314.       else if (inF == 1)
  315.     {
  316.       posE = list[i].find_first_not_of(" ");
  317.       posB = list[i].find_last_of(" ");
  318.       //      cout << posE << "<-----" << posB << "< ---------" << endl; // <-----------------------------------
  319.       if (posE != string::npos)
  320.         {
  321.           depth.push_back(posE/4);
  322.           element = list[ i ].substr( posE, posB-posE );
  323.         }
  324.       else
  325.         element = list[ i ].substr(0, 1);
  326.     }
  327.       else if (inF == 2 || inF == 3 || inF == 4)
  328.     {
  329.       element = list[i];
  330.       if (i == 0)
  331.         parentId.push_back(-1);
  332.       else
  333.         parentId.push_back(0);
  334.     }
  335.  
  336.       elements.push_back(element);
  337.       if (inF == 0 || inF == 1)
  338.     {
  339.       if (element.find(".") != string::npos)
  340.         { }
  341.       else
  342.         {
  343.           folderNames.push_back(element);
  344.           folderId.push_back(i);
  345.         }
  346.       if (inF == 0)
  347.         {
  348.           posB = list[ i ].rfind( "/", posE-1 );
  349.      
  350.           if ( posB != string::npos)
  351.         {
  352.           posB++;
  353.           workFolder = list[i].substr(posB, posE-posB);
  354.         }
  355.           else
  356.         {
  357.           workFolder = ".";
  358.         }
  359.         }
  360.       else if (inF == 1)
  361.         {
  362.           if (depth[i] == 0)
  363.         {
  364.           workFolder = ".";
  365.         }
  366.           else if (depth[i] > depth[i-1])
  367.         {
  368.           workFolder = elements[i-1];
  369.         }
  370.           else if (depth[i] == depth[i-1])
  371.         {
  372.           workFolder = elements[ parentId[i-1] ];
  373.         }
  374.           else if (depth[i] < depth[i-1])
  375.         {
  376.           int j = i-1;
  377.           //          int deep = depth[i-1]-depth[i];
  378.           //          int tempId = i;
  379.           // findParent(deep, tempId);
  380.           while (depth[i] != depth[j])
  381.             {
  382.               --j;
  383.             }
  384.           workFolder = elements[ parentId[j] ];
  385.         }
  386.         }
  387.  
  388.      
  389.  
  390.       if (i == 0)
  391.         {
  392.           folderNames.push_back(".");
  393.           folderId.push_back(0);
  394.           parentId.push_back(-1);
  395.         }
  396.       else
  397.         {
  398.           currentId = findIdOfFolder( &workFolder );
  399.           parentId.push_back(currentId);
  400.         }
  401.     }
  402.       //      cout << workFolder << " " << strokeId[i] << " " << parentId[i] << endl;
  403.     }
  404.   if (inF == 2 || inF == 3 || inF == 4)
  405.     getStat();
  406.   if (inF != 5)
  407.     fixNI();
  408. }
  409.  
  410. int findParent(int deep, int id)
  411. {
  412.   if (deep = 0)
  413.     return id;
  414.   else
  415.     {
  416.       id = parentId[id - 1];
  417.       deep--;
  418.       findParent(deep, id);
  419.     }
  420. }
  421.  
  422. int findIdOfFolder( const string *folder)
  423. {
  424.   int id;
  425.   for (int i = 0; i < folderNames.size(); i++)
  426.     {
  427.       if (*folder == folderNames[i])
  428.     {
  429.       id = folderId[i];
  430.       return id;
  431.     }
  432.     }
  433.   return 999;
  434. }
  435.  
  436. void displayList(int depth, int dirId)
  437. {
  438.   vector<int> child;
  439.   int fold;
  440.   int jjj;
  441.   if (dirId == 0 && outF == 1)//python
  442.     {
  443.       cout << folderNames[0] << " " << folderId[0] << endl;
  444.     }
  445.   else if (dirId == 0 && outF == 5) // xml
  446.     {
  447.       cout << "<dir name='" << elements[0] << "' id='" << strokeId[0] << "'>" << endl;
  448.     }
  449.   howManyChild( &dirId, child);
  450.  
  451.   for (vector<int>::iterator it = child.begin(); it != child.end(); it++)
  452.     {
  453.       for (int d = 0; d < depth; d++)
  454.     {
  455.       if (outF == 1) // For python
  456.         cout << "    ";
  457.       else if (outF == 5)
  458.         cout << "  "; // For xml
  459.     }
  460.       if (outF == 1) // python
  461.     {
  462.       cout << elements[ *it ] << " " << strokeId[*it] << endl;
  463.       string buff1 = elements[ *it ];
  464.       jjj = strokeId[*it];
  465.       fold = compareIdFold(&buff1, jjj);
  466.       if (fold != 999)
  467.         {
  468.           displayList(depth+1, *it);
  469.         }
  470.     }
  471.       else if (outF == 5) // xml
  472.     {
  473.       string bufff = elements[*it];
  474.       jjj = strokeId[*it];
  475.       fold = compareIdFold(&bufff, jjj);
  476.       //      fold = findIdOfFolder(&bufff);
  477.       if (fold != 999)
  478.         {
  479.           cout << "<dir name='" << elements[*it] <<"' id='" << strokeId[*it] << "'>" << endl;
  480.           displayList(depth+1, *it);
  481.           for (int d = 0; d < depth; d++)
  482.         cout << "  ";
  483.        
  484.           cout << "</dir>" << endl;
  485.         }
  486.       else
  487.         {
  488.           cout << "<file name='" << elements[*it] <<  "' id='" << strokeId[*it] << "'>" << endl;
  489.         }
  490.     }
  491.     }
  492.   if (dirId == 0 && outF == 5) // xml
  493.     {
  494.       cout << "</dir>" << endl;
  495.     }
  496.  
  497. }
  498.  
  499. void howManyChild(const int *id, vector<int> &childId)
  500. {
  501.   for (int i = 0; i < numOfDir; i++)
  502.     {
  503.       if (parentId[i] == *id)
  504.     {
  505.       childId.push_back(i);
  506.     }
  507.     }
  508. }
  509.  
  510. void displayStat()
  511. {
  512.   string buff2;
  513.   int fold;
  514.   vector<int> stat;
  515.   int jjj;
  516.   for (int i = 0; i < numOfDir; i++)
  517.     {
  518.       if ( outF== 2) // For acm1
  519.     {
  520.       buff2 = elements[i];
  521.       jjj = strokeId[i];
  522.       fold = compareIdFold(&buff2, jjj);
  523.       if (fold == 999)
  524.         cout << 0 << endl;
  525.       else
  526.         {
  527.           howManyChild(&fold, stat);
  528.           cout << stat.size() << " ";
  529.           for (int j = 0; j < stat.size(); j++)
  530.         {
  531.           cout << stat[j] << " ";
  532.         }
  533.           cout << endl;
  534.         }
  535.       stat.clear();
  536.     }
  537.  
  538.       else if ( outF == 3 ) // For acm2
  539.     {
  540.       cout << parentId[i] << endl;
  541.     }
  542.  
  543.       else if (outF == 4) // For acm3
  544.     {
  545.         parFoldOut(i);
  546.     }
  547.       else if (outF == 5)
  548.     {
  549.       //      printXml();
  550.       //      break;
  551.     }
  552.     }
  553. }
  554.  
  555. void parFoldOut(int i)
  556. {
  557.   for (int j = 0; j < numOfDir; j++)
  558.     {
  559.       if (parentId[j] == i)
  560.     cout << parentId[j] << " " << strokeId[j] << endl;
  561.     }
  562. }
  563.  
  564. void fixNI()
  565. {
  566.   for (int h = 0; h < folderId.size(); h++)
  567.     {
  568.       int num = 0;
  569.       for (int i = 0; i < numOfDir; i++)
  570.     {
  571.       if (folderId[h] == parentId[i])
  572.         num++;
  573.     }
  574.       if (num == 0)
  575.     {
  576.       folderNames.erase(folderNames.begin()+h);
  577.       folderId.erase(folderId.begin()+h);
  578.     }
  579.     }
  580.  
  581. }
  582.  
  583. int compareIdFold(const string *fold, int id)
  584. {
  585.   int it;
  586.   for (int i = 0; i < folderNames.size(); i++)
  587.     {
  588.       if (*fold == folderNames[i] && id == folderId[i])
  589.     {
  590.       it = folderId[i];
  591.       return it;
  592.     }
  593.     }
  594.   return 999;
  595. }
  596.  
  597. void getStat()
  598. {
  599.   int num;
  600.   for (int i = 0; i < numOfDir; i++)
  601.     {
  602.       if (inF == 2)
  603.     {
  604.       cin >> num;
  605.       if (num != 0)
  606.         {
  607.           int buffId;
  608.           folderNames.push_back(elements[i]);
  609.           folderId.push_back(i);
  610.           cout << elements[i] << endl;
  611.           for (int j = 0; j < num; j++)
  612.         {
  613.           cin >> buffId;
  614.           parentId[buffId] = i;
  615.         }
  616.         }
  617.     }
  618.       else if (inF == 3)
  619.     {
  620.       cin >> num;
  621.       parentId[i] = num;
  622.       if (checkFoldExist(num) == false)
  623.         {
  624.           folderId.push_back(num);
  625.           if (num == -1)
  626.         num = 0;
  627.           folderNames.push_back(elements[num]);
  628.  
  629.         }
  630.      
  631.     }
  632.       else if (inF == 4 && i != 0)
  633.     {
  634.       cin >> num;
  635.       int bj;
  636.       cin >> bj;
  637.       parentId[bj] = num;
  638.       if (checkFoldExist(num) == false)
  639.         {
  640.           folderId.push_back(num);
  641.           folderNames.push_back(elements[num]);
  642.         }
  643.     }
  644.     }
  645. }
  646.  
  647. bool checkFoldExist(int foldId)
  648. {
  649.   for (int i = 0; i < folderNames.size(); i++)
  650.     {
  651.       if (folderId[i] == foldId)
  652.     return true;
  653.     }
  654.   return false;
  655. }
  656. bool readXml(int *idb, int parId)
  657. {
  658.   size_t bPos = 0;
  659.   size_t ePos = 0;
  660.   string element;
  661.   string buff;
  662.  
  663.   do
  664.     {
  665.       getline(cin, buff);
  666.       bPos = buff.find_first_of("'", bPos);
  667.       ePos = buff.find_first_of("'", bPos+1);
  668.       if (bPos != string::npos && ePos != string::npos)
  669.     {
  670.       element = buff.substr(bPos+1, ePos-bPos-1);
  671.       elements.push_back(element);
  672.       strokeId.push_back(*idb);
  673.       parentId.push_back(parId);
  674.       *idb += 1;
  675.       if (buff.find("<dir name") != string::npos)
  676.         {
  677.           folderNames.push_back(element);
  678.           folderId.push_back(*idb-1);
  679.           readXml(idb, *idb-1);
  680.         }
  681.     }
  682.      
  683.       bPos = buff.find_first_not_of(" ");
  684.       if (bPos != string::npos)
  685.     buff = buff.substr(bPos);
  686.       else
  687.     buff = buff.substr(0);
  688.       if (parId == -1)
  689.     break;
  690.     } while (buff != "</dir>");
  691.   numOfDir = *idb;
  692. }
  693.  
  694.  
Advertisement
Add Comment
Please, Sign In to add comment