C ++ и Root, передавая 2D-массив в функцию и используя его в TGraph

Как я могу передать 2D-массив в функцию и использовать его как myArray [i] [j], но не зная размера этого массива внутри этой функции?

Я могу знать размер внутри основного.

Я хочу использовать это так:

TGraph *myGraph = new TGraph(nValues, myArray[0][j], myArray[1][j]);
// I'll not use a loop for j, since TGraph receives all the values in the array,
like "x values" and "y values"

Если я делаю это так, это работает, но я должен был бы перейти к функции Col1 и Col2, которые являются двумя одномерными массивами:

main() {
...
graphWaveTransmittance("a", nValues, Col1, Col2,
" Au ", "Evaporated", "thickness 5nm", kGreen+1);
...
}void graphWaveTransmittance(char *n, int nValues, float Param1[], float Param2[],
char *title, char *header, char *entry, Color_t color) {

TGraph *myGraph = new TGraph(nValues, Param1, Param2);
...
}

Массив:

float valuesArray[nCol][nValues];

for(int y=0; y<nValues; y++){
for (int i=0; i<nCol; i++) {
valuesArray[i][y] = values[i][y];
}
i=0;
}

Примечание: я сделал это так, потому что values ​​[] [] — это массив со значениями, которые считываются из текстового файла. Прежде чем читать файл, я не знаю, сколько строк будет необходимо. С этим вторым массивом (valuesArray [] []) я могу сделать так, чтобы он имел размер только числа значений, которые читаются.

Во-первых, я поместил все значения в values ​​[] [] с «-1», и его размер очень большой. Затем я посчитал количество строк и просто использовал это значение для valuesArray [] []. Это первый массив со значениями (большой):

const int nCol = countCols;
float values[nCol][nLin];

// reads file to end of *file*, not line
while(!inFile.eof()) {
for(int y=0; y<nLin; y++){
for (int i=0; i<nCol; i++) {
inFile >> values[i][y];
}
i=0;
}
}

Еще один вопрос, я видел, что «while (! InFile.eof ())» не должно использоваться. Что я могу использовать вместо этого? (Я не знаю общее количество строк из файла .txt на данный момент)

Импортируя значения в столбцах в .txt, до сих пор у меня есть:

    vector<vector<float> > vecValues;  // your entire data-set of values

vector<float> line(nCol, -1.0);  // create one line of nCol size and fill with -1

bool done = false;
while (!done)
{
for (int i = 0; !done && i < nCol; i++)
{
done = !(inFile2 >> line[i]);
}
vecValues.push_back(line);
}

Проблема в том, что значения похожи на vecValues ​​[значение] [номер столбца из .txt] Я хочу иметь vecValues ​​[номер столбца из .txt] [значение].

Как я могу это изменить?


Я читаю из файла так:

main() {
...

vector < vector <float> > vecValues; // 2d array as a vector of vectors
vector <float> rowVector(nCol); // vector to add into 'array' (represents a row)
int row = 0; // Row counter// Dynamically store data into array
while (!inFile2.eof()) { // ... and while there are no errors,
vecValues.push_back(rowVector); // add a new row,
for (int col=0; col<nCol; col++) {
inFile2 >> vecValues[row][col]; // fill the row with col elements
}
row++; // Keep track of actual row
}graphWaveTransmittance("a", nValues, vecValues, " Au ",
"Evaporated", "thickness 5nm", kGreen+1);
// nValues is the number of lines of .txt file
...
}//****** Function *******//

void graphWaveTransmittance(char *n, int nValues,
const vector<vector <float> > & Param, char *title, char *header,
char *entry, Color_t color) {

// like this the graph is not good
TGraph *gr_WTransm = new TGraph(nValues, &Param[0][0], &Param[1][0]);

// or like this
TGraph *gr_WTransm = new TGraph(Param[0].size(), &Param[0][0], &Param[1][0]);

Примечание: TGraph может принимать числа с плавающей точкой, мои предыдущие массивы были числами с плавающей точкой

Знаете ли вы, почему график не отображается правильно?

Спасибо

0

Решение

Недавно я столкнулся с подобной проблемой. Я закончил с использованием двухмерного векторы, которому не нужно знать внутреннее измерение при передаче функции.

Объявите векторы как это

vector< vector<int> > vec(xRange, vector<int>(yRange, initialValue));

При замене xRange на ваш размер в измерении x, yRange на ваш размер в направлении y, а initialValue — на то, с чем вы хотите инициализировать 2d-вектор.

На этом этапе вы можете получить доступ или обновить векторное содержимое, используя

vec[x][y]

Чтобы передать это функции, используйте эту

void myFunc(std::vector< std::vector<int> >& vec) {

Обязательно

#include <vector>
0

Другие решения

Вы можете использовать векторы, чтобы решить эту проблему, как уже упоминал Майкл Паркер. Чтобы заставить его работать в root с графиками, обратите внимание, что TGraph ожидает два массива типа double или float в качестве параметров.
Поэтому вы должны использовать

std::vector<std::vector<double> >
или же
std::vector<std::vector<float> >

в твоем случае.
Тогда ваша функция выглядит так:

void drawGraph(const std::vector<std::vector<double> > & data)
{
TGraph* graph = new TGraph(data[0].size(), &data[0][0], &data[1][0]);
//...

}

&data[0][0] «конвертирует» векторы в массивы, как того требует TGraph.

По поводу вашего второго вопроса, вместо использования !inFile.eof()Я обычно прямо спрашиваю, был ли процесс чтения успешным, т.е. в вашем случае:

if(!(inFile >> values[i][y]))
{
//at end of file
}

Я предпочитаю использовать это во время цикла, но это дело вкуса.
Кстати, с помощью векторов вам больше не нужно запускать хотя весь файл заранее, чтобы посчитать количество строк, просто используйте push_back(...),

Если вы не знаете ни количества строк, ни количества столбцов, вы можете использовать getline для считывания файла и определения количества столбцов:

std::vector<std::vector<float> > data;
std::string buffer;
getline(infile,buffer)//I do not check that the file has at least one line here
istringstream firstLine(buffer);
float value;
while(firstline >> value)
{
data.push_back(std::vector<float>(1,value));
}

while(getline(infile,buffer))
{
istringstream line(buffer);
float value;
unsigned int counter = 0;
while(line >> value)
{
data[counter].push_back(value));
counter++;
}
}

Обратите внимание, что это требует:

 #include<sstream>

и это предполагает, что количество столбцов не изменяется в зависимости от размера файла.

0

По вопросам рекламы [email protected]