我循环浏览文本文件,将每个段落读成字符串。我想处理包含一年的任何段落,但如果没有找到年份,那么我想继续循环遍历该文件。当找到一年时,我想知道找到那一年的指数。
为了简单起见,我试图避免任何提升或正则表达式代码。我还假设,为了简单起见,唯一感兴趣的年份将是在20世纪和2000年代。我尝试了以下代码,但由于某种原因,通配符不起作用。是因为通配符对数字不起作用吗?
string sParagraph = "Aramal et al. (2011), Title";
int iIndex;
if (sParagraph.find("19??")!=string::npos)
iIndex = sParagraph.find("19??");
else if (sParagraph.find("20??")!=string::npos)
iIndex = sParagraph.find("20??");
else
continue;
答案 0 :(得分:0)
我几天前正在寻找类似的东西。我的方法可能非常(非常非常)效率低下:我循环遍历整个字符串并使用' atoi()'看看每组四个角色是否都是一年。
for (int i = 0; i < txt.length() - 3; i++)
{
string t = txt.substr(i, 4); //Take a group of four characters.
int year = atoi((char*)t.c_str());
if (year > 1800 && year < 3000)
{
break;
}
else year = 0;
}
最后,&#39;年&#39;是零或实际年份。
答案 1 :(得分:0)
如果不使用正则表达式或增强代码,可能会使代码更具可读性,但它不会更简单。
“简单”一遍伪算法:
map<int, std::vector<int>> years;
String par = " ... "
//inefficient but didn't want to have to add more complicated code
//in the while loop. Just want to solution to be clear
int par_index = par.find_first_of("19");
if(par_index == string::npos)
par_index = par.find_first_of("20");
if(par_index == string::npos)
//skip //No years in this paragraph
while(par_index < par.size()) {
string year(par, par_index, 4);
int year = atoi(year.c_str()); //or use C++11 stoi
if(2100 < year && year >= 1900)
years.at(year).push_back(par_index);
par_index += 4;
}
这将创建一个映射,其中键是年份,值是一个int的向量,表示年份登陆的索引。
答案 2 :(得分:0)
所以你当然可以这样做。但它不会更简单,它会更复杂。
无论如何,这可能是您最好的非正则表达式解决方案。它使用string::iterator
而不是位置:
string sParagraph = "Aramal et al. (2011), Title";
auto iIndex = adjacent_find(sParagraph.begin(), sParagraph.end(), [](char i, char j){return i == '1' && j == '9' || i == '2' && j == '0'; });
const auto end = next(sParagraph.end(), -3);
while (iIndex < end && (isdigit(static_cast<int>(*next(iIndex, 2))) == false || isdigit(static_cast<int>(*next(iIndex, 3))) == false)){
iIndex = adjacent_find(next(iIndex, 4), sParagraph.end(), [](char i, char j){return i == '1' && j == '9' || i == '2' && j == '0'; });
}
要使用此功能,您需要检查是否已迭代到end
:
if(iIndex < end){
continue;
}
为了便于比较,您可以使用regex_search
来确定年份是否存在:
string sParagraph = "Aramal et al. (2011), Title";
smatch iIndex;
if (!regex_search(sParagraph, iIndex, regex("(?:19|20)\\d{2}"))){
continue;
}
smatch
包含更多信息,只包含一个位置,但如果您想要年初的索引,您可以执行以下操作:iIndex.position()
对于不熟悉C ++ 11功能的人来说,常见的陷阱是:“我不明白如何使用这些东西,它必须比我已经知道的更复杂。”然后回到他们已经知道的东西。不要犯这个错误,请使用regex_search
。