我正在尝试将一些我不认识的人用 C 语言编写的与研究相关的代码(绝对没有文档)转换为 C++。 基本上将 T* 和 T** 对象转换为向量和更用户友好的容器。
Atm 我有两个变量,
double* data
double* references
我在这里看到了一个技巧,它可以使正则向量轻松分配给 double*,如下所示:
references = &(*m_DataMaxPoints)[0];
所以没关系。
但是,数据*应该从
std::vector<std::vector<double>>* m_Data;
设置
我不知道应该如何分配它。 我尝试过
&(*m_Data)[0][0];
,但我真的不知道我应该在这里做什么。
欢迎任何提示..:(
编辑 1:C 程序中数据*的原始处理
double* 数据在 main() 中声明
int main(int argc, char *argv[])
{
FILE *infile;
int verbose_flag = FALSE;
double *data = NULL, *reference = NULL, *maximum = NULL;
int *cumsizes = NULL;
int nobj = 0, nruns = 0;
int k;
double volume = 0;
double time_elapsed;
read_input(stdin, "stdin", &data, &nobj, &cumsizes, &nruns);
read_input 将文本文件中的数字解析为数组。
#define PAGE_SIZE 4096 // allocate one page at a time
#define DATA_INC (PAGE_SIZE/sizeof(double))
#define SET_INC 128 // assume 128 datasets (can grow)
int read_input(FILE *infile, const char *filename, double **datap, int *ncolsp, int **cumsizesp, int *nrunsp)
{
char b[2];
double number;
int newline; // last input was newline
int datai; // the current element of (*datap)
int col; // the column being read
int set = *nrunsp; // the current data set
int ncols = *ncolsp; // the number of columns
int datasize;
int setsize;
datai = (set == 0)
? 0
: ncols * (*cumsizesp)[set-1];
setsize = (set == 0)
? 0
: ((set-1) / SET_INC + 1) * SET_INC;
*cumsizesp = realloc(*cumsizesp, setsize * sizeof(int));
datasize = (datai == 0)
? 0
: ((datai - 1) / DATA_INC + 1) * DATA_INC;
*datap = realloc(*datap, datasize * sizeof(double));
// remove leading whitespace
fscanf (infile, "%*[ \t\n]");
if (feof(infile)) {
warnprintf("%s: file is empty.", filename);
return -1;
}
do {
newline = 0;
if (set == setsize) {
setsize += SET_INC;
*cumsizesp = realloc(*cumsizesp, setsize * sizeof(int));
}
(*cumsizesp)[set] = (set == 0) ? 0 : (*cumsizesp)[set-1]; // beginning of data set
while (newline == 0) {
col = 0; // beginning of row
while (newline == 0) {
if (fscanf(infile, "%lf", &number) != 1) {
char buffer[64];
fscanf(infile, "%60s", buffer);
errprintf(
"could not convert string `%s' to double, exiting...",
buffer);
}
if (datai == datasize) {
datasize += DATA_INC;
*datap = realloc(*datap, datasize * sizeof(double));
}
(*datap)[datai++] = number;
#if DEBUG > 2
fprintf(stderr, "set %d, row %d, column %d, x = %g\n",
set, (*cumsizesp)[set], col, number);
#endif
col++; // new column
fscanf(infile, "%*[ \t]");
newline = fscanf(infile, "%1[\n]", b);
}
if (!ncols)
ncols = col;
else if (col != ncols) {
if ((*cumsizesp)[0] == 0)
errprintf ("reference point has dimension %d"
" while input has dimension %d",
ncols, col);
else
errprintf("row %d has different length (%d)"
" than previous rows (%d), exiting...",
(*cumsizesp)[set], col, ncols);
}
(*cumsizesp)[set]++;
fscanf (infile, "%*[ \t]");
newline = fscanf (infile, "%1[\n]", b);
}
#if DEBUG > 1
fprintf (stderr, "Set %d, %d rows in total\n", set, (*cumsizesp)[set]);
#endif
set++; // new data set
fscanf (infile, "%*[ \t\n]");
} while (!feof(infile));
*ncolsp = ncols;
*nrunsp = set;
return 0;
}
我想做的是尽可能少地转换为 C++,以便通过为此接口创建一个包装类,使其更易于使用和实现到更大的项目中。
因此,文件解析和数据分配是通过向量完成的(它们不需要是指针)。
解析后,我更喜欢将向量转换为C风格的数组,这样我就可以调用原始代码的函数,而不必添加向量来支持所有这些,因为我不明白如何以纯文本方式读取它C(多目标进化算法实现)。原代码最终调用:
volume = hv(data, nobj, cumsizes[nruns-1], reference);
虽然我想这样做:
double* data = &(*m_Data)[0][0]; // my 2d vector<double>
double* references = &(*m_DataMaxPoints)[0]; // 1d vector<double>
int cumsizes = m_Data->at(0).size();
m_Volume = hv(data, Objectives(), cumsizes, references);
不是必要的方法,正如你的问题迭代器的评论中提到的那样,但是这将是一个不错的选择。不管怎样,如果你真的想使用指针,这里就是这样的:
vector< vector<double> >* vec = new vector< vector<double> >(16);
for (size_t i = 0; i < 16; ++i) {
(*vec)[i].resize(16);
}
(*vec)[4][2] = 6.66;
此代码创建一个指针( vec ),指向未初始化的双精度向量向量(维度为 16x16),位置 [4][2] 处值为 6.66,我想您现在已经得到了合成。
std::vector
用于处理所有内存分配。它不需要
malloc
、
realloc
或
new
。如果不重写大部分代码,您就无法有效地实现这一点。如果您希望 C 代码在 C++ 中编译,则需要进行一些小的更改,例如转换:
*datap = (double*)realloc(*datap, datasize * sizeof(double));
此外,您可以通过引用传递 C++ 对象,因此不需要指针。通过引用传递向量。最简单的方法是保留现有的 C 代码,然后将数据从
datap
复制到
vec
。示例:
void foo(std::vector<std::vector<double>> &vec)
{
//copy from datap to vec:
//add a new row:
vec.push_back(std::vector<double>{});
//add columns
vec.back().push_back(11.0f);
vec.back().push_back(12.0f);
vec.back().push_back(13.0f);
//add another row:
vec.push_back(std::vector<double>{});
//add columns
vec.back().push_back(21.0f);
vec.back().push_back(22.0f);
vec.back().push_back(23.0f);
}
int main()
{
std::vector<std::vector<double>> vec;
foo(vec);
for(size_t row = 0; row < vec.size(); row++)
{
for(size_t col = 0; col < vec[row].size(); col++)
printf("%3.0f, ", vec[row][col]);
printf("\n");
}
return 0;
}
或者你也可以用 C++ 重写整个代码。示例:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
void read_matrix(std::vector<std::vector<double>> &vec)
{
std::ifstream fin("file.txt");
if(!fin)
return;
std::string line;
while(std::getline(fin, line))
{
//add a new row:
vec.push_back(std::vector<double>{});
//add columns
std::stringstream ss(line);
double value;
while(ss >> value)
vec.back().push_back(value);
}
}
int main()
{
std::vector<std::vector<double>> vec;
read_matrix(vec);
...
return 0;
}