Как я могу передать 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 может принимать числа с плавающей точкой, мои предыдущие массивы были числами с плавающей точкой
Знаете ли вы, почему график не отображается правильно?
Спасибо
Недавно я столкнулся с подобной проблемой. Я закончил с использованием двухмерного векторы, которому не нужно знать внутреннее измерение при передаче функции.
Объявите векторы как это
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>
Вы можете использовать векторы, чтобы решить эту проблему, как уже упоминал Майкл Паркер. Чтобы заставить его работать в 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>
и это предполагает, что количество столбцов не изменяется в зависимости от размера файла.