C ++ новичок: написание функции для извлечения векторов из файла. Как я могу получить неизвестное количество векторов из функции? - PullRequest
0 голосов
/ 22 сентября 2011

Я пишу функцию для получения наборов данных из файла и помещения их в векторы.Наборы данных затем используются в расчете.В этом файле пользователь записывает каждый набор данных в строку под заголовком «Dataset1».Результатом является i векторов к моменту завершения функции.Функция работает просто отлично.

Проблема в том, что я не знаю, как получить векторы из функции!(1) Я думаю, что могу вернуть только одну сущность из функции.Так что я не могу вернуть мне векторы.Кроме того, (2) я не могу записать векторы / наборы данных в качестве параметров функции и вернуть их по ссылке, поскольку количество векторов / наборов данных различается для каждого вычисления.Если есть другие возможности, я о них не знаю.

Я уверен, что это глупый вопрос, но я что-то здесь упускаю?Буду очень признателен за любые предложения.До сих пор я не помещал код извлечения вектора / набора данных в функцию;Я сохранил его в своем основном файле, где он работал нормально.Теперь я хотел бы очистить свой код, поместив весь код извлечения данных в свою собственную функцию.

Для каждого вычисления я действительно знаю количество векторов / наборов данных, которые функция найдет в файле, потому что у меня естьэта информация записана в файл и может его извлечь.Есть ли способ, которым я мог бы использовать эту информацию?

Ответы [ 3 ]

3 голосов
/ 22 сентября 2011

Если каждый вектор одного типа, вы можете вернуть std::vector<std::vector<datatype> >

Это будет выглядеть так:

std::vector<std::vector<datatype> > function(arguments) {  
    std::vector<std::vector<datatype> > return_vector;
    for(int i =0; i < rows; ++i) {
       \\ do processing
       return_vector.push_back(resulting_vector);
    }
    return return_vector;
} 
1 голос
/ 22 сентября 2011

Ваш вопрос по сути "Как мне вернуть кучу вещей из функции?" Бывает, что ваши вещи являются vector<double>, но это не очень важно. Важно то, что у вас есть куча их неизвестного размера.

Вы можете улучшить свое мышление, перефразировав один вопрос на два:

  • Как мне представить кучу вещей ?
  • Как мне вернуть это представление из функции?

Что касается первого вопроса, это именно то, что делают контейнеры . Контейнеры, как вы наверняка знаете, потому что вы уже используете один, содержат произвольное количество похожих объектов. Примеры включают в себя std::vector<T> и std::list<T>, среди других. Выбор того, какой контейнер использовать, продиктован обстоятельствами, которые вы не упомянули - например, насколько дорогими являются элементы для копирования, нужно ли удалять элемент из середины стопки и т. Д.

В вашем конкретном случае, зная, что мало мы знаем, кажется, вы должны использовать std::vector<>. Как вы знаете, параметр шаблона - это тип того, что вы хотите сохранить. В вашем случае это (по совпадению) std::vector<double>. (Тот факт, что контейнер и содержащийся в нем объект похожи, не имеет значения. Если вам нужна куча BLOB-объектов или виджетов, вы говорите std::vector<Blob> или std::vector<Widget>. Поскольку вам нужна куча vector<double> с , вы говорите vector<vector<double> >.) Таким образом, вы объявите это так:

std::vector<std::vector<double > > myPile;

(Обратите внимание на пробел между > и >. Этот пробел требуется в предыдущем стандарте C ++.)

Вы строите этот вектор так же, как и свой vector<double> - либо с использованием универсальных алгоритмов, либо вызывая push_back, либо другим способом. Итак, ваш код будет выглядеть так:

void function( /* args */ ) {
    std::vector<std::vector<double> > myPile;
    while( /* some condition */ ) {
        std::vector<double> oneLineOfData;
        /* code to read in one vector */
        myPile.push_back(oneLineOfData);
    }
}

Таким образом, вы собираете все входящие данные в одну структуру, myPile.

Что касается второго вопроса, как вернуть данные. Ну, это просто - используйте оператор return.

std::vector<std::vector<double> > function( /* args */ ) {
    std::vector<std::vector<double> > myPile;
    /* All of the useful code goes here*/
    return myPile;
}

Конечно, вы также можете вернуть информацию через переданную ссылку на ваш вектор:

void function( /* args */, std::vector<std::vector<double> >& myPile)
{
    /* code goes here. including: */
    myPile.push_back(oneLineOfData);
}

Или через переданный указатель на ваш вектор:

void function( /* args */, std::vector<std::vector<double> >* myPile)
{
    /* code goes here. */
    myPile->push_back(oneLineOfData);
}

В обоих случаях вызывающая сторона должна создать вектор-вектор-двойник перед вызовом вашей функции. Предпочитаю первый (return) способ, но если ваш дизайн программы диктует, вы можете использовать другие способы.

1 голос
/ 22 сентября 2011

Как уже упоминалось, вы можете просто использовать вектор векторов.

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

Что касается информации о количестве векторов, вы можете использовать ее, изменяя размер глобального вектора до соответствующего значения.

...