Reading Polynomial From File in C++? - c++

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.

Related

Problem in writing Goldbach conjecture program

I'm just learning programming and my task was to writce a code in C++ that for given even number would return this number as a sum of two primes. Previously I managed to write a code checking if number is prime or not but as I tried to apply this, my program failed.
#include <iostream>
using namespace std;
int main()
{
int a,s1=0,s2=0;
cout<<"Enter any even natural number greater than 3."<<endl;
cin>>a;
for(int i=0;i<a;++i)
{
for(int k=2;k<=i;++k)
{
if(i%k!=0) s1++;
}
for(int t=2;t<=(a-i);++t)
{
if((a-i)%t!=0) s2++;
}
if(s1==i-2 && s2==a-i-2) cout<<a<<"="<<i<<"+"<<a-i<<endl;
}
return 0;
}
Only one small change needed that I can see, you need to set s1 and s2 to zero inside your loop, not just once at the beginning of main.
for(int i=0;i<a;++i)
{
s1=s2=0;
...
Now (if you feel like it) rewrite the code using a function called is_prime. This function takes one integer parameter and returns true if the integer is a prime (and false if not). Had you written such a function in the first place then you would not have made the mistake you did.
Breaking complex problems into smaller ones by writing functions is an absolutely vital skill in programming.

C++ how to check if an object is equal to any value in an array?

I am trying to create a simple game where the user inputs a number, and the computer tries to guess it. The program randomly generates a number between 1 & 100. Whenever the user says a number is too high it stores that value, and every value above that, in an array and vice versa for too low. Then I want the program to generate another random number, but if the number it generates is within the array of wrong numbers, it tries again. But I have absolutely no idea how to check if the number is present in the array. Is this possible?
Yes, this is possible. You will want to use the std::find() algorithm, the reference page for which can be found Here.
It is called as std::find(std::begin(array), std::end(array), someObject);
and returns an iterator to the first element in the range [first,last) that compares equal to someObject. If no such element is found, the function returns last element i.e. end of range.
In building your random number game I would consider whether, checking if the computers guess is out of range and then guessing again if so, is the best way to approach the problem (because it's not the best way).
Also before asking a question please try to find similar questions such as This, or This before asking a new question in order to prevent stackoverflow from becoming too cluttered
For that game you don't need an array. Look at the following program:
#include <iostream>
constexpr long long average (long long a, long long b)
{
return (a+b)>>1;
}
int main()
{
char ans;
long long start, end;
std::cin >> start >> end;
do
{
auto n=average(start,end);
std::cout << n << std::endl;
std::cin >> ans;
if(ans=='<') end=n-1;
else if(ans=='>') start=n+1;
}
while(ans!='=');
}
Think of a number in the range [start, end] and the program will guess it.
It uses binary search algorithm so it will need approximately log2(end-start+1) tries in the worst case.

Count how many "things" are being put in array from input file

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.

Override methods in C++

I was supposed to create a base class (P2D) that represents a point in two dimensions and a derivate class (P3D) that represents a point in three dimensions. In the first class I created a method this way:
virtual istream& set(istream&); //sets the values
istream& P2D::set(istream& in){
in >> x >> y;
return in;
}
In the second class, instead:
istream& set(istream&); //sets the values
istream& P3D::set(istream& in){
P2D::set(in);
in >> z;
return in;
}
In the main function i thought about putting all points (regardless of whether they are in two or three dimensions) in a vector, and then about setting all points in a while cycle somehow using the set method above.
Here is the piece of code in question:
vector<P2D*> points;
bool ans(true);
P2D* p;
while(ans){
cout << "Insert a point" << endl;
p->set();
points.push_back(p);
cout << "Do you want to insert another point? ";
cin >> ans;
}
I know this is wrong and i know why, but is there a chance to overcome that not using the dinamic memory? Am i forced to let the user choice if he wants to insert a two or a three dimension point?
This seems broken to me, as inheritance implies an 'is a' relation, and 3D point definitely is not a 2D point.
This reflects on your problem, as there is no elegant way to do it as you suggest. IMO, user has to decide whether to enter 2D or 3D point, but still it doesn't make sense to keep it as a collection of 2D points.
It all depends on what you intend to do later with points in the collection. Maybe you should have a Point type as parent of both 2D and 3D point, but it is hard to tell without bigger context.

merge sort c exception OOR UPD::output problems

While trying to make this merge-sort algorithm with recursive calls, i ended up getting an exception of std::out_of_range.
I don't know much about debugging and finding causes of errors. Below i will post the code(not full, only some parts) and a sourcefile containing the same code(full version, of course).
I will gladly listen to suggestions, even if they don't provide any help against this error, so feel free to comment this code and make jokes of me :)
https://docs.google.com/file/d/0ByVN9ccAyFY2dkVLN0ZlTWVHZG8/edit
Main func
int main()
{
vector<int> original; //input vector
input (&original); //write input to vector<int> original
divide(&original); //pass the vector
for(unsigned int i=0;i<original.size();i++)//output the results
cout<<original.at(i);
}
Input func
int input(vector<int> *inVec) //read all input until non-integer
{
int tmp;
while (cin>>tmp)
inVec->push_back(tmp);
for(unsigned int i=0;i<inVec->size();i++)
cout<<inVec->at(i)<<endl;
}
Divide
int divide(vector<int> *original)
{
int origL=original->size();
if(origL>1)
{
vector<int> first; //vectors for holding 2 halfs of "original"
vector<int> second; //
first.assign(original->begin(),original->begin()+origL/2);//1st half of "original"
second.assign(original->begin()+origL/2+1,original->end());//2nd half
divide(&first); //recursive call until "first" and
divide(&second); //"second" include only one number
merge(&first,&second,original);//merge first and second back into one vector
}
}
Merge func
int merge(vector<int> *A,vector<int> *B,vector<int> *original)
{
//clear the original vector. we will use it to store sorted results.
original->erase(original->begin(),original->end());
unsigned int i=0,j=0;
//out the smallest number from A and B into
//original[0] and so on. This makes it a
//sorting algorithm.
for(i=0;i<A->size();i++)
{
if(j<B->size())
if(A->at(i)<=B->at(j))
original->push_back(A->at(i));
else{
original->push_back(B->at(j));
i--;j++;}
}
//the ABOVE loop scans whole vector A or B.
//if there are still uncopied elements in
//the other vector, then we check for them and
//push them into original.
if(j<B->size())
for(i=j;i<B->size();i++)
original->push_back(B->at(i));
if(i<A->size())
for(j=i;j<A->size();j++)
original->push_back(A->at(j));
return EXIT_SUCCESS;
}
EDIT1:
Made the changes to MERGE, so now there are no runtime errors. However, output is not right. If someone notices what could cause the problem, please kindly tell me. Meanwhile I am going to try to find it myself.
What will happen when you run out of elements in B in the function merge? OOR. Try a test case when all the elements in B are smaller than the ones in A and only call merge to see what I mean.
Also this is c++ please use reference in preference to pointers.
There exists a bug in your merge function, you should test if either vector B or vector A is empty, or the access to the vectors will cause the exception.
Next part is incorrect:
first.assign(original->begin(),original->begin()+origL/2);
second.assign(original->begin()+origL/2+1,original->end());
F.e. when you have origL==2, first vector will be { original[0] }, and second vector will be empty. You must reimplement filler for second vector:
second.assign(original->begin()+origL/2,original->end())