【问题标题】:Running function with ifstream and stringstream multiple times使用 ifstream 和 stringstream 多次运行函数
【发布时间】:2021-02-18 10:44:12
【问题描述】:

我对 c++ 相当陌生,如果有更好/更优化的方法来使用调用 ifstream 和字符串流的函数,我想征求意见/建议。

我有一个包含 150 行和 8 列结构的文档(简化了值的小子集):

5.43e-08    0.0013  0.0105  0.013   0.026   0.068   0.216   0.663
6.98e-08    0.0004  0.0188  0.022   0.103   0.854   0   0
7.31e-08    0.0004  0.0125  0.017   0.074   0.895   0   0
5.82e-08    0.0006  0.0596  0.075   0.150   0.713   0   0

每行的数字代表一个位置(pos 1 ... pos 150),每列是质量的概率(Qual1 .. Qual8)。我的目标是从代表质量分布的每一行中采样,为所有 150 个位置创建一个质量字符串。我已经创建了一个可以做到这一点的函数。

std::string Qual(std::ifstream &infile){
  
  std::string line;
  double Q_1,Q_2,Q_3,Q_4,Q_5,Q_6,Q_7,Q_8;
  char Qualities[] = {'1', '2', '3', '4' ,'5', '6', '7','8','\0'};
  std::string Read_qual;

  while (std::getline(infile, line)){
    std::stringstream ss(line);
    ss >> Q_1 >> Q_2 >> Q_3 >> Q_4 >> Q_5 >> Q_6 >> Q_7 >> Q_8;
    
    std::srand(std::time(nullptr));
    std::random_device rd;
    std::default_random_engine gen(rd());
    std::discrete_distribution<> d({Q_1,Q_2,Q_3,Q_4,Q_5,Q_6,Q_7,Q_8});

    Read_qual += Qualities[d(gen)];
  }
  return Read_qual;
}

问题是我必须重复使用这个函数来创建多个基于其他输入的分布。据我在这里看到的堆栈溢出,我必须使用 .clear() 和 seekq 来保持文件打开但仍然使用它。

int main(int argc,char **argv){
  std::ifstream infile("Freq.txt");
  std::cout << Qual(infile) << std::endl;
  infile.clear();
  infile.seekg(0);
  std::cout << "-------" << std::endl;
  std::cout << Qual(infile);
  return 0;
}

我的问题是: 使用 c++ 时是否有更理想的解决方案来完成此任务。像任何可能更快的功能一样。任何人都可以提出任何建议吗? 继续打开和关闭文件更好吗?

【问题讨论】:

  • IMO,您所拥有的一切都没有问题,请保持简单。
  • 先将数据读入一个集合,然后多次使用该数据。
  • 谢谢大家!所以对于一个容器,比如vector(类似于下面),你会建议传递ss流然后从中随机采样吗?或者直接将随机样本放入容器中。
  • 为什么必须使用 infile.clear() 和 infile.seekg(0)?我想你会重复这个过程 150 次,每次都拿起下一行的 8 个双精度进行分布测试。如果您在每次调用 Qual 之前发出 infile.seekg(0),您将始终在第一行读取相同的 8 个数字。
  • @ytlu,谢谢你的提问!需要明确的是,文件本身是 150 行,每行有 8 列。因此,我为每一行创建了这 8 列的随机分布,然后我在其中选择一个带有“Read_qual += Qualities[d(gen)];”的字符给我 150 个质量值(每行一个值)。我必须重复这个过程,比如说 2000 次,但是为了让我重复这个过程,我必须在函数调用之间使用 infile.clear()。我觉得这并不理想,因此问题:-)

标签: c++ c++11 ifstream sstream


【解决方案1】:

让我们尝试缓存

完全未经测试的不完整代码

struct row { // your type that goes into the distribution
  double Q_1,Q_2,Q_3,Q_4,Q_5,Q_6,Q_7,Q_8;
};
using QualData = std::vector<row>;  // typedef

QualData ReadData(std::ifstream &infile) {
  std::string line;
  double Q_1,Q_2,Q_3,Q_4,Q_5,Q_6,Q_7,Q_8;
  char Qualities[] = {'1', '2', '3', '4' ,'5', '6', '7','8','\0'};
  std::string Read_qual;
  QualData qual;

  while (std::getline(infile, line)){
    std::stringstream ss(line);
    ss >> Q_1 >> Q_2 >> Q_3 >> Q_4 >> Q_5 >> Q_6 >> Q_7 >> Q_8;
    
    qual.emplace_back(Q_1,Q_2,Q_3,Q_4,Q_5,Q_6,Q_7,Q_8);
 
  }
  return qual;
}

... do qual

int main(int argc,char **argv){
  std::ifstream infile("Freq.txt");
  auto qualData = ReadData(infile);

  std::cout << Qual(qualData) << std::endl;
  std::cout << "-------" << std::endl;
  std::cout << Qual(qualData);
  return 0;
}

你可以想象还有什么需要改变的。

【讨论】:

  • 感谢您的建议。因为我是 C++ 新手,所以我不得不问。因此,您正在使用结构创建一个向量来包含行。然后使用“QualData ReadData(std::ifstream &infile)”调用向量,然后使用 emplace_back 在向量末尾插入行。那么ReadData是一个向量类型的函数吗?因为我以前从未见过使用 QualData = std::vector; 编写它
  • @RAHenriksen 这是 typedef 的新形式,更容易阅读。
  • 我建议将 main() 中的 8 个双精度值的每一行读入数组 [8] 或 vector(8) ,然后将数组传递给函数 Qual。
【解决方案2】:

我的建议:

std::string Qual(double *a)
{  
  std::string line;
  char Qualities[] = {'1', '2', '3', '4' ,'5', '6', '7','8','\0'};
  std::string Read_qual;
 
  std::srand(std::time(nullptr));
  std::random_device rd;
  std::default_random_engine gen(rd());
  std::discrete_distribution<> d({a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
  Read_qual += Qualities[d(gen)];
  return Read_qual;
}

和main()

 int main()
 {
  std::ifstream infile("Freq.txt");
  double alldata[150][8];
  for (int i=0, i<150; i++)
  for (int j=0; j<8; j++) infile >> alldata[i][j];
  infile.close();

  for (int idx = 0; idx < 2000; idx++)
  {
     for (int row = 0; row < 150; row++) 
     std::cout << Qual(alldata[row]) << std::endl;
   }
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    相关资源
    最近更新 更多