统计某一文本中的数据

    xiaoxiao2024-10-18  4

    数据以文本形式给出,分为两列,列之间以tab键分隔,也就是'\t', 第一列是年份,第二列是value。

    同一个年份,连续大于50的value,为一个元组。

    求这样的元组的数目。

    注意:如果给出的是excl文本,需要另存为work.txt文件,然后使用nodpad++将编码转换成无BOM的utf-8格式。

    时间仓促,没有考虑资源泄漏,但不影响结果。

    此外,需要以年为单位,统计每年中符合以上条件的元组,并保存到文本里,暂时保存的output.txt文件。

    如果要将output.txt纯文本转换成xslx格式,那就新建一个xslx文件,然后用这个文件打开output.txt文件,然后选择tab键作为分隔符,就能转换成功了。

    使用tab键作为分隔符的原因,是因为我发现把xslx文件自动转换成纯文本后,该程序默认使用了tab做分隔,就遵循惯例了。

    #include <fstream> #include <string> #include <iostream> #include <list> #include <map> #include <string.h> #include <stdio.h> using namespace std; const char *FILENAME = "./data/work.txt"; const char *OUTPUT = "./data/work_output.txt"; struct LineValue{ int year; int value; }; struct LineList { LineValue* lv; LineList *next; }; LineValue lvFirst = { 0, 0 }; LineList First = { &lvFirst, NULL }; LineList *NowList = &First; void showList(LineList *list) { LineList *prt = list; while (prt != NULL) { cout << "year: " << prt->lv->year << endl; cout << "value: " << prt->lv->value << endl; prt = prt->next; //getchar(); } } void showLV(LineValue* lv) { if (lv == NULL) { cout << "lv is NULL" << endl; return; } cout << "year: " << lv->year << endl; cout << "value" << lv->value << endl; } void writeOutput(std::map<int, int> &m_calMap, const char* filename) { ofstream in; in.open(filename, ios::trunc); map<int, int>::iterator it; for (it = m_calMap.begin(); it != m_calMap.end(); ++it) { in << it->first << '\t' << it->second << '\n'; } in.close(); } void showCalMap(std::map<int, int> &m_calMap) { map<int, int>::iterator it; for (it = m_calMap.begin(); it != m_calMap.end(); ++it) { cout << it->first << '\t' << it->second << endl; } //getchar(); } const int STANDARD = 50; const int LENSET = 6; const int YEAR_END = 2012; std::map<int, int>& calMap(LineList *list, std::map<int, int >& m_resault) { int len = 0; int var_num = 0; int year = list->lv->year; LineList *prt = list; while (prt->next != NULL) { if (prt->lv->year == prt->next->lv->year) { if ((prt->lv->value >= STANDARD) && (prt->next->lv->value >= STANDARD)) { ++len; if (len == LENSET) { len = 0; ++var_num;; } } } else { // new year m_resault.insert(pair<int, int>(year, var_num)); year = prt->next->lv->year; len = 0; var_num = 0; } LineList *next = prt->next; if (next->next == NULL) { int end_year = prt->lv->year; m_resault.insert(pair<int, int>(end_year, var_num)); } prt = next; } return m_resault; } int calList(LineList *list) { int coutNum = 0; int len = 0; LineList *prt = list; while (prt->next != NULL) { if ((prt->lv->year == prt->next->lv->year) && (prt->lv->value >= STANDARD) && (prt->next->lv->value >= STANDARD)) { ++len; if (len == LENSET) { len = 0; ++coutNum; } } else { len = 0; } prt = prt->next; } cout << "coutNum: " << coutNum << endl; getchar(); return coutNum; } //模板函数:将string类型变量转换为常用的数值类型(此方法具有普遍适用性) template <class Type> Type stringToNum(const string& str) { istringstream iss(str); Type num; iss >> num; return num; } int main() { ifstream in(FILENAME); string filename; string line; if (in) // 有该文件 { while (getline(in, line)) // line中不包括每行的换行符 { //cout << line << endl; int iBegin = 0; string::size_type iLatter = 0; string::size_type iFormer = string::npos; LineValue *LV = new LineValue; LineList *linelist = new LineList; linelist->lv = LV; linelist->next = NULL; NowList->next = linelist; NowList = linelist; int num = 1; while (1) { iLatter = line.find_first_not_of('\t', iLatter); if (string::npos == iLatter) { break; } iFormer = line.find_first_of('\t', iLatter + 1); if (string::npos == iFormer) { iFormer = line.length(); } string strNew(line, iLatter, iFormer - iLatter); int lvalue = atoi(strNew.c_str()); //cout << lvalue << endl; if (num == 1) { LV->year = lvalue; ++num; } else { LV->value = lvalue; } iLatter = iFormer + 1; } //getchar(); } } else // 没有该文件 { cout << "no such file" << endl; } // showList(&First); calList(&First); std::map<int, int> m_res; calMap(&First, m_res); showCalMap(m_res); writeOutput(m_res, OUTPUT); return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-1292749.html
    最新回复(0)