StuXYZ 731 Practically a Master Poster

The obvious approach most Vector3D classes use it to represent the data in one form and convert from input in another form into it (e.g. leave the vector in cartesian for and convert from spherical and cylindrical input). Depending on the problem that is a viable solution [not always].

Then it is a matter of doing one thing at a time. I would actually recommend writing the output first, that greatly helps with debugging, so you have a class like this:

class Vector3D
{
  private:
    
    double x,y,z;    // This can be done in many ways,but I have chosen discrete 
                     // values. [you can use an array, etc]
  public:

    Vector3D();         // Default constructor [e.g. set x,y,z to zero]
    Vector3D(const Vector3D&);      // ALWAYS write a copy constructor
    Vector3D& operator=(const Vector3D&);    // ALWAYS write an assignment operator
    ~Vector3D()  {}            // Destructor 

    void write(std::ostream&) const;        // Write should be constant 
};

// This is implemented in the standard way
std::ostream& operator<<(std::ostream& OutStream,const Vector3D& A)
{
   A.write(OutStream);
   return OutStream;
}

Then all you have to write is a simple write method and the constructors/copy constructors and you can star doing stuff with your class. Initially, the vector 0,0,0 is a bit boring, so you start to increase the scope, e.g. an constructor that takes three values, test that and build up the class.

After a bit you add this:

class Vector3D
{
  // stuff....
public:
  // stuff...
  Vector3D& operator+=(const Vector3D&);
  Vector3D operator+(const Vector3D&,const Vector3D&) const;

// then to multiply by a …
StuXYZ 731 Practically a Master Poster

The array is the problem. The polynomials are going to change size on every operation.The effect of that is you have to have something fluid. Just use a vector to sort the terms. That way if you add another polynomial, then you see if you have the term in the first polynomial, if so add the coefficients, but if you don't just append that term to the end of your list/vector.

Basically, the pseudo code of addition is this:

Add poly A to B:

for each term T in B:
  
   if (A contains exponent of T):
      add coefficients
   else:
     append T to A

// After loop:
Sort A [helps in the first test in the loop/pretty write out]
Remove zeros.

After you have a pseudo code for the algorithm you intend to use, then you can figure out what sort of data/structures you need. If you use arrays, I think they will be a complete mess.

StuXYZ 731 Practically a Master Poster

The issue isn't really the coefficient value that you have with the polynomial, it is that you have to realize, that the size of your polynomial will change dramatically, on addition, subtraction etc. Once you have figured out how to handle that, [in particular to remove zeros e.g. (x^2+3x) + (3x^4-3x) should give (3x^4+x^2).]

Note that in doing this you are going to benefit by writing a tidy output method, that keeps the polynomial in the typical form that you expect to see. I would actually do that first, since it really will help debugging.

Next tackle addition, and add in the methods that are going to make life easier, e.g. a sort of the powers, a zero remover, and an evaluation tool (e.g what is the value of the polynomial if x=5. Again this is useful for rapid testing/checking.

Finally, you obviously know about std::vector, so either use a list / vector for the polynomial terms, and don't bother with the max coefficient part [your maxTerm]. The polynomial will change as required. Then it is easy.

StuXYZ 731 Practically a Master Poster

Sorry to say, it is the usual problems.

Basically, if you get a problem like this put some std::cout statements in the inner loops that are doing stuff. .e.g in reverseArray.

You would find: for(count=5;count = 0; count--) is wrong since I think you intended to write for(count=5;count != 0; count--) .

Note: That error would have been a warning from your compiler if you turn on the warnings.

You have another error, that is a bit more subtle, that is you have an array of size items, BUT you set count = 5. That means you have a bug waiting to happen. Next, you then use score[count] . Note that score is an array from score[0] to score[4]. Try something like score[count-1] Finally, please remember to delete the memory you allocate in reverseArray.

StuXYZ 731 Practically a Master Poster

The error is close to the worst kind because (a) it is at run-time [it is always easier to fix compile-time]. (b) it is random, you can run the program one time, and get a different answer next time -- and you have changed NOTHING.

Ok so what is happening, in simple form you have this:

int index;
for(int i=0;i<10;i++)
   if (i==11)
     index=20;
std::cout<<Index == "<<index<<std::endl;

Can you see that index is not set to anything. there is no initializer. It has no value. You could get round that by writing int index(10); then index would always be 10 in the above code.

Now, maybe the question, is why is it that the condition I set in my findCoord is not met. For the first case, consider a point at the left edge of the maze, then it cannot have a point to the left, hence you cannot satisfy the condition maze[i].getCoordX() == xarg && maze[i].getCoordY() == yarg since you are calling it with (effectivley) xarg = maze[i].getCoordX()-1; I notice a number of annoying errors [NOT ALL ERRORS!!!!]:

(a) your copy constructor doesn't copy everything, but that isn't your main problem.
(b) getNorth and getSouth test on y!=maxY and y!=0 which are the wrong way round.
(c) same problem with 2south /2north.


However, I really think you are going to have to add some error code. But before you do please tidy up the program, because as you add complexity, it …

StuXYZ 731 Practically a Master Poster

First off before you actually code this, you need to think about the maths that is involved. Let us consider it. Using "pen and paper" first, is often the quickest way to write a computer program (and it also gives you all the test cases quickly).

Consider the cat is at a point A, (Ax,Ay) and the Dog is at B, (Bx,By) and there is
one and only one tree at T(Tx,Ty). Additionally, the Dog is V times faster than the cat (note, that V could be 1.0 if they are evenly matched or it could be 0.5 if the dog is getting too old for this sort of thing).

That is the simplest problem. If you can solve this, then it is easy to do the other case, just test to see if the cat wins for the first tree, and then for the next.

The only part of the problem you haven't given us is the Dog strategy, I assume that the Dog is smart and (a) runs towards the "optimal" tree, (b) does not in doing so create an escape path for the cat to another tree.

Then the algorithm is simply the dog wins if

length_of(T-B) / V    <   length_of(T-A)

So you need to code several pieces of information,

(i) to subtract two points
(ii) calculate the length of a vector (use Pythagoras / dot product etc)
(iii) test the condition.
(iv) Encapsulate it in a loop for each …
StuXYZ 731 Practically a Master Poster

Have you actually fixed the problem of uninitialized values, I ran you program with
these two findCoord, and prints "ERROR HERE" in both cases and exits.

int findCoord(std::vector<MazeCoord> &maze, MazeCoord &coord)
{
    for (unsigned int i = 0; i < maze.size(); i++) 
      {
        if (maze[i].getCoordX() == coord.getCoordX() &&
            maze[i].getCoordY() == coord.getCoordY()) {
	  return i;
        }
    }
    std::cout<<"ERROR HERE:findCoord(V,M)"<<std::endl;
    exit(1);
}
// AND 
int 
findCoord(std::vector<MazeCoord> &maze, int xarg, int yarg)
{
  for (unsigned int i = 0; i < maze.size(); i++) 
      if (maze[i].getCoordX() == xarg && maze[i].getCoordY() == yarg) {
	return i;

  std::cerr<<"ERROR HERE in findCoord(V,x,y)"<<std::endl;
  exit(1);
}

Now what have you changed so that the program never reaches either of the exits, because under the original program, in both cases you will have a completely random value returned, maybe within range, maybe not, but definitely unpredictable and may change as you run the program.

StuXYZ 731 Practically a Master Poster

First of all, welcome to Daniweb. Thank-you for writing a coherent, well constructed post, with code tags.

Your problem in this code [which actually causes the core dump] is that both of the findCoord functions can return an undefined number.

Consider your code:

int 
findCoord(std::vector<MazeCoord> &maze, int xarg, int yarg)
{
  int index;   // Uninitialized value
  for (unsigned int i = 0; i < maze.size(); i++) 
    {
      if (maze[i].getCoordX() == xarg && maze[i].getCoordY() == yarg) {
	index = i;
	break;
      }
    }
  // What happens if there was no break????
  return index;
}

As you can see if the condition is not met then you get an uninitialized value on return and that is going to cause problems.

So first decide how likely it is to be like this, e.g. is it always indicative that something terribly wrong has happened elsewhere, e.g. then throw an exception, or it is just run of the mill stuff, then return an error code, e.g. -1.

Let us do the latter, and tidy things up a bit.

int 
findCoord(std::vector<MazeCoord>& maze,const int xarg,const int yarg)
{
  for (unsigned int i = 0; i < maze.size(); i++) 
    if (maze[i].getCoordX() == xarg && maze[i].getCoordY() == yarg) 
      return i;
    
  // no value found:
  return -1;
}

Obviously, you have to change the other findCoord, and you have to start dealing with the error codes, and change your algorithm a bit. Obviously, if you get stuck doing that, please feel free to post …

StuXYZ 731 Practically a Master Poster

It is not strange that it runs, however, the problem is that exitMinutes is uninitialized.

That means that when the value in exitMinutes is read, it could be ANYTHING. To see how that came about, consider your program.

In the main program you write int exitMinutes; which creates a variable called exitMinutes BUT does not actually set its value. So it is whatever that memory location previously had in it.

Then you have this:

void inputAndValidate(int entranceHourP, int entranceMinutesP, 
                       int exitHourP, int exitMinutesP)
{
	do
	{
	cout << "Enter the hour and minutes the parking garage was entered (each separated by a space): " << endl;
	cin >> entranceHourP >> entranceMinutesP;
	}
	while((entranceHourP > 0) || (entranceHourP < 24) && ((entranceMinutesP > 0) || (entranceMinutesP < 59)));

Now under NORMAL operation, you pass a value to the function and then set the values before you test it. Fine, BUT what happens when you fail to enter numbers into cin, but instead, enter letters (for example).

The line cin>>entranceHourP >> entranceMinutesP; exits WITHOUT setting entranceMinutesP and as std::cin sets its own error state. THEN you use it uninitialized in the while loop. Hence the compiler warning/error.

Finally, the values you pass to the function are completely unused, you could just as easily write void inputAndValidate() and define your variables below.

StuXYZ 731 Practically a Master Poster

The question is really do you know how to draw stuff in a c++ program and want help with the maths for making a 36 pointed star shape [10 degrees]. Or do you want help writing a C++ program to draw stuff.

If it is the maths, then the obvious way to do it is to note thThe question is really do you know how to draw stuff in a c++ program and want help with the maths for making a 36 pointed star shape [10 degrees]. Or do you want help writing a C++ program to draw stuff.

If it is the maths, then the obvious way to do it is to note that the unit vector constructed with the coordinates [tex]\cos(\theta), \sin(\theta)[/tex] and iterate through the angle from 0 to 360 degree (0 to 2*PI radians: C++ cos /sin functions are in radians!) and draw the appropriate line to the edge of the square.


So show us your basic code, and we will help a bit.

StuXYZ 731 Practically a Master Poster

Well appart from the strange layout, it works. That is always good.

Do note that a*a is the same as pow(a,2).

It is also a lot more normal to do the calculations in the double form. E.g. pow(a,2.0); . It is often quicker as well, since the floating point unit is normally in double.

Finally, think about the fact that often the points are not on integer values, what if I want to test the point 0.5,0.5,1.0 ?

You would normally use tmp variables since it makes it clearer e.g. I would be inclined to write a function that returns a value, e.g. distance. That way you can say use if for determining if two spheres intersect.

double distance(// variables here )
{
const double xd=a-x;
const double yd=b-y;
const double zd=c-z;

return sqrt(xd*xd+yd*yd+zd*zd);
}
StuXYZ 731 Practically a Master Poster

You almost have the code for that...
You have written:

int winnerIndex(int votes[])
{
   int i;
   int maximum;
   maximum = votes[0];
   for(i=0; i<5; i++)
     {
    if(votes[i] > maximum)
      maximum = votes[i];
     }
  return maximum;
}

Now if you add something like this:

int winnerIndex(int votes[])
   // This function now returns the index in votes that is the maximum:
{
   int index(0);
   int maximum(votes[0]);
   for(int i=1; i<5; i++)
     {
    if(votes[i] > maximum)
          {
        maximum = votes[i];
            index=i;
          }
     }
  return index;
}

Note I have changed a few thing:

(a) you don't need to loop through the i=0 index because you have effectively processed that in the initialization stage.
(b) I have elected to maintain two variables, maximum and index, you could do it with
just the index value but each comparison would need to be to votes[index].
(c) There is not code to deal with a tie.

You might like to change this function to include an extra input parameter to the size of the array, at the moment it is hard coded to 5, that is really ugly. And a silent bug waiting to happen when you add/remove a candidate.

StuXYZ 731 Practically a Master Poster

In addition to gerard143's solution, which is fine. You may want to make getitsvalue virtual.

This is problem is a specialization of the common construction:

class Base
{
   public:
    // Stuff... 
    virtual void write(std::ostream&) const;   
};

class Derived : public Base 
{
   public:
   virtual void write(std::ostream&) const;
};

std::ostream& operator<<(std::ostream& Out,const Base& A) 
{
   return Out<<A;
}

I only really bring that up since it is so common, that you will see that construct in many different books and open-source programs. [Note the operator<< is sometime templated with all the different classes in the program.]

StuXYZ 731 Practically a Master Poster

There is a third part the equation here: To illustrate consider this:

class AClass
{
  public:
    AClass(const int,const int) { std::cout<<"Constructor"<<std::endl;}
    AClass(const AClass&) { std::cout<<"Copy Constructor called"<<std::endl; }
    AClass& operator=(const AClass&) 
       { std::cout<<"Assignment operator called"<<std::endl; 
         return *this; 
       } 
};

int main()
{
  
AClass Object(1,1);        // Object constructed with constructor 

Object = AClass(2,2);      // ASSIGNMENT operator called.

So it the case that you have given then the assignment operator is called.

I am assuming that you have written an assignment operator. If you haven't do so now and for EVER other class you have, and while you are at it the destructor. C++ writes you an assignment operator and desctructor and copy constructor if you don't provide one, BUT they are shallow copies and if your class has any kind of complex object you definately need to write your own. The Rule is:
If in 1% doubt about needing to write the constructors/destructors/assignment operator write all 4.

In addition, I see that TheClass is derived from Parent, but you don't call its constructor in your copy consstructor. That is almost certainly unclear if not wrong.

Finally, since somethings like m_NumberOfPixelsInRegion are not constant, you are most likely going to have to write this construct for the assignment operator

TheClass&
TheClass::operator=(const TheClass& A)
{
   if (this!=&A)
     {
        Parent::operator=(A);
        m_NumberOfPixelInRegion=A.m_NumberOfPixelsIRegon;
        // ... etc ...
     }
   return *this;
}
daviddoria commented: Thanks, that was exactly the problem! +5
StuXYZ 731 Practically a Master Poster

Firstly all variables are scoped. That means that if a variable is within a set of brackets { } then the variable will exist only within that region.
Each time the execution leaves that region, the variable is said to be out of scope.

int myFunc()
{
   int A(10);
   if (A!=8)
     {
       int B=37;
       std::cout<<"B is equal to "<<B<<std::endl;
     }
   // This line will compile:
   std::cout<<"A=="<<A<<std::endl;
   // This line will not compile: 
   std::cout<<"B == "<<B<<std::endl;
   return;
}

Note the line accessing B at the end of the function will not compile, because B is out of scope

All information on a variable is lost when it goes out of scope. There are a couple of exceptions,with the main one being the declaration of a static variable. e.g.

int myFunction()
{ 
  static int A(10);  
  int B(10);
  std::cout<<"A == "<<A<<" B=="<<B<<std::endl;
  A++;
  B++;
  return;
}

In this code A increases each time that you call the function, but B stays as 10.

Note: In your code you DID NOT initialize the variables win and loss. Their initial value can be ANYTHING and it can be runtime dependent, e.g. you run the program once, it works, next time it doesn't. Always initialize variables with either int win(0); or int win=0; . Both of these pieces of code are equivilent.


Global variables are normally, just variables that are defined in the "global" scope, i.e. they exist until the last point in the program.

In this …

StuXYZ 731 Practically a Master Poster

Well that is pretty strange!

The obvious thing to to write a tree container that contains the objects in the tree, either as pointers or directly [sometimes both].

Here, we have class Tree, that has a single pointer to Player.

Then let us figure out if anything actually works:

First off is the find method, as fast as I can see it assumes that the tree is ordered by numerical comparison of the pointer values. So overloading the < and != operators for Player has no impact.

// Your previous post
PlayerTree->Insert(players[1]);
PlayerTree->Insert(players[0]);
PlayerTree->Insert(players[3]);
PlayerTree->Insert(players[2]);
PlayerTree->Insert(players[4]);

Now assuming that you have pointers that increase as you got from players[0] -> [5]

You then call a display order that DOESN'T use the root player, but whatever item you give, but let us assume that you put in players[1]. Your tree after the inserts looks like this

4
          / 
        3     
      /   \
    1       2
      \
        0

All other entries should be null ptr.

Then the display should be 0 : 1 : 2 : 3 : 4 . If you don't believe me,
the step through the tree from the diagram. : Node 1, has a left, so go to 0, ok so it doesn't have a left, display 0 , no right, so go up to 1 again, display etc..

Does this help?

StuXYZ 731 Practically a Master Poster

Firstly you didn't mess up the code tags, thanks for using them.

Second, without all of your code I cannot tell, but you are putting the Player pointers into a tree. That is most likely ordered, and hence the output is ordered.

Can I just add, if you do this

std::cout<<*p1<<std::endl;
std::cout<<*p2<<std::endl;
// etc...

do you get the right order e.g. 0,3,1 etc ? If so then it is that your tree is ordered. [Did you write the tree ??]

StuXYZ 731 Practically a Master Poster

First welcome to Daniweb, second please use code tags! It make life easier for all of us.

The problem is possible with the use of srand(time(NULL)); . What you are doing is re-initializing the random number generator with a number and that number is from the time. HOWEVER, time(NULL) normally only gives an answer to the nearest millisecond, I guess that you are reinitializing the random number generator with the same seed number each so the first random number is always the same.

To cure the problem put srand(time(NULL)); or as easier for debugging,
write something like srand(53234231); but put in just after int main() and nowhere else.

Note: 53234231 is not special, it can be absolutely any number (except zero )

Hope that helps

StuXYZ 731 Practically a Master Poster

You seem to think that intermediates are attempts that is not the case,
I don't understand how you can skip that test of 875, it is a guess, and too high a guess.

e.g.

computer value: 789

minValue=1;
maxValue=1000;
for(int i=0;i<10;i++)
  { 
    guess=(maxValue+minValue)/2;
    // set maxValue minValue based on the result
    if (high)
      minValue=guess;
    else
      maxValue=guess
  }

That would give:

attempt 1:  500   low
attempt 2:  750   low 
attempt 3:  875   high
attempt 3:  812   high
attempt 4:  781   low
attempt 5:  796   high
attempt 6:  788   high
attempt 7:  792   high
attempt 8:  790   low 
attempt 9:  789   Success.

With only one value to find and only that information, and the cost of guessing high/low being the same, then that the optimal way to find the solution.

StuXYZ 731 Practically a Master Poster

It sounds like you are looking for an interpreted language which can interact with you c++ code. If that is the case, then look at languages like lua, e.g. http://www.lua.org. Used with swig it makes a really quick interface, http://www.swig.org

There are others, but I found these two worked well for me. I will point out that python is used a lot but I haven't had much experience using it.

What you might be looking up in google is "C++ interface interpreted". That gets you stuff about interfaces to a host of languages e.g. R, SQL, perl etc.

Maybe this helps.

StuXYZ 731 Practically a Master Poster

There is always the ostream methods e.g.

void print_list_four(const std::list<cProg3>& lst)
{
  copy(lst.begin(),lst.end(),std::ostream_iterator<cProg3>(std:cout,""));
}

However, you will want two things, (1) to change your void Print_f(fstream &Outfile); to something slightly more general. void Print_f(std::ostream&) const; and (2) to add this functions

std::ostream&
operator<<(std::ostream& OutStream,const cProg3& A) const
{
   A.Print_f(OutStream);
   return OutStream;
}

Effectively you are giving your class a operator<< and then using with a functional.

However, there are a lot of ways to do this, and the difficulty is choosing the most appropriate.

StuXYZ 731 Practically a Master Poster

Without all the code to test this, we are just guessing. BUT: the for loop in the copy constructor looks horribly suspicious.

for (DLNode *sourcePtr = source.head->next->next;
	sourcePtr != tail;
	 sourcePtr = sourcePtr->next) 
{
  // ...
}

You see that tail is set to tail(new DLNode::DLNode(head, 0, NULL)) so despite the inserts it remains within the scope of the new list. Therefore,
sourcePtr which is within the realm of the old list cannot ever be equal to it.

This is just a guess. I don't feel I have enough of the code to evaluate it further. I hope this helps. [It is an easy one to put a test in for.]

StuXYZ 731 Practically a Master Poster

Several things come to mind. [and in no particular order]. You will have to judge what you think the importance is.

(a) You test a double precision number to be exactly equal to zero, that very often doesn't happen, e.g. your get 1e-314 or something very close to zero but not zero. In many programs you should NEVER test for zero but rather being within a tolerance,e.g. fabs(Var)<1e-20) .

(b) define a constant for pi, [or use M_PI from cmath] with a lot more significant figures, you can also use 4.0*atan(1) , or you favorite trig identity.

(c) On the entry part, if the user enters a radius, then don't ask for an area or a diameter. At the moment if they input all three, then the area dominates.

(d) The output part [as pointed out by Nick Evan] is repeated, so why not use an
if else construction and put the output at the end.

(e) pow(x,2) is equivalent to x*x. I would write the later, BUT my compiler g++, actually produces the same machine code so it is purely stylistic.

(f) There is no test for negative entry.

(g) not putting a '\n' on the last output line seems a bit ugly

(h) you have written int main() as int main( int nNumberofArgs, char* pszArgs[]) , it is very common to write that as int main(int argc,char* argv[]) . So common that it is almost a standard.


StuXYZ 731 Practically a Master Poster

First off I wish to apologizes for failing to read the ivaylos91's question properly, as was pointed out by arkoenig and VernonDozier.

Second, I have not re-read the question, and would like to ask another about ivaylos91's code.

1) The question does not seem to imply that (a) f(x,y) is itself integer, only that the values x and y are integer. Thus you should be very careful defining min and max as integer, they would be probably be better as float.

2) min and max should not be initialized to zero. For example the function f(x,y)
might have a maximum value of -1.0, or a minimum value above zero. (It is normal to initialize to a start value of x,y e.g. if the range is -50,-50 to 50,50 you might like to start with min=max=f(-50,-50); but any value within the range
is perfectly acceptable. (e.g. f(0,0) if you like.)

3) Be careful on line 33/34 that you can't set f to max but you want to set max to f.

4) you look increases by 0.01, was that just for testing, because I expected an increase of 1.0 per step.

5) Subtle I know, but you have missed the inner brace pair { } on the inner loop.

Finally, I horribly suspect that VernonDozier is right, that you will be asked to change the boundaries, especially since such an unpleasant function was picked to test your algorithm with. In that case a steepest decent method, with integer step …

StuXYZ 731 Practically a Master Poster

First off, absolute brute force isn't going to work in this case as the input is in floating point, and you can easily get a function that has maxima at non-integer values.

Next, the finding of minima/maxima of a function in a range, is still an active research topic. Even some very simple functions have large number of mimina/maxima in an interval and determining the global maxima is difficult.

Given that, here are two approaches that you might like to consider, first is to calculate the partial derivatives and solve the simulation equation you get when you set both to zero. Note that you will, get maximums, minimiums and saddle points [dependent on the function]. The find the range that you have selected and if any are valid. This will lead to a large and complex program if it has to be done for a user entered function. It will lead to a simple program, that might not even need the user function for a specified function as given. [You just put in a table of the max/min. and find out if you which are within the users input interval]

Now, you can observer that for a function of 2 or more variables there is not a simple solution bracketing approach [as is often done with 1 variable problems]. There are approaches that use the steepest decent method [Let us consider finding a minima, just reverse the logic for a maxima] and then you can use this …

StuXYZ 731 Practically a Master Poster

The code that you wrote correctly works in both cases because you didn't actually do anything with obj2 or obj1.

Note you wrote this: cout << "ob2.tab[0] = {" << obj1.getTab()[0] << "}" << endl; That should have been obj2.getTab() not obj1.getTab() Additionally you have incorrectly written the constructor: This should core dump in most circumstances e.g. you have written:

A::A(double t[], int size)     // size MASKS the variable size in the class 
{
   tab = new double[size];
   for (int i = 0; i < size; i++)
    tab[i] = t[i];
}

It should have been written like this:

A::A(double t[], int s) :
  size(s),
{
   if (size>0)
     {
       tab = new double[size];
       for (int i = 0; i < size; i++)
         tab[i] = t[i];
     }
   else
     tab=0;
}

THEN if you remove the copy constructor, you get a core dump BUT it occurs on the deletion operator of obj1. To understand that, you must note what happens if you don't actually provide a copy constructor. The compile substitutes a simple copy constructor that makes a shallow copy of everything. In this case, the variable tab, is just copied, i.e. both obj1.tab and obj2.tab point to the same memory location, however, obj2.tab is deleted and everything is ok, [you have had one allocation and one deletion.] The get tab[0] command actually works, since there is no check to see that the memory hasn't been deleted, and nothing else has happened for the program to fill/change that memory. Then …

StuXYZ 731 Practically a Master Poster

Well you really are going to have to give us a little more code. There are no obvious things that you are doing wrong:

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>

int
main()
{
  std::ostringstream cx;
  typedef std::pair<int,std::string> PT;
  std::vector<PT> XX;
  for(int i=0;i<10;i++)
    {
      cx<<"a";
      XX.push_back(PT(i,cx.str()));
    }
  // Erase some stuff:
  XX.erase(XX.begin()+3,XX.begin()+5);
  // Write it out:
  for(unsigned int i=0;i<XX.size();i++)
    std::cout<<"XX == "<<XX[i].first<<" "<<XX[i].second<<std::endl;
}

The above code deletes a section from the vector and shows that the strings haven't been deleted. If that works on your system, you are going to have to enrich that program until it has your error.

Have you checked that you are not miss using an iterator e.g.

std::vector<PT>::iterator Iter;
for(Iter=XX.begin();Iter!=XX.end();Iter++)
  {
     if (Iter->first==3)
       XX.erase(Iter);   // THIS INVALIDATES Iter.
  }

Beyond that you will have to post a bit more code. sorry couldn't be more help.

StuXYZ 731 Practically a Master Poster

I expect that you wrote somthing like this: std::cout<<"result == "<<a<<std::endl; . The problem with that is the default precision, for output, is 6. The number itself is of a higher precision.
If you write this

#include <iostream>
#include  <iomanip>   
 
int main()
{
double a=1.2345678901234567890;

std::cout<<std::setprecision(20);
std::cout<<"results ="<<a<<std::endl;
// Not all numbers are now in precision 20.

The following code give you something like : 1.1234567890123456912
That is because [for my 64 bit machine -- sizeof(double) == 8 bytes] the precision of double is about 14/15 decimal places. [and I got lucky with the roundoff for the 16th ;) ]


You will get more decimal points and a bigger exponent range if you use long double. If you need a larger precision for something, then there is the gmp [gnu multiple-precision library] http://gmplib.org/, which is only limited by your computer memory and speed.

Overall I am normally very very disappointed with the way that formating is done in C++. I basically rely on the boost::format http://live.boost.org/doc/libs/1_39_0/libs/format/doc/format.htmlsystem which is much more printf like but with slightly more type checking, and slightly better error messages.

StuXYZ 731 Practically a Master Poster

First off, well done for thinking about contributing to OSS [Open source software].

Personally, I think the best way to get a project is to actually look at your secondary skills and interests. Almost everyone involved in OSS is actual able to program. The skill level is surprisingly high. The reason is that when you code is public, if you submit poor code/good ideas, it gets re-written, and when you see the re-write, you already know the algorithm, so you can quickly follow it. That raises the skill level, faster than college courses and faster than a closed shop coding, were "that it work/passes unit tests" is often the level of extent [Not always I know!]

The first route in is very difficult, in my opinion, that is do the documentation of a project, building up to the code and then bug fixes and then contributing. All of that is do able but the time that it take to feel that you are contributing is SO long. What happens [in practice], is that before you figure out what is going on, the bug that you are looking at, got fixed by someone who "just made number of changes", and you end up chasing yesterdays ghosts, or you actually patch a bug, but the bug really was a symptom of a much bigger problem and should have been dealt with by refactoring a section.

So if you are a beginner programmer, there is a second way in, that …

StuXYZ 731 Practically a Master Poster

Sorry the solution given is just too inefficient. You simple don't need to copy the whole array each time.

Taking ravenous's code base:

const unsigned int range = 100;
const unsigned int numberToSelect = 10;


int* remainingNumbers = new int[range];
int* chosenNumbers = new int[numberToSelect];
 
// Initialise the list of possible choices
for(int i = 0; i < range; i++)   
  remainingNumbers[i] = i;
 
for(int i = 0; i < numberToSelect; i++)
  {
    const int selectedElement = rand() % (range - i);
    // Remember the value of the chosen element */
    chosenNumbers[i]=remainingNumbers[selectedElement]; 
  
    // Now: ONLY exchange the selected number with the last valid number
    // in the remainingNumbers set:
    remainingNumbers[selectedElement]=remainingNumbers[range-i-1];
}
delete [] remainingNumbers; 
/* Do things with the chosen numbers */

/* tidy up */
delete [] chosenNumbers;

That is more efficient. It still has the uniqueness, and is still equally likely to select all values. -- Just in case that this not
clear:
Consider the number 1-5

Array: 1 2 3 4 5
// select number 2 (from  rand % (5-0)
Array: 1 5 3 4 (5)         // 5 at the end if repeated since we copied it in
// select number 3 ( from rand % (5-1)   -- you can't get the last number in the array.
Array: 1 5 4 (4) (5)       // 4 and 5 repeated
// select 5           // FROM position [1] from rand % (5-2)
Array: 1 4 (4) (4) (5) 
/// etc....

Can I also say that it …

StuXYZ 731 Practically a Master Poster

Something that avoids all the graphical stuff, [Well use an external program - not part of the project] is a simulation. That can go from easy, to extremely complex. There are a number of classes of simulation, but it is easier to give an example, what about a set of stars in an galaxy. You obviously have [initially], very simple equations of motion. You can simulate just a few stars. You might like to simulate the expected constellations patterns in 50,000 years, or small scale like a simulation of our solar system.

Then you can take you project into a number of interesting directions, you can add relativity, you can add solar aging (mass of the start decreased), you can add the effect of a supernova, mass is ejected very fast, energy is ejected at speed of light. You might want to simulate a solar system, that again can get complex, with solar winds, thermal pressure, planet+solar spin, comets etc, or stay simple with just basic F=ma motion.

If you don't want to play with gravity, e.g. a pool simulation [game with 15 ball + white ball] etc, starts very very simple, gets very complex very quickly [spin,
table nap, cushions]

Almost every simulation of a system that has definate state, starts relatively simple but has underlying complexity, even the simple Newtonian star system, with three stars, is actually chaotic in many configurations, and can be enriched, until you have no more time, etc. Effort can …

StuXYZ 731 Practically a Master Poster

The first thing you need to do to fix this, is to realize that you are passing WHOLE strings and not individual characters:
Add this line like this:

while(iss >> str) 
    {
      std::cout<<"str::"<<str<<"::"<<std::endl;        // ADD THIS LINE
      //iss >> str;

That will show you that you have str that is a complete string, it is not individual characters. E.g. When you do the test str!="+" it will ALWAYS be true, since "4+3" is absolutely NOT "+". Thus your code simply think you have a single object, and the postfix and prefix versions of a single object/number are both the same, just the object.


When you put str to be an individual character (e.g. char). You got a whole pile of errors. THAT IS GOOD!!!! That is the compiler helping you fix your code that is simple wrong in many places.

So, in short, make str (a) a char , (b) a better name, that you are not going to mistype and find is a keyword. (c) fix all of the compiler errors and then try a little debugging, e.g. putting output statement and assert's etc.

Sorry that is a little harsh but that is the only way you are going to fix this code that I can see. When you have fixed the compiler errors, feel free to repost, I/others will happily help with the remaining runtime bugs.

Finally, about putting a qualifier on on the line T tmp = stack<T>::top(); . …

StuXYZ 731 Practically a Master Poster

First off welcome Daniweb.

Next, now that I have your code, what are the problems with it. Unfortunately, quite a few -- I have listed a few to get you going in the right direction.

The first is that you are using this code [lines 32-34]:

cin >> line;            // get a string into line up to the first space deliminter ] 
getline(cin, line);     // This reads the rest of the line 
istringstream iss(line);

That means that for the program to accept say 4*5 you have to enter: someJunk 4*5 . All the characters in the first expression up to the space ("someJunk") are thrown away.

So fix it by removing the cin>>line; Unfortunately, that isn't your only problem:

while(iss >> str) 
  {
    // Stuff...
  }

Since str is a string [not a char] then it assumes that you are entering you text like this: 5 * 4 + ( 6 - 32 ) .

The obvious way round that is to use a char. There are a lot of changes to that, you need to make the "+" into single character e.g. '+' .

Next you are using a very strange construct for handling the brackets

else if(str == ")") 
  {   //If the ) is encountered, pop the stack until the ( is found
    while(str != "(") 
      {
        // THIS LINE doesn't change the str so it is an infinite loop:
        // Until stack thows an exception.
	cout << stack.pop();
      }
StuXYZ 731 Practically a Master Poster

Obviously, it would be a lot easier to look at this if you had posted all the code.

However: Find_Trav_Subtree looks very strange [to me].

You see it calls the right branch if (current->Right) AND then always returns Find_Trav_Subtree from the right branch REGARDSLESS of it returning a NULL. I would have expected to see something like this:

BSTNodePtr Result(0);
// Note only return from right if a valid result is found:
if ( Current->Right && (Result = Find_Trav_SubTree(Current->Right,ID)) )
   return Result;
return ( Current->Left) ? Find_Trav_SubTree(Current->Left,ID) : 0;

There are many ways to do this.

Hope that helps, if not please post the full BSTClass so we can also compile and debug it.

StuXYZ 731 Practically a Master Poster

There are several mistakes in the above code. The main one is that you wrote the code in one long block without debugging each section. It is almost always easier to write the code in little bits, keeping a running program that does a little more each time.

Let us look at some of your common errors: Consider this code

while(i<phraseLength&&!letterFound)
   {
      if(nextLetter==phrase[i]);
      letterFound=true;
      i++;
   }

The first thing I did with your code was compile it with all the warnings on:
and I get several warnings and it tells me that I have an empty body in the if construction at 160.

The second thing I did, was reformat it with a code indenter. . That shows the problem. The if statement has an extra semi-colon so letterFound is ALWAYS true.


I am sure you can see your mistake now.


EDIT: theLamb beat me too it, sorry for the repeat, . But please compile with warnings and use an automatic code indenter. It really really helps show you were the errors are, just because things "look wrong".

thelamb commented: Put some good effort into this +3
StuXYZ 731 Practically a Master Poster

There is a nice tutorial at http://www.newty.de/fpt/index.html.

The ->* is a pointer dereference to a function pointer. Easiest way to google it is
to put it in quotes.

StuXYZ 731 Practically a Master Poster

On reading this I thought that the obvious solution is to use a functional.
The functional can be defined as a member of your class, or not.

Additionally, I wasn't actually sure what algorithm you were implementing, in this example I consider that you have an vector of values, and wish to find the positions of the lowest values without disturbing the vector.

consider if you did this:

class comp
{
  const std::vector<double>& RefVec;   

  comp(const std::vector<double>& A) : Ref(A) {}

  bool operator()(const int A,const int B) const
  {
    return (RefVec[A]<RefVec[B]);
  }
};

int main()
{
  std::vector<int> Index;
  std::vector<int> Out;
  std::vector<double> Value;
  
  for(int i=0;i<10;i++)
    {
      Value.push_back( ((i % 3)-1.0) * i*i);
      Index.push_back(10-i);
    }

  Out.resize(3);
  partial_sort_copy(Index.begin(),Index.end(),Out.begin(),
		    Out.end(),comp(Value));
 
  for(int i=0;i<3;i++)
    {
      std::cout<<"Lowest Values == "<<Value[Out[i]]<<std::endl;
    }
}

The function idea can be extended to include very complex ideas, since the functional has state.

Next: You can use member pointers to functions, but you need a calling function:
You just need a slightly different syntax. However, it wont help you (easily) here since you are going to have to do a lot of bind2nd etc to get it to work [or use boost::bind].

Note the comment the compiler gives you is correct, the key phase is address of an unqualified which is because you missed out the className:: part of the qualification.

class X
{
  public:
  // Two functions with same signature [ void () const ]
  void call() const { std::cout<<"CALL"<<std::endl; }
  void call2() const …
StuXYZ 731 Practically a Master Poster

There are two issues here (a) code given doesn't do the assignment. (b) you don't understand the recursion.

First let us deal with (a). Code given returns false if stones are greater than 5.
That is not true. Consider the case that there are exactly 6 stones. If I take one stone leaving 5, you can take 1 or 2 or 3 leaving 4:3:2. In those cases I would take
3,2,1 stones and you have to take the last stone. So from 6 there is a guaranteed win. So returning false is wrong.

Now we have actually (partially) discovered the solution in that example. If there
are exactly 5 stones and it is my turn to play I will lose [no guaranteed win], equally the same is true of one stone, but 4,3,2 are all guaranteed wins.

So what is the recursive code and how are you going to write it.

Let us start with a simpler example [this one has branching which makes it more complex].

Say you wish to calculate a factorial, then you might write this:

double factorial(const int N)
{ 
   if (N<=1) return 1.0;
   return N*factorial(N-1);
}

Not how for say factorial(5) you make 5 calls to the function of which 4 are from the function itself.

Now the real question is do you need to use a recursive function to do this problem. The reason to ask is that there are several ways to solve …

StuXYZ 731 Practically a Master Poster

Sorry I am not impressed with your teacher.

Most compilers of c++ and a lot of other compiled language split the program up into individual files. Each of those files are normally compiled into object files.
These normally have the .o extension. They are the machine code of each block of code. However, in many of these .cpp file, there is a call to a function that is declared (normally in a .h file), but not defined (the actual code for a function, in a .cpp file. The object file contains a symbolic link to that function but not a direct call. These is resolved by the linker that takes all the .o files and tries to resolve all the symbolic links to produce a single executable.

Normally the production of an object file is done first, and then the object files are linked together. The commands given would be

g++ -c Client.cpp
g++ -c Server.cpp
// All the other .cpp files etc....

The you would link it with the command g++ Server.o Client.o other.o and that would give you an executable called a.out. [if you used the -o option you can change that name]

However, for short programs, there is a quick way, just give g++ the list of files to compile and it will compile and link them .

Your command line was : g++ hw2.cpp

So unfortunately the linker says that it cannot link the files because it doesn't know …

thelamb commented: Thoroughly explained (Y) +3
StuXYZ 731 Practically a Master Poster

The reference to a pointer is not that difficult to understand once you understand that it is a reference to a type: Let us consider some examples to make the point

void func(int X)
{
   X=10;
   return;
}
int main()
{
   int y(20);
   func(y)
   // y still 20 here:
   std::cout<<"y == "<<y<<std::endl;   
}

In the simple code above, you can see that y doesn't change. So let us change func to this.

void func(int& X)
{  
   X=10;
   return;
}

Ok now, x get changes since it is a reference.

Well what about a pointer:

void func(int* X)
{
   *X=10;
}
int main()
{
   int y(20);
   func(&y);
}

Well you have to call that differently with that ADDRESS of y. But let us change it to this:

int main()
{
   int y;
   int *yPtr=&y; 
   func(yPtr);
   if (yPtr==&y)
     std::cout<<"yPtr unchanged";
}

But after the call yPtr STILL points to the address &y. What if you want to CHANGE a pointer, well it is just like changing a value, just that the pointer is the value.
You might like to write this:

void func(int*& XPtr)
{
   XPtr=new int[8];   // Allocate 8 int
   return;
}
int main()
{
   int* yPtr(0);
   func(yPtr);
   delete [] yPtr;         // yPtr == memory from a new.
}

As [hopefully] you can see, all a reference effectively does is allow access to a value as if it was in direct scope. So that you add a reference if you want to change and …

StuXYZ 731 Practically a Master Poster

Ok the class is a policy class. So let us understand what you can do with the original code and your code.

First consider two classes:

class SimpleObj
{
  // Stuff..
  public:
    SimpleObj();  // Simple default constructor
};

class ComplexState
{
  public:
    ComplexState(const int,const std::string&);   // THE ONLY CONSTRUCTOR
};

Now with your code, you cannot use ComplexState, there is not default constructor.

However, with the original code, let me add this:

class ComplexBuilder
{
public:

  // No need for template as it is specialized:
  static void create( ComplexState*& ptr ) 
  {  
    ptr = new T(3,"testfile");
  }
};

Now I can use your class like this:

MakeT<ComplexState,ComplexBuilder>::instance()->doStuff();

The reason for a reference, to a pointer, is that the pointer value itself changes.

If I have mis-understood your problem, or I am not clear, feel free to add a reply.

mike_2000_17 commented: bullseye! +1
StuXYZ 731 Practically a Master Poster

You problems are in your fuction changeGridStorage.

You do this

x.resize(n);    // this is fine
y.resize(m);    

for(int k=0;k<=m;k++)  // I REALLY don't think that you need <= BUT this isn't your 
                       //   main problem

  v.resize(n,vector<double>(k,0));    // Ok talk about packing a lot into one line:
                                      // I will discuss it below

Now you have a v.resize() method. The prototypee for that, the simple v.resize(int,T c = T()) were T is the type of the vector.

In your case you are setting c to be vector<double>(k,0); and what you are doing is setting the size of the secondary vector in the pair to be 0,1,2,3,4 .... AND you are constantly resizing vector v.

So write it as

v.resize(n,vector<double>(m,0.0));

Then your code doesn't crash. This is another one of those reasons that I like the boost::multi_array class http://www.boost.org/doc/libs/1_45_0/libs/multi_array/doc/index.html. However, I understand that it is often a long step straight into boost as a beginner.

Other than that, I think that program works. [I can recommend putting the "\n" into the second loop of the GridFunction() and adding a space into the first. It does make it easier to read.

StuXYZ 731 Practically a Master Poster

Well done! I haven't seen this bug/error before. Anyway it made me smile.

What you have done, is simple use istringstream in a very odd way, the effect is to create a local variable

std::string str;
while(getline(input,str))
  {
    istringstream(str);   // This line is the proble:
    // str is a istringstream JUST within the scope of the WHILE:  
    cout << str;   // OUTPUT the STATE of the LOCAL istringstream
    cin.get();

You could replace it with an instance of the object, e.g.

while(getline(input,str,'\n'))
  {
    istringstream DX(str);
    cout <<"String == "<< str<<std::endl;
    cin.get();
  }

Then you can do whatever you wish to do with the object DX, which is the instance of the istringstream, and str is still the string in all scopes of your program.

StuXYZ 731 Practically a Master Poster

Your problem is that you have masked length. You wrote this:

#
void file(char* Filename, int length)
{
  int length;   // UNINITIALIZED VARIABLE:
  for(int i=0;i<length;i++)
    {
    }
}

Note that length is NOT the same length as the one passed to the function, you have masked it with the later declaration. Any good compiler with the warnings on will tell you about that. (unused variable, and uninitialized variable warnings).

Also your test of the file eof is ONLY for the first element, why not at each stage.

Finally, don't use the keyword register. It is ignored by most compilers, and unless you are mixing assembler and C++, the chances of you actually betting the compilers optimizer are very very low.

jonsca commented: Good points! +5
StuXYZ 731 Practically a Master Poster

Ancient Dragon is nearly perfectly correct in what he said, but can I say that you have to think about the deletion of the memory as well.

First off, he has made a couple of typos, however, I think that is caused by fiolet.
The AD code should be:

this->pixels = new pixel*[height];
for(int i = 0; i < height; i++)
   this->pixels[i] = new pixel[width];

Now I strongly suspect that AD put that there deliberately to see if we are all awake. :) But it illustrates a key point, you should not name variables and classes by similar names, especially names that are just one tiny typo away from each other.
It just makes reading the code SO difficult. [and leads to errors].

The deletion should then be this:

for(int i=0;i<height;i++)
  delete [] pixels[i];
delete [] pixels;

However, I slightly prefer to allocate like this:
NOTE: I have swapped width and height because I noticed that you were using [x][y] implying that y is the height.

// pixels defined as : pixel** pixels;
pixels=new pixel*[width];
pixels[0]=new pixel[height*width];
for(int i=1;i<width;i++)
  pixels[i]= pixels[0]+i*height;
// ....
// Deletions:
delete [] pixels[0];
delete [] pixels;

My preference for this is that you don't have an extra variable in the delete sequence and you get a continuous block of memory. However, I appreciate that there is epsilon difference overall between the two methods.

Finally, both methods allow this:

struct pixel
{
   // other stuff...
   int r; …
StuXYZ 731 Practically a Master Poster

In this particular case, it seems to be that you are getting the exception from the line if (data[i].at(it->key) == check_word_key) . That is because it->key DOES NOT correspond to the size of the vector data.

This occurs because data is not a vector of size TABLE_SIZE but is of the number inserted. E.g. you insert keys 34, 56 and 78. Now you have three vectors with one component each. THEN you access from key 34, and you do data[34].at(34). Opps error.
Since data[34] only has one component.

To see this, modify your lines:

std::cout << "iteration through FOR loop" << std::endl;
std::cout<<"Size of data["<<index<<"]=="<<data[index].size()<<std::endl;
std::cout<<"Accessing "<<it->key<<std::endl;
StuXYZ 731 Practically a Master Poster

You have made the same mistake as the original [in a different place].

You bool operator does not know anything about the vector or the type, that is because it actually is the type contained in the vector:

it should be this:

bool operator==(const int& Index) const   // Get the value to be compared into index
{
  return (key==Index);
}

You have completely confused yourself by using the variable name key in just about every possible location in your code, thus it is a scope understanding master-class to figure out what is going on. Try this:

template <class RecordType>
bool table<RecordType>::is_present(int possibleTarget) const
{
  std::size_t i = hash(possibleTarget);  

  typename std::vector<RecordType>::const_iterator it;

  for (it = data[i].begin(); it != data[i].end(); ++i)
     {
       if (data[i].at(it->key) == possibleTarget)
          return true;
     }
  return false;
}

Finally, get hash() to return a reference to a data object and not an index value, you can use an empty vector for a "not found". [When you have it working!!!]

StuXYZ 731 Practically a Master Poster

you have two problems with your code:

(a) missing typename on the in the template file.

std::vector<RecordType>::const_iterator it;  // THIS IS WRONG

// This is correct:
typename std::vector<RecordType>::const_iterator it;

There are many explanations around for this, it basically is because since depending on what std::vector<RecordType> is specialized as, you can't figure out what const_iterator will be. [It might resolve to a value for example].

Next you have a small issue in resolving the repeating name issue and
in precedence order:

if (data[i].at(*it.key)  == key)  // THIS IS wRONG
// This is better [precedence order correct]
if (data[i].at(it->key)  == key)

That will leave you with one function to add, and that is a bool word_record::operator==(const int&) const; since you are comparing a RecordType with an int on the line 15 of the code.
you might like to write the completely unintelligible if (data[i].at(it->key).key == key) but then I don't think that is a good idea.

Additionally , you need to provide implementations of table::table and table::insert().

StuXYZ 731 Practically a Master Poster

It adds bad_alloc.

Yes, some compilers have it in iostream, [including gcc] but if you were to remove the std::cout part then new is the file that it is actually declared in.

The #define _NEW ... #endif around the file will limit the compiler overhead from re-compiling the file. [obviously doesn't completely eliminate it]

StuXYZ 731 Practically a Master Poster

It is a bit more complex than that. You have made a whole set of basic errors, and I think you have to fix all of them to get yourself out of jail here.

Let me start: First off you have TWO constructors, (a) the default constructor and (b) a valued constructor. The first is ok, [but ugly] and the second is junk.

The second is written like this:

Employee(std::string name, int number, int date)
    { set(name, number, date); 

void 
Employee::set(string name, int number, int date)
{ 
}

So obviously nothing gets set.

Next YOU DO NOT HAVE A copy constructor OR an assignment operator. If you have a non-POD [Plain Old Data] class, and in this case std::string is NOT a plain data object, ALWAYS write those two methods, unless you are into that super guru c++ class, which I can only aspire to.

This does not actually affect you here BUT it will as soon as you do anything else.

If you fix set, then this program works.

However, I don't understand why you get a ProdcutionWorker, and then create an Employee. I think that you wanted a production worker. so why not do a

// Remove this: 
// Employee info(name,number,date);
// and change it to this:
stats.set(name,number,date);
// change all instances of info to stats in the output.