开始数据拖网例程的建议

时间:2011-11-16 17:41:22

标签: c++

我正在寻找关于创建数据拖网例程的最有效方法的一些一般性建议。我对C ++有基本的了解。

我需要创建一个例程来搜索具有以下格式的文本文件(示例):

4515397   404.4    62.5  1607.0     2.4     0.9 ...
4515398   404.4    62.3  1607.0     3.4     1.2 ...
4515399   404.4    62.2  1608.0     4.6     0.8 ...
4515400   405.1    62.2  1612.0     5.8     0.2 ...
4515401   405.9    62.2  1615.0     6.9    -0.8 ...
4515402   406.8    62.2  1617.0     8.0    -2.7 ...
4515403   406.7    62.1  1616.0     9.0    -5.3 ...

在上面的示例中,当列5和列6都小于4 时,我感兴趣的是导出第2列和第3列的平均值。我实际上并不对第1,4或7列中的值感兴趣(省略号正是它们在文件本身中的显示方式)。

为了使问题更加复杂,文件中偶尔会出现随机文本字符串,如下所示(这些可以丢弃):

4522787   429.6    34.4  2024.0    .       .    ...
4522788   429.9    34.2  2022.0    .       .    ...
4522789   429.9    34.1  2022.0    .       .    ...
EFIX R   4522633    4522789 157   427.9    36.8    2009
4522790   429.3    34.2  2021.0    .       .    ...
END 4522791     SAMPLES EVENTS  RES   23.91   23.82
MSG 4522799 TRIAL_RESULT 0
MSG 4522799 TRIAL OK

最后,每个文本文件包含五组数据,我打算对这些数据进行平均。这5个数据集中的每一个都由这样的行界定:

MSG 4502281 START_GRAB

MSG 4512283 END_GRAB

这些界限之外的所有东西都可以扔掉。

因此,作为一个相对缺乏经验的程序员,我开始研究实现目标的最有效方法。什么是我最好的方法;即C ++对于这类任务来说是不必要的复杂吗?也许甚至有一个实用工具可以进行这种数据拖网工作?

现在我发现我可能会使用Microsoft Excel脚本为我执行此操作。我想知道对此的任何想法。

2 个答案:

答案 0 :(得分:1)

我从天真的方法开始,看看我能走多远:

#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>

int main()
{
  std::ifstream infile("thefile.txt");
  if (!infile) { return 0; }

  std::vector<double> v2, v3;

  std::string line;
  while (std::getline(infile, line))
  {
    int id;
    double col1, col2, col3, col4, col5, col6;
    std::istringstream iss(line);

    if (iss >> id >> col1 >> col2 >> col3 >> col4 >> col5 >> col6)
    {
       // we only get here if the first token is an integer!

       if (col5 < 4.0 && col6 < 4.0)
       {
         v2.push_back(col2);
         v3.push_back(col3);
       }
    }
    else
    {
      iss.clear(); // clear error
      std::string id;
      if (iss >> id && id == "MSG")
      {
        // process the special block
      }
    }
  }

  // now compute the average of the v2 and v3:
  double av2 = std::accumulate(v2.begin(), v2.end(), 0) / double(v2.size());
  double av3 = std::accumulate(v3.begin(), v3.end(), 0) / double(v3.size());
}

答案 1 :(得分:0)

如果你想用C ++解决它,我强烈推荐Boost regex

基本上,您需要三个正则表达式:一个用于START_GRAB,一个用于有效负载线,一个用于END_GRAB线。编写正则表达式并不太难。网上有很多教程,你可以在这里试试你的正则表达式:

http://gskinner.com/RegExr/