So I am trying to create a function that makes a 2-dimensional array from a dat file that is opened. I am running to errors trying to compile my program though. Below is my attempt, also my dat file has 8 columns but more rows than I can count so I am trying to create a dynamically allocating array or vector. Any help is appreciated.
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <iomanip>
using namespace std;
double Comsic_Ray_Events(vector< vector<double> > cosmic_ray, vector <double> row_vector(columns));
int main()
{
return(0);
}
void Comsic_Ray_Events(vector< vector<double> > cosmic_ray, vector <double> row_vector(columns))
{
double row = 0.;
const double columns = 8.;
ifstream cosmic_ray_data;
vector< vector<double> > cosmic_ray;
vector <double> row_vector(columns);
cosmic_ray_data.open("events_comp-h4a_10.00-10000.00PeV_zen37.00.dat", ios::in);
if(cosmic_ray_data.is_open())
{
while(cosmic_ray_data.good())
{
cosmic_ray.push_back(row_vector);
for(int i = 0; i < columns; i++)
{
cosmic_ray_data >> cosmic_ray[row][i];
cout << setprecision(4) << cosmic_ray[row][i] << endl;
//row++;
}
row++;
}
}
else if(cosmic_ray_data.fail())
{
cout << "File didn't open correctly" << endl;
}
cosmic_ray_data.close();
}
Well I see some design issues in your code as well with your functions, i tried to write a very simple example with your variable names more or less, hope you understand it.
First, i don't know why you try to use a void function if you write that you'd like a function that returns you a 2-dimensional vector. Second, i don't get why your function with the double return type at the beginning has the 2 vector as parameters, if that's what you wrote you want to get from the input. I can only imagine as paramater the "filename.dat" maximum. Here's the very-very simple code to achieve what you'd like:
vector<vector<double> > Cosmic_Ray_Events()
{
ifstream cosmic_ray_data("events.dat");
vector<vector<double> > cosmic_ray;
int columns = 8;
while(cosmic_ray_data.good())
{
vector <double> row_vector;
for(int i=0; i<columns; i++)
{
double data;
cosmic_ray_data >> data;
row_vector.push_back(data);
}
cosmic_ray.push_back(row_vector);
}
cosmic_ray_data.close();
return cosmic_ray;
}
Then the way you can use it:
vector<vector<double> > cosmic_events_vector = Cosmic_Ray_Events();
Beyond that, if that's not what you'd want, then be more specific plz.
Related
I'm dealing with an algorithm homework which need to be executable on linux(I'm using wsl), and this homework need to store the solution and export to the output file.
To store the solution, I need to open an 2D array of "vectors storing pairs", and at the end, I need to sort the pairs by its first component in the ascending order.
I know that for the first requirement, the running time would be O(N^2)(This is also the standard answer for this dynamic programming problem), and for the second one, I've google C++ STL, and it says that the algorithm used by c++ only needs O(NlogN).
(1)It return 'killed' if I use the new to declare 2D array of vector, for the cases that N=10000, but it works fine if N=1000.
[Edited]
(2) I check the comment, and they suggest that I should write the code using vector to store vector instead of new. However, when I change to using vectors storing vectors, now the program cannot run, keep throwing segmentation fault.
I don't know where is happening. Can anybody help?
problem description:
https://drive.google.com/file/d/1m8ISIGlVGXH3oeyechLbBA1QQVSmsw-q/view?usp=sharing
file: https://drive.google.com/file/d/1Ci8MXUsX65oVOxKCD1u3YcWiXsKNYToc/view?usp=sharing
Note:
The .o files are alredy make, finish editing, you need to 'make', and run
./bin/mps [inputfile] [outputfile]
I've modified some code, but it can only run with case N=12, 1000; not for larger N.
chord.h:
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
class Chord {
public:
Chord(int);
~Chord();
void setEndPoint(int, int);
int getMaximumChords();
void print();
int size;
int* data; //stores the endpoints of the chord
// vector<pair<int,int>>** sol;
//I recently use this(1), works for N=1000, but killed if N larger
vector< vector< vector<pair<int, int>> >>sol;
//suggest to change to this(2), not working even for N=12,
//return segmentation fault
int getEndPoint(int);
};
chord.cpp:
#include "chord.h"
#include <iostream>
Chord::Chord(int tmp){ //initialize all elements 0
size = tmp;
data = new int [size];
};
Chord::~Chord(){
delete[] data;
}
void Chord::setEndPoint(int a, int b){
data[a] = b;
data[b] = a;
return;
}
void Chord::print(){
for(int i=0;i<size; i++){
cout << data[i] << endl;
}
return;
}
int Chord::getEndPoint(int a){
return data[a];
}
int Chord::getMaximumChords(){
for(int j=1; j<size; j++){
for(int i=j-1; i>=0; i--){
int k = getEndPoint(j);
if(k==i){ //case 1: ij is the chord
sol[i][j] = sol[i+1][j-1]; //make a copy
sol[i][j].reserve(1);
sol[i][j].push_back(make_pair(i,j));
}else if(k<i || k>j){ //case 2: k outside interval[i,j]
sol[i][j] = sol[i][j-1];
}else{ //case 3: k inside interval[i,j]
if (sol[i][j-1].size() > sol[i][k-1].size() + sol[k+1][j-1].size() + 1){
sol[i][j] = sol[i][j-1];
}else{
sol[i][j] = sol[i][k-1];
sol[i][j].reserve(sol[k+1][j-1].size()+1);
sol[i][j].push_back(make_pair(k,j));
sol[i][j].insert(sol[i][j].end(),sol[k+1][j-1].begin(), sol[k+1][j-1].end());
}
}
}
}
sort(sol[0][size-1].begin(), sol[0][size-1].end());
return sol[0][size-1].size();
}
main.cpp
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include "chord.h"
using namespace std;
int main(int argc, char* argv[]){
if (argc < 3){
printf("Please enter output file name!");
return 0;
}
//import input
fstream fi(argv[1]);
fstream fo;
fo.open(argv[2], ios::out);
int N=0, a=0, b=0;
char buffer[200];
fi >> N;
Chord chord(N);
while(fi>> a >>b){
chord.setEndPoint(a,b);
}
//chord.print();
int ans= chord.getMaximumChords();
//export output
fo << ans <<endl;
for(int i=0; i<chord.sol[0][chord.size-1].size(); i++){
fo << chord.sol[0][chord.size-1][i].first << " " << chord.sol[0][chord.size-1][i].second << endl;
}
fi.close();
fo.close();
return 0;
}
By default, std::vector is constructed with 0 size, and I see that you don't ever resize the vector, but you access its elements by index [i][j]. You have to resize first two (or maybe three) dimensions of 3-dimensional vector sol to fit necessary size, do following resize inside constructor:
Chord::Chord(int tmp){ //initialize all elements 0
size = tmp;
data = new int [size];
sol.resize(size, vector< vector<pair<int, int>> >(size));
};
After this resize change in constructor your program doesn't crash on 10000 input, at least on my Windows laptop.
Also maybe you need to resize two dimensions to bigger than size, you should know better. Also 3rd dimension might be needed to resize too, if you need this by algorithm, up to you. If you need to resize 3rd dimension, then do following (but if I understand your algorithm correctly you don't need this change, resizing 3rd dimension, you need it to be of size 0):
sol.resize(size1, vector< vector<pair<int, int>> >(size2, vector<pair<int, int>>(size3)));
(here size1/size2/size3 are three sizes of three dimensions, so that your vector gets 3-dimensional shape (size1, size2, size3), decide what these 3 sizes should be at your algorithm start, I think they should be (size, size, 0))
I was looking at the implementation of Prim's Algorithim on geeksforgeeks.org and tried to implement the function on practice mode. I looked at how the input was received and I saw this:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1e4 + 5;
int spanningTree(vector <pair<int,int> > g[], int n);
int main()
{
int t ;
cin>>t;
while(t--)
{
vector <pair<int,int> > adj[MAX];
int n,e;
int w, mC;
cin >> n>> e;
for(int i = 0;i < e;++i)
{
int x,y;
cin >> x >> y >> w;
adj[x].push_back({w, y});
adj[y].push_back({w, x});
}
mC= spanningTree(adj, MAX);
cout << mC << endl;
}
return 0;
}
I'm having a lot of trouble understanding how they're using vector. I've never seen the passing of a vector in a similar way to an array: vector <pair<int,int> > g[].
I looked at the STD implementation of vector and couldn't find anything about passing a vector this way, or constructing a vector with vector <pair<int,int> > adj[MAX];.
Lastly, I am very confused about what the following code does:
adj[x].push_back({w, y});
adj[y].push_back({w, x});
I tried implementing it myself:
#include <iostream>
#include <vector>
#include <utility>
#include <string>
using namespace std;
int main()
{
vector< pair<string, int> > vec[2];
vec[0].push_back({"One", 1});
vec[1].push_back({"Two", 2});
for(int x = 0; x < 2; ++x){
cout << vec[x].first << ", " << vec[x].second << endl;
}
return 0;
}
But I get an error class 'std::vector< pair<string, int> >' has no member named ‘first’.
If I could have some help understanding how vector is being used here, I would really appreciate it. I looked at multiple StackOverflow posts already, including vector::push_back vs vector::operator[].
The link to the original problem is here
I've never seen the passing of a vector in a similar way to an array: vector <pair<int,int> > g[]
It is an array! An array of vectors.
The problem with your code is that you have two vectors, both with a single element, and your loop only pulls out the vectors... not their single element.
Your version would be:
#include <iostream>
#include <vector>
#include <utility>
#include <string>
using namespace std;
int main()
{
vector< pair<string, int> > vec[2];
vec[0].push_back({"One", 1});
vec[1].push_back({"Two", 2});
for(int x = 0; x < 2; ++x){
cout << vec[x][0].first << ", " << vec[x][0].second << endl;
}
return 0;
}
All I added was [0] (index into each vector).
Of course such an example is of questionable practicality. In such a situation it would seem that you want one vector with two elements, and no arrays in sight.
To be honest, I'm not wild about the original code, either. Mixing arrays and vectors is a recipe for confusion (hyello); they could have used "2D vectors" or, better, a 1D vector with 2D indexes laid on top of it. That would then have much better cache locality as well.
Its' a C-style array of vectors, really nothing magic here.
int spanningTree(vector <pair<int,int> > g[], int n);
Maybe you have seen something like that before:
int foo( int array[], int n);
In their code, the elements of the array are not ints but std::vectors. Why they mix plain arrays and std::vector I cannot tell you.
In your example, you need to first use operator[] to access an element before you can access its .first and .second, or use front to get the first element:
for(int x = 0; x < 2; ++x){
cout << vec[x].front().first << ", " << vec[x].front().second << endl;
}
I am a new in C++ and have difficulties in importing specific data (numbers) from the file.
My input looks like:
Open High Low Close
1.11476 1.11709 1.10426 1.10533
1.10532 1.11212 1.10321 1.10836
1.10834 1.11177 1.10649 1.11139
1.09946 1.10955 1.09691 1.10556
1.10757 1.11254 1.09914 1.10361
1.10359 1.12162 1.10301 1.11595
1.09995 1.10851 1.09652 1.10097
I use the following code which works fine for me to read the second column entirely, however I need to read specific data only. For example the third row/ third column which is 1.10649How can I read specific data? Do I need to use the string to get the row/column and then convert it to int in order to read it in a vector? I am open for any suggestions and would be greatly appreciated if any could help me with this issue.
// Data import 2nd Column
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
using namespace std;
int main()
{
const int columns = 4;
vector< vector <double> > data;
ifstream market_data("market_data.txt");
if (market_data.is_open()) {
double num;
vector <double> line;
while (market_data >> num) {
line.push_back(num);
if (line.size() == columns) {
data.push_back(line);
line.clear();
}
}
}
vector <double> column;
double col = 2;
for (double i = 0; i < data.size(); ++i) {
column.push_back(data[i][col - 1]);
cout << column[i] << endl;
}
system ("pause");
return 0;
}
You need to use a integer value for indexing (size_t to be precise), change
for (double i = 0; i < data.size(); ++i) {
to
for( size_t i = 0; i < data.size(); ++i) {
// ^^^^^^
Otherwise everything seems fine from your code sample.
If your numbers will always contain 7 characters (i assume it's not binary file), then you could make this simple.
Use seekg() method of ifstream.
Each number fills 10 characters (7 of number, 3 spaces). So, if you have table ROWS x COLUMNS, then to get specific number, you can do this:
const int ROW_LEN = 4
const int DATA_LEN = 10
...
int row,column;
double num;
std::cin >> row; //assume first row is 0
std::cin >> column //assume first column is 0
marked_data.seekg((column*ROW_LEN + row)*DATA_LEN);
marked_data >> num // here is your number
Thank you for replies.. I have solved the issue. So instead of:
vector <double> column;
double col = 2;
for (double i = 0; i < data.size(); ++i) {
column.push_back(data[i][col - 1]);
cout << column[i] << endl;
}
enough to write:
cout << data[2][2] << endl;
I'm trying to create a bunch of vectors in c++, each having a different name. I've looked around on this site, and have not found any information that is 'simple', as I'm very new to c++. I would like to do it without importing libraries i've never used before.
For example:
#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
int n = 2;
int m = 4;
double size = pow(m,n);
for (int i=0; i<n; ++i)
{
vector<double> xi(size);
// where xi would vary with the iteration through n
// i.e. I would have vectors x1, x2 in the case of n=2
}
return 0;
}
This isn't the simple case were I could create x1, and x2 by themselves at the start, because I won't know what 'n' will be, as it will be inputted by the user at the start of the program. What would be the easiest way of doing this?
Use a vector of vectors.
std::vector<std::vector<double>> xArray;
for (int i=0; i<n; ++i)
{
vector<double> xi(size);
// Fill up xi
// ...
xArray.push_back(xi);
}
You can't do what you're asking in C++. However, you can store your created vectors in another vector of vectors and thus, you can refer to them via their index in the vector of vectors that contains them:
std::vector<std::vector<double>> myvecs;
for(int i(0); i < n; ++i) {
std::vector<double> xi(size);
//...
myvecs.push_back(xi);
}
Depending on what you are trying to do it might make sense to use something like a std::map<std::string, std::vector<int>>.
You could do this:
std::map<std::string, std::vector<int>> myMap;
for (int i=0; i<n; ++i) {
vector<double> xi(size);
string name;
// Make a name with stringstream ...
myMap[name] = xi;
}
Then if need be you could search for the vector using `name, eg:
cout << "Name of your vector: "
cin << name;
cout << "Here is your vector"
std::vector<int> &myVect = myMap[name];
// Do some printing.
I am supossed to do a code using function which after asking the user for input,puts number before the vector like this:
if vector is 11,12,13,14
new vector is 1 11 2 12 3 13 4 14 until the vector finishes and then I have to print it but I get an error of vector subscript out of range,aprecciate any help.
Here is my code
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<double> llena_vector(int x,vector<double> ingreso)
{
cout<<"Ingrese numeros: ";
while(cin>>x);
ingreso.push_back(x);
return ingreso;
}
vector<double> arma_vector(int contador,vector<double> intercalado)
{
int i=0;
for(contador=1;contador< intercalado.size()+1;contador++);{
intercalado.insert(intercalado.begin()+i,contador);i++;}
return intercalado;
}
vector<double> imprime_vector(int cuenta,vector<double> imprimir)
{
for(cuenta=0;cuenta<imprimir.size();cuenta++);
cout<<imprimir[cuenta]<<" ";
return imprimir;
}
int main()
{
int y=0;
int q=0;
int w=0;
int f=0;
vector<double> usuario;
vector<double> guardar;
vector<double> resultado;
vector<double> print;
guardar= llena_vector(y,usuario);
resultado=arma_vector(q,guardar);
print=imprime_vector(w,resultado);
system("pause");
}
Here is a cleaner version of the code, in working condition.
#include <iostream>
#include <vector>
using namespace std;
void fill_vector(vector<double>& v)
{
cout << "Enter 5 numbers." << endl;
for (int i = 0; i < 5; ++i)
{
double d;
cin >> d;
v.push_back(d);
}
}
void insert_count(vector<double>& v)
{
size_t size = v.size();
for (size_t i = 0, j = 0; i < size; ++i, j += 2)
{
vector<double>::iterator pos = v.begin() + j;
v.insert(pos, i + 1);
}
}
void print_vector(vector<double>& v)
{
for (size_t i = 0; i < v.size(); ++i)
cout << v[i] << " ";
cout << endl;
}
int main()
{
vector<double> v;
fill_vector(v);
insert_count(v);
print_vector(v);
}
Like others (may have) pointed out:
you didn't need to pass by value (you're basically passing around a bunch of copies), you can pass by reference instead to reduce overhead and speed it up
you shouldn't put semicolons (;) directly behind your loop statements
size_t is often better than int when looping on size
you included <string> when it wasn't being used
you were passing arguments that weren't needed (e.g. a counter)
you used a while loop for user input, but it's only appropriate when piping in data otherwise it will loop forever; a for loop with a known count is more appropriate for user input
the function that inserted numbers between the existing elements had an error, you were incorrectly calculating the position to insert
your code formatting was a mess, making the code very difficult to read
you shouldn't pollute the namespace (i.e. using namespace std), but I left it as is since it's common in example code
if you're using C++11, I recommend using a for-each loop for printing the vector, and the auto keyword when declaring the iterator
i guess there is a typo: you should remove the last ; in for(cuenta=0;cuenta<imprimir.size();cuenta++);
Edit: as pointed by jrd1, you have this typo in all your for and while loops...
To begin with, your code has a number of issues. But, I've modified it to keep it as similar to your original.
#include <iostream>
#include <string>
#include <deque>
#include <cstdlib>
using namespace std;
deque<double> llena_deque(int x, deque<double> ingreso)
{
cout<<"Ingrese numeros: ";
while(cin>>x)
ingreso.push_back(x);
return ingreso;
}
deque<double> arma_deque(int contador, deque<double> intercalado)
{
int size = intercalado.size()+1;
for(int i=1; i < size; ++i) {
cout << i << endl;
intercalado.push_front(i);
}
return intercalado;
}
deque<double> imprime_deque(int cuenta, deque<double> imprimir)
{
for(cuenta=0;cuenta<imprimir.size();cuenta++)
cout << imprimir[cuenta] << " ";
return imprimir;
}
int main()
{
int y=0;
int q=0;
int w=0;
int f=0;
deque<double> usuario;
deque<double> guardar;
deque<double> resultado;
deque<double> print;
guardar= llena_deque(y,usuario);
resultado=arma_deque(q,guardar);
print=imprime_deque(w,resultado);
return 0;
}
All your loops had ; at the end of them. That's one reason why you're getting your errors, as the semi-colon terminates a statement - hence, your loops were never truly accessing the vectors, which is why you were getting the memory access violations.
You're passing all your memory by value (which could potentially be slow). Consider using references.
Your operations suggest that you constantly need to keep pushing new data in front of your vector. If so, then use deque (as I did) as it is has functionality designed explicitly for that purpose (insert operations at both ends).
Although, I will say that the logic of your code is quite puzzling at times: i.e. in arma_vector, why pass the value of contador if you don't even use it? You could have used i instead...