Algorithm/C++ 从文本文件中提取模式的代码
Algorithm/C++ code for extracting patterns from text file
一个包含大型 switch case 的文件作为输入给出。个案从 0 递增到 n。每个案例都有一些特定的元素(a、b 等)。
输出将由三部分组成:包含所有唯一元素的向量,包含使用元素的第一个位置(案例)的第二个向量,最后是包含元素周期性的第三个向量。
输入将是这样的文本文件:
//standard comment useful for parsing file
switch something
{
case 0:
a;
b;
c;
break;
case 1:
break;
case 2:
a;
break;
case 3:
d;
break;
case 4:
a;
d;
break;
}
输出:
向量 1 将是 {a, b, c, d}
矢量 2 将为 {0, 0, 0, 3}
Vector 3 为{2, 0, 0, 1} *注:0为非循环元素,2为
元素两次连续出现之间的情况差异
(案例 4 - 案例 2 = 案例 2 - 案例 0 = 2)。这种差异会重演
所以我们只需要比较连续出现的两个。
此外,此算法应该适用于包含数十万行代码的超大文件。
考虑到文本文件的格式是一致的,并且正是问题中描述的格式,一种方法是边读行边解析。我确信有更好的方法,但无需过多参与,这就是我得到的:
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
int main()
{
std::ifstream inputFile("cases.txt");
std::vector<char> uniqueChars;
std::vector<int> firstCase;
std::vector<int> periodicity;
std::string inputLine;
while (std::getline(inputFile, inputLine, '\n'))
{
if (inputLine.compare(0, 5, "case ") == 0)
{
int caseN = std::stoi(inputLine.substr(5));
while (std::getline(inputFile, inputLine, '\n') && inputLine != " break;")
{
std::istringstream iss(inputLine);
char c, semi;
while (iss >> c >> semi)
{
auto found = std::find(uniqueChars.begin(), uniqueChars.end(), c);
if (found == uniqueChars.end())
{
uniqueChars.push_back(c);
firstCase.push_back(caseN);
periodicity.push_back(0);
}
else
{
size_t charPos = std::distance(uniqueChars.begin(), found);
if (periodicity[charPos] == 0)
{
periodicity[charPos] = std::abs(caseN - firstCase[charPos]);
}
}
}
}
}
}
// print
for (auto c : uniqueChars)
std::cout << c << " ";
std::cout << std::endl;
for (auto i : firstCase)
std::cout << i << " ";
std::cout << std::endl;
for (auto p : periodicity)
std::cout << p << " ";
std::cout << std::endl;
return 0;
}
示例文件的输出:
一个包含大型 switch case 的文件作为输入给出。个案从 0 递增到 n。每个案例都有一些特定的元素(a、b 等)。
输出将由三部分组成:包含所有唯一元素的向量,包含使用元素的第一个位置(案例)的第二个向量,最后是包含元素周期性的第三个向量。
输入将是这样的文本文件:
//standard comment useful for parsing file
switch something
{
case 0:
a;
b;
c;
break;
case 1:
break;
case 2:
a;
break;
case 3:
d;
break;
case 4:
a;
d;
break;
}
输出:
向量 1 将是 {a, b, c, d}
矢量 2 将为 {0, 0, 0, 3}
Vector 3 为{2, 0, 0, 1} *注:0为非循环元素,2为 元素两次连续出现之间的情况差异 (案例 4 - 案例 2 = 案例 2 - 案例 0 = 2)。这种差异会重演 所以我们只需要比较连续出现的两个。
此外,此算法应该适用于包含数十万行代码的超大文件。
考虑到文本文件的格式是一致的,并且正是问题中描述的格式,一种方法是边读行边解析。我确信有更好的方法,但无需过多参与,这就是我得到的:
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
int main()
{
std::ifstream inputFile("cases.txt");
std::vector<char> uniqueChars;
std::vector<int> firstCase;
std::vector<int> periodicity;
std::string inputLine;
while (std::getline(inputFile, inputLine, '\n'))
{
if (inputLine.compare(0, 5, "case ") == 0)
{
int caseN = std::stoi(inputLine.substr(5));
while (std::getline(inputFile, inputLine, '\n') && inputLine != " break;")
{
std::istringstream iss(inputLine);
char c, semi;
while (iss >> c >> semi)
{
auto found = std::find(uniqueChars.begin(), uniqueChars.end(), c);
if (found == uniqueChars.end())
{
uniqueChars.push_back(c);
firstCase.push_back(caseN);
periodicity.push_back(0);
}
else
{
size_t charPos = std::distance(uniqueChars.begin(), found);
if (periodicity[charPos] == 0)
{
periodicity[charPos] = std::abs(caseN - firstCase[charPos]);
}
}
}
}
}
}
// print
for (auto c : uniqueChars)
std::cout << c << " ";
std::cout << std::endl;
for (auto i : firstCase)
std::cout << i << " ";
std::cout << std::endl;
for (auto p : periodicity)
std::cout << p << " ";
std::cout << std::endl;
return 0;
}
示例文件的输出: