This is the beginnings of a program that will read the numbers in an input file and put them into an array, and then sort them ascending and print them into an output file.
I am having trouble with the function that records how many numbers there are in the input file (I am trying to do this while putting the numbers in the array).
Here is the code of the function. There are no errors. Whenever I run the program it prints the amount of numbers in the input as 0.
int store (int arg[], int numsize, istream& infile)
{
while (infile >> arg[ //i dont know what to put here// ]) {
numsize++;
}
return numsize;
}
There are several problems with your code:
In order to put anything in the square brackets, you need to be sure that arg has enough space for it
However, you cannot be sure of that, because you have no idea how many items will be entered
Taking numsize as a parameter is useless, because you can't modify it anyway.
This code ignores C++ Standard Library containers in favor of C-style arrays.
Fortunately, all of this can be fixed with switching your container from C-style arrays to std::vector<int>:
std::vector<int> arg;
Now the entire read operation could then be finished in a single line of code:
std::copy(
std::istream_iterator<int>(infile),
std::istream_iterator<int>(),
std::back_inserter(arg)
);
You do not need to count elements in your code, because arg.size() provides you with access to the number of elements that have been read.
Related
I am trying to read two polynomials from a text file in my c++ program and i have written the following code, my issue is that its only reading the first one and the second one is coming out as all zeroes?
Also im thinking its probably because idk how to stop reading the first poly because apparently you cannot write:
while(f!='=')
anyways heres the code:
....
int main()
{
poly *p1,*p2;
p1=NULL;
p2=NULL;
fstream f; //error: only reading first polynomial
f.open("input1.txt");
// string x1="4X7-2X6-1X3+4X2+3X0=0"; //these are the polynomials im trying to read
// string x2="2X6+3X2-2X0=0";
int c,e;
char b;
int x,i=0;
cout<<"Number of terms of poly 1: ";
cin>>x;
while(i<x)
{
f>>c>>b>>e;
cout<<c<<b<<e;
p1=p1->create(p1,c,b,e);
i++;
}
p1->display(p1);
cout<<"\nNumber of terms of poly 2: ";
cin>>x;
i=0;
while(i<x)
{
f<<endl;
f>>c>>b>>e;
cout<<c<<b<<e;
p2=p2->create(p2,c,b,e);
i++;
}
p1->display(p2);
poly *p3;
cout<<"\nThe addition of polynomials is:";
p3=p3->polyaddition(p1,p2);
p3->display(p3);
}
i wanted to read the polynomials without asking the number of elements on console. Any help would be appreciated. Thanks!
Most important thing to do: Write a function which reads just one monomial component - the next one on the input. Then invoke it repeatedly until you get to the end of the line.
Of course, before implementing the function, take the time to carefully consider what the signature of that function needs to be; and how a polynomial should be represented, when you don't know its degree in advance.
Notes:
You absolutely must take care to check for errors, like #user4581301 suggests - so that you don't end up in an infinite loop if the reading fails, or if you hit the end of the line in the middle of a supposed monomial etc.
Using this function, you'll get the added bonus of avoiding some of the code duplication you have now in reading the two polynomials. To avoid all of it, write a second function which reads an entire single polynomial.
I have 2 structs, one simply has 2 values:
struct combo {
int output;
int input;
};
And another that sorts the input element based on the index of the output element:
struct organize {
bool operator()(combo const &a, combo const &b)
{
return a.input < b.input;
}
};
Using this:
sort(myVector.begin(), myVector.end(), organize());
What I'm trying to do with this, is iterate through the input varlable, and check if each element is equal to another input 'in'.
If it is equal, I want to insert the value at the same index it was found to be equal at for input, but from output into another temp vector.
I originally went with a more simple solution (when I wasn't using a structs and simply had 2 vectors, one input and one output) and had this in a function called copy:
for(int i = 0; i < input.size(); ++i){
if(input == in){
temp.push_back(output[i]);
}
}
Now this code did work exactly how I needed it, the only issue is it is simply too slow. It can handle 10 integer inputs, or 100 inputs but around 1000 it begins to slow down taking an extra 5 seconds or so, then at 10,000 it takes minutes, and you can forget about 100,000 or 1,000,000+ inputs.
So, I asked how to speed it up on here (just the function iterator) and somebody suggested sorting the input vector which I did, implemented their suggestion of using upper/lower bound, changing my iterator to this:
std::vector<int>::iterator it = input.begin();
auto lowerIt = std::lower_bound(input.begin(), input.end(), in);
auto upperIt = std::upper_bound(input.begin(), input.end(), in);
for (auto it = lowerIt; it != upperIt; ++it)
{
temp.push_back(output[it - input.begin()]);
}
And it worked, it made it much faster, I still would like it to be able to handle 1,000,000+ inputs in seconds but I'm not sure how to do that yet.
I then realized that I can't have the input vector sorted, what if the inputs are something like:
input.push_back(10);
input.push_back(-1);
output.push_back(1);
output.push_back(2);
Well then we have 10 in input corresponding to 1 in output, and -1 corresponding to 2. Obviously 10 doesn't come before -1 so sorting it smallest to largest doesn't really work here.
So I found a way to sort the input based on the output. So no matter how you organize input, the indexes match each other based on what order they were added.
My issue is, I have no clue how to iterate through just input with the same upper/lower bound iterator above. I can't seem to call upon just the input variable of myVector, I've tried something like:
std::vector<combo>::iterator it = myVector.input.begin();
But I get an error saying there is no member 'input'.
How can I iterate through just input so I can apply the upper/lower bound iterator to this new way with the structs?
Also I explained everything so everyone could get the best idea of what I have and what I'm trying to do, also maybe somebody could point me in a completely different direction that is fast enough to handle those millions of inputs. Keep in mind I'd prefer to stick with vectors because not doing so would involve me changing 2 other files to work with things that aren't vectors or lists.
Thank you!
I think that if you sort it in smallest to largest (x is an integer after all) that you should be able to use std::adjacent_find to find duplicates in the array, and process them properly. For the performance issues, you might consider using reserve to preallocate space for your large vector, so that your push back operations don't have to reallocate memory as often.
TL;DR: Help me pass vector array input into a function that originally took in int pointers and ints.
I am in a college class that is learning about well-known algorithms. In this class, we use C++ to code the given algorithms. There was no pre-req class to learn C++, so my knowledge is pretty low when it comes to some of the major stuff with programming.
My problem: I have to create a program that takes an input file, sorts it with the user's choice of sorting algorithm, and write the results to an output file. My original code that works perfectly uses an input file of 20 items, placed into an array of length 20, and sorts no problem with each individual sorting algorithm.
Since last night, the only thing I have changed is that my input goes to a vector array, since the teacher will give us files of varying length (10 items to 1,000,000 items). I have four sorting algorithms that need to sort these given input files. Only one of them works, and it does not pass any variables into the function.
The other 3 originally passed in array pointers and other variables, however they do not work with my new input now going to a vector array instead of an int array. I know that what I am passing in needs to be changed, but I have no idea how to do this correctly. I have tried many different ways from sources found on the internet (with pointers and references), but I have had no luck. Here is some snipets of the code I'm using.
vector<int> A;
void insertionSort() // This works no problem as is.
void split(int* A, int* B, int low, int high) //code for Merge-Sort
{
//recurisvely calls split() and splitMerge()
}
void splitMerge(int* A, int* B, int low, int mid, int high) // more code for Merge-Sort
{
// more code for Merge-Sort
}
//quickSort() and countSort() also pass ints and do not work either.
//small part of main()
for (i = 0; unsorted >> temp; i++)
{
A.push_back(temp);
cout << A[i] << "\n";
length++; //I use int length extensively in for-loops in my functions
}
Last thing. I do not get an error when trying to run the Merge-Sort. It just freezes my console window.
conversion from vector to array is done this way
vector vInts;
...fill the vector
int * intArr=vInts[0]
so you don't need to modify your code too much
I believe there is not enough code to make an accurate prediction on where the error may be, but I think the problem is that the sorting algorithms is doing something like A++ with you pointers to access the next member.
Because arrays store the pointer to the next array inside the object and not on adjacent cells of memory, your algorithms are cycling through stuff they shouldn't.
If this is the case, the solution to your problem is to use an iterator instead of a pointer.
void split(A.begin(), B.begin(), int low, int high)
My program is supposed to read numerical data (in pairs) from a text file, remove the duplicates and then tell me the size of the vector before moving on to other things. I tested the code below and it works with files that have about 10-20 lines of data, however when I try it on larger data sets (over 100,000 lines of numerical data), there is no output when I try to cout the size(); of the vector. Not sure what the problem is.
while( getline( fs1, instrng ) ) {
istringstream s1(instrng);
int a, b;
s1 >> a >> b;
pair<int,int> pair1 = make_pair(a,b);
vec1.push_back( pair1 );
sort( vec1.begin(), myvec1.end() );
myvec.erase(unique(myvec.begin(),myvec.end()), myvec.end());
In your context the use of std::sort() and std::unique() is working. The problem is a performance issue. You need to do one of two things:
You wait long enough to give the implementation a chance to do a lot of sorting.
You move the use of std::sort(), std::unique(), and std::vector<...>::erase() out of the loop.
Put differently: you managed to create a O(n * n * log n) implementation for something which should be O(n * log n) where n is the number of elements.
BTW, you should always verify that input was successful: you failed to check that reading the two integers on the line was successful. Personally, I would just read the integers from the original stream and not use std::istringstream as creation and/or set up of these streams is also adding unnecessary costs. This cost is, admittedly, a lot less than sorting for each element.
I'm attempting to create a program that takes a large number of stock prices. I have these prices stored in a .txt file with one double per row. There are an unknown number (probably thousands). I cannot get the data into an array which I can manipulate. I've been unable to solve this problem for a couple hours now. Whenever I attempt to read the data out of the file and then convert it to a double, I get weird thread errors and the program hangs. Can anyone show me how to read an unknown amount of doubles into an array.
string line;
vector<double> doubles;
fstream myfile ("/Users/jaychinnaswamy/Documents/PMHistory.txt",std::ios_base::in);
int x=0;
float a;
while (myfile >> a)
{
doubles[x]=a;
}
An example of the file structure is:
50.4000000000000
50.8000000000000
50.5000000000000
50.2100000000000
49.1500000000000
48.5000000000000
Thanks
You have created an empty vector here.
vector<double> doubles;
And here, you are indexing into the vector, as if it's not empty. It's still empty and you are accessing an invalid element.
doubles[x]=a;
Change that code to use std::vector::push_back().
doubles.push_back(a);
Two things obvious from the code I see (already mentioned in comments):
You don't increment x.
Even w/o increment, you access doubles[x] with x==0 when doubles has no elements. That's undefined behavior. You need to allocate elements ahead of time or use push_back to grow vector as needed.
The code you have submitted has a few issues. As stated by others, you have instantiated an empty std::vector and your code does assignments onto an index that does not exist. Since your problem revolves around an unknown amount of elements (dynamic size), use the push_back method of std::vector. I would advise you not convert from float to double through a. You know the data is a double and you want to store it as a double, so use double. Since this is just a piece of your code, you can utilize a for loop to make double a scope bound to the loading of the data.
Your code can be rewritten into:
std::ifstream myfile("/Users/jaychinnaswamy/Documents/PMHistory.txt");
std::vector<double> doubles;
for (double a; myfile >> a;) {
doubles.push_back(a);
}
However, if you don't require data verification, you know the file contains only doubles, and you really just want to import the numbers, then use the range constructor for std::vector to read the file for you via std::istream_iterator.
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
int main() {
std::ifstream myfile("/Users/jaychinnaswamy/Documents/PMHistory.txt");
std::vector<double> doubles{(std::istream_iterator<double>(myfile)),
std::istream_iterator<double>()};
}
Pay special attention to the () around the first iterator argument of the std::vector range constructor. Without the () will result in syntactic ambiguity, also known as the "most vexing parse".