0

要使用给定的图形包,我需要定义、预订和填充直方图。我怎样才能得到直方图的名称,它是一个字符串,在 3 for 循环中与 2 个整数作为字符串 ( hts_i_j ) 连接。这必须在 C++ 中完成 请参见下面的示例

界定

TH1F* hts_5_53;
TH1F* hts_5_54;
……
TH1F* hts_5_69;

预订

hts_5_53= HDir.make<TH1F>("hts_5_53")," Title", 100,0.,100.);
hts_5_54->HDir.make<TH1F>("hts_5_54")," Title", 100,0.,100.);
……
hts_16_69->HDir.make<TH1F>("hts_16_69")," Title", 100,0.,100.);

填写

hts_5_53->Fill(f)
hts_5_54->Fill(f)
……
hts_16_69->Fill(f)

相反,我想定义、预订和填写 3 个 for 循环。例如。

for(int i=5, i<17, ++i){
  for(int j=53, j<70, ++j){

   hts_i_j 

 } 
}

如何在定义、预订和填充 3 for 循环时以简单的方式将字符串 hts 与索引 (i,j) 连接起来

4

4 回答 4

1

您不能在代码中构造字符串,然后使用这些名称返回具有这些名称的变量。编译器在将您的程序构建为可执行代码时会丢弃变量的名称。

您正在做的事情可能最好用array解决。hts定义一个具有您需要的维度的数组名称。C++ 数组总是从零开始索引,但您的最低界限似乎是五。您可以在使用它们时从所有索引中减去五个,或者您可以使数组的五个元素更长,并“丢弃”较低的元素。

TH1F* hts[17][70];
for (int i = 5; i < 17; ++i) {
  for (int j = 53; j < 70; ++j) {
    ostringstream name;
    name << "hts_" << i << "_" << j;
    hts[i][j] = HDir.make<TH1F>(name.str()), " Title", 100, 0., 100.);
  }
}

您的make行中某处有语法错误;我没有尝试在这里修复它。

要拥有最小大小的数组,您必须在使用索引之前对其进行按摩:

int const Offset1 = 5;
int const Offset2 = 53;
TH1F* hts[17-Offset1][70-Offset2];
for (int i = Offset1; i < 17; ++i) {
  for (int j = Offset2; j < 70; ++j) {
    ostringstream name;
    name << "hts_" << i - Offset1 << "_" << j - Offset2;
    hts[i][j] = HDir.make<TH1F>(name.str()), " Title", 100, 0., 100.);
  }
}

另一种选择是使用mapfrom 字符串到您的 TH1F 对象:

std::map<std::string, TH1F*> hts;
for (int i = 5; i < 17; ++i) {
  for (int j = 53; j < 70; ++j) {
    ostringstream name;
    name << "hts_" << i << "_" << j;
    hts.insert(name.str()), HDir.make<TH1F>(name.str()), " Title", 100, 0., 100.));
  }
}

然后您可以使用该名称访问您想要的任何项目:

hts["hts_5_62"]->Fill(f);
于 2010-05-03T19:17:25.627 回答
0

在标准 C++ 中,字符串流是字符串格式化的基本解决方案:

std::ostringstream os;
os << "hts_" << i << "_" << j;

使用 检索结果字符串os.str()。有关替代方案的讨论,请参阅庄园农场的字符串格式化程序

使用生成的字符串和合适的容器,您的循环可能会变成:

for (int i=5; i<17; ++i) {
    for (int j=53; j<70; ++j) {
       hts[i][j] = f(str); 
    } 
}

但是,为什么您首先需要将索引存储在字符串中,我不清楚。

旁注:如果您正在从不涉及字符串格式和容器的合理使用的书中学习,请从 SOs book guide中选择一本好的介绍性书籍。

于 2010-05-03T19:01:26.440 回答
0

我真的不明白你的问题。

在为它们声明变量后,你对“书籍”做了什么?如果您将它们放在某种集合中,则可能不需要为每个集合声明一个变量。只需在内部 for 循环中声明一个通用变量,根据需要对其进行分配,然后将其放入您需要的任何集合中。

或者,如果你有一个程序只需要处理几本书,那么就按照你现在的做法去做,不要循环。只需手动声明每个。

于 2010-05-03T19:02:27.590 回答
0
//string concat with a macro
#define HTS_(i,j) hts_##i##_##j

//usage
//declare variables    
    TH1F* HTS_(5,53);
    TH1F* HTS_(5,54);
    //but note that the following produces variable hts_k_l, not hts_8_9;
    int k = 8;
    int l = 9;
    TH1F* HTS_(k,l);
    //use your variables
    hts_5_53 = HDir.make<TH1F>("hts_5_53")," Title", 100,0.,100.);
    hts_5_54 =HDir.make<TH1F>("hts_5_54")," Title", 100,0.,100.);

我认为 Boost.Preprocessor 能够在“循环”中使用它

但是我无法想象所有这些都可以应用于什么:) 它通常是用数组完成的

于 2010-05-12T10:54:03.867 回答