StuXYZ 731 Practically a Master Poster

In order:

1) Yep 95% of the time, the thing to do is return a reference. It is not obligatory, for example you could return a flag (for example on a cyclic counter as it loops over)

2)

loc& operator++();      // prefix
        loc& operator++(int);      // postfix

Note that you do nothing with the int e.g. you write

loc&
loc::operator++(int)
{
  // stuff
   return *this;
}

3) I very very much doubt you want a friend function. If they are the same class then you have automatic access anyway. I will also say that version 3 is very strange. The code as given will not work. operator++ MUST take nothing or an int.

If you want a bit more help with (3), then a little more pseudo code explaining what you are actually trying to achieve would help a lot I think.

Hope this helps.

StuXYZ 731 Practically a Master Poster

No you can have a bit of both. In C++ you can have multiple inheritance
e.g. class A : public B,public C and class A could contain any number of things... e.g.

class A : public B,public C
{
     D Item;
     E array[5];
     F* ArrPtr;
};

In the last example class A inherits from B and C but contains a single instance of D, 5 instances of E and a pointer to an F or some group of F
(exactly which is to be determined by later code).

The only problem you will get, is that the phrase "composite class" is often used to imply that the main function of the class is as a container. It does not preclude inheritance or complex internal functions but in discussions the intent of the phrase is that the class contains and manages stuff.
It is sometimes used in a verb form e.g. "class X is a composite of Y and Z", meaning that X contains one or many instances of Y and Z.

StuXYZ 731 Practically a Master Poster

This just doesn't work, your read the file into line one line at a time
and each time overwrite the previous line before actually doing anything.

Move the } below c++; down one line but still it doesn't do much.
(other than actually print
1 lines
2 lines ....


Normalize means divide a vector by a number such that the length of the vector is 1.0. A vector with length 1 is called a unit vector.
It is applicable to all dimensionality, e.g. vector([tex]3/4,-1/4,\sqrt{6}/4[/tex]) is a unit vector.

StuXYZ 731 Practically a Master Poster

In future please add the compiler error messages (well the first few).

you seem to define your own iterators in spellcheck. That is going to cause problem LATER.

pair<iterator,bool> requiires a complete type of YOUR iterator
that is only pre-declared with the line class iterator; Another problem is that list<EntryType>::iterator i = buckets[index].begin(); make i an iterator of type list<EntryType>::iterotor
BUT
buckets[index] is a list of type string but entryType is a pair.

Additionally.. pair<iterator, bool> spellCheck<string,string,hFstring>::insert(EntryType& entry) needs a template<> in-front of it since it is a specialization.
Also there is not generic, so why bother with a template class???

Sorry for the rant. Basically, you should start again. Write it WITHOUT templates and then convert. It will be much easier.

Additionally, don't use using namespace std; It is not making your life easier just adding to the confusion. You need to wri te std::list etc BUT then you are clear when you are using your own and when you are using the stl.

StuXYZ 731 Practically a Master Poster

Hi

Ok in no particular order a few problems with this code + the fix for your compile problem. (I hope)

the do { } while loop in main is a double test, try something like

int flag;
do
  {
     singleChar=getChar();
     flag=validateChar(singleChar);
     if (flag)
        std::cout<<"valid"<<std::endl;
      else
         std::cout<<"no valid"<<std::endl;
} while (flag);

That way you don't call validateChar twice on the same code.

displayCharIndex is wrong because the ine
char* strchr .... is a function declaration (function returning char*)
you want something like....

int 
displayCharIndex(char strArray[], int size, char ch)
{
char* strchr; 
//search code 
//make strchr point to the first instance of ch in strArray
// ...
return strchr-strArray;

I am guessing this is an assignment so I haven't written the search code for you. If you make an attempt and get stuck, please re-post.
Additionally, since you are using the stdio calls (strlen etc). Don't name your variables similar names e.g. strchr. You will get into a mess later.

StuXYZ 731 Practically a Master Poster

The mistake is that you are using integers (the set 0,1,2,3 and -1 etc)
to represent floating point number. int a=2*1.2; gives sets a to 2.

write

double Meters;
double Yards;

instead of the two int declarations.

StuXYZ 731 Practically a Master Poster

Classic error:

Line if (choise = y)

This ASSIGNS choise to be y, and then check to see if it is not zero.

Also you don't need the "do" after the if construction.

This tell me either (a) you are using a very old compiler or
(b) you ignore the warning messages. If it is (a) download gcc
and continue. If it is (b) , well the warning cannot be ignored until you are VERY certain you know why they are there.

Finally there is no loop???

StuXYZ 731 Practically a Master Poster

ArkM comment is good. It just works.

It does completely shuffle the deck, and it avoids all the pitfall on non-random shuffles [D. E. Knuth, The Art of Computer Programming vol2]. It is near perfect until you get a CPU bottle neck and it can be called with any RandomNumber Generator (add a third argument to the call).

However, before you go on and try to write this program, PLEASE go an read about pointers. It will take you less than a day, ArkM's solution is using pointers. your clearing the deck before a new game is 99% likely to be a pointer error (and if it is not you are likely to be using a very inefficient algorithm). After pointers, you will enjoy your C++ code a lot more, particularly this type of problem, and have the basis for understanding stl classes like list/vector etc.

p.s. If you get stuck, post a question with a bit of test code.

StuXYZ 731 Practically a Master Poster

I am assuming that you have googled this and are confused, so I will take a stab at explaining it but feel free to ask questions.

Composition is to contain. An example is easiest

class Wheelbarrow
{
private:
    Cement A;
    Water B;
    Sand C;
    
};

The class contains stuff. In this case material, but it can be anything.
The point is it contains objects/number or other things that the class can use.

Inheritance is to be the same type as. An example

class Car
{. };

class OffroadCar : public Car
{ };

Anything a general car can do, is also done by OffroadCar BUT some things (normally functions) are specialized and some things can be added. e.g.

Car & Offroad car both might need double showSpeed() but Offroad car might have a bool isStuckinMud();

StuXYZ 731 Practically a Master Poster

From the slightly overly-short section of code, (please post the rest of the while(!inFile.eof()) {.... })

I am guessing that you do not actually read any file.
inFile.eof() only checks the state of the file (it is not at the end)
If you do not have a readline / operator>> / getc or some such function, your file never advances and the while condition is always true.

StuXYZ 731 Practically a Master Poster

Basically, don't try to do two things at once.

You have (A) an array of Loanc and want (B) another array of Loanc.

So

int next(0);
temp[0]=arr[0];       // MUST remember that you don't test the first
for(int i=0;i<arrSz-1;i++)
   if (arr[i]!=arr[i+1])
      temp[next++]=arr[i+1];

If arr is not sorted then you will fail. You need a check to see if the size is zero. You would be a millions time better off using a std::vector or list, (which can be resized). It would also be much
more pleasant to calculate the correct size first before allocating
temp.

Please on future post, create a short test version.

Finally, if this is going to work. You will need to improve your memory handling, it is not obvious that you free the memory you allocate.

StuXYZ 731 Practically a Master Poster

Hope you don't mind an additional comment...
If you shuffle the whole deck, you spend an amazing amount of time in the random number generator. It is a lot better (particularly for blackjack simulations -- where you only have a few cards to get out.), to generate the random cards on the fly. The is important when considering the large deck (normally 8) that are used.

Additional, to that blackjack can be played with a reduced deck, i.e. the suits don't matter. So a 64 bit random number can be used to generate a number of cards.

Anyway, you need (for a one pack suited game):

for(int i=0;i<52;i++)
  deck[i] = i+1; 

int cardLeft=52;
int *cardPtr=deck;
for(int i=0;i<cardNeeded;i++)
{
   int j=rand() % cardLeft;
   // swap first card with selection
   // use : std::swap(cardPtr,cardPtr+j) ;  or

   // swap cards
   int tmp=cardPtr[j];
   cardPtr[j]=*cardPtr;
   *cardPtr=tmp;
  // Increment top of deck.
   cardPtr++;
 }

Now you can take the top of the deck and use it. That can be put into a function form if required. It doesn't really matter how you write this loop, or you defer it as you need each card. The key idea is to reduce the number of very expensive calls to the random number generator.

p.s. You don't use rand() for any accurate simulation work. (e.g. use Mersenne Twister instead.)

StuXYZ 731 Practically a Master Poster

The reason is that anArray is local to the scope of the function. So by the time that you use it with the ptr is it out of scope. Old compilers, use to allow this (without warnings), and no end of mayhem followed.

To get round this, you can (a) declare it on the heap int* anArray=new int[5]; .. populate ...

or (b) declare it static static int* anArray={1,2,3,4,5}; If you use option (a), you are responsible to deleting the memory!

StuXYZ 731 Practically a Master Poster

I am sorry but I laughed! However, we all begin somewhere. I can't say my early stuff was any good. [having said that I am not sure what I write today is that good.]

First off: the ; (semi-colon) is a statement end. It doesn't actually
matter were you put it, but it is extremely usual to put it at the end of the line. eg.
num1=(5/9)*32;
The white space (spaces and newline) don't matter.

So I am assuming that you haven't looked at any kind loops yet, or this program would score rather lowly.

But your program has been hurt by the fundamentals of computing, ie that it is difficult to represent numbers. Numbers in C++ can be integers / double / float and others. Each type of number has specific rule on the mathematics. In this case,

the line num5=((5/9)*(80-32)); is the same as num5=0; because (5/9)=0

The reason is that 5 and 9 are integers and under c++ and many computer languages normal mathematical integer arithmatic applies,
and the result must be in the domain of the problem. So 5/9 can only be an integer.

This can be circumvented in a number of ways. e.g. (5/9.0) or (5.0/9) or casting.

You might have wanted to use an intermediate variable here.
e.g. double factor=5.0/9.0;

StuXYZ 731 Practically a Master Poster

First off. What do you want to do about multiple edges? The problem you have is that link-lists are very specialized graphs, in which they connected linearly as A-B-C-D.

So do define topographic graph in the sense of your diagram, you are going to have to add some additional linkage to the program.
There are many ways of doing this:

Maybe define an edge + a vertex. Not that each edge can only
connect two vertex.

struct Node;         // Pre-declare

struct Edge
{
   int cost;
   Node* A;
   Node* B;
};

struct Node
{
   int data;
   std::vector<Edge*> ConnectionList;   // this can be an array etc
};

Note that each vertex (node) can connect to any other node in multiple ways e.g. a simple two node graph A B , could have two routes from A-B and even a route A-A. hence Node A would have 3 edges. (and Node B would have 2).

Once you have separated Node from Edge, most things are relatively straightforward. However, the next "interesting" problem will come when you need to define a Loop class, (one which records a cyclic loop). or a Route class, but you don't need it for this problem.

So now make those two structures proper classes, add copy/assignment etc.
Produce a container for all of them and be come up with a simple plan to do memory management. That should be all you need for a while.

Finally, I use integer cost …

StuXYZ 731 Practically a Master Poster

I think a little care in needed here. Poster #4 suggested making a heap object of A. [new A(5)] but that is maybe not what you want. It adds a level of complexity that might not be needed. You have to delete ob in B's destructor and manage the memory carefully in the copy constructor.

So what about

class A
{
  private: 
    int value;
  public: 
    A(int);        // constructor taking a value
};

class B
{
   private:
       A obj;
  public:
     B();           // Default Constructor
};

A::A(int v) : value(v)
{}

B::B() : Obj(5)
{}


int
main()
{
  A ob(8);
  B bItem;
}

That way you have a A object in each B, and it goes out of scope on with with the corresponding B object.

It you want to pass parameters to B from A, try this.

class B 
{
 private:
       A obj;
       A secondObj;
  public:
     B(int,int);           // Constructor
};

B::B(int a,int b) : 
   Obj(a),SecondObj(b)

int
main()
{
   B bItem(3,4);       // Make Obj(3) and secondObj(4)
}
mrboolf commented: you're right, it's probably better in this case. thanks for pointing it out +1
StuXYZ 731 Practically a Master Poster

As a follow up, I guess that I wouldn't have used enum in your case.
It is not wrong, it is just that you normally want to convert from a constant to an internal representation. You effectively do the reverse.

The more common usage is to enumerate "magic constants".
These are easier to see with an example:

enum matrixTYPE
{
    SYMMETRIC = 1,
    DIAGONAL = 2,
    SQUARE = 4,
   ....
}

Then you use them in an

if ((mTYPE & SYMMETRIC) // instead of (mType & 1)
  {
      processHoefmanComplex();
  }

So effectively, it is making the code easier to read. Also if for various reasons you change your mind about 1, (say you merge your matrix code with another code) then you only have to change one line of code. That will avoid hours of debugging later. Code typing cost is always cheaper than debugging.

Note that often you can do similar with a const. I use const double X(value) for parameters etc. (often putting them in a global namespace. e.g namespace physics_const )

StuXYZ 731 Practically a Master Poster

Ok. There are two problems with this.

First, you cannot declare variables within the outer scope of a switch statement. Hence lines 16 and 19 are illegal.
Second you have declared "enumerator" both at 16/19 (a local copy)
and at line 6. So you need

enum daysinweek em;
	switch(whatday)
	{
	case 0:
	  em=monday;
	  break;
	case 1:
	  em=tuesday;
	  break;
	}
	cout<<em;

I have used em, instead of enumerator, and this way em is in scope
for the cout<<em line.

Hope this helps.

CPPRULZ commented: helpful +1
StuXYZ 731 Practically a Master Poster

Hi,

There is a tiny bit of a trick to doing this. Basically, you need to get enough memory for the characters AND enough memory for a pointers to it.

This assumes that both the 501 and 41 in your example are effectively variables that are only known at run time.
So

int m(501);   // obviously this can be set elsewhere
int n(41);      
...

char *tmpC=new char[m*n];
char **OutPtr=new char*[m];
 for (int i=0;i<m;i++)
    OutPtr[i]=tmpC + (i*n);

Now just use OutPtr. (or return it from a function).

Obviously, I had better give the delete method.
it is just

delete [] *OutPtr;
delete [] OutPtr;

Hope that helps.

Salem commented: Nice way, #2 +23
StuXYZ 731 Practically a Master Poster

First off I am going to deal with the minor errors. The the major problem.

Number of minor errors:

(A) Only constructors take the ":" assignment . Error in line 18 in
destructor. It should read ~BinaryNode() {delete left; delete right;} (B) Maybe delete line Compare compare . Use it as a direct functor if (node == NULL || Compare()(key, node->key)) Major:

This code is unlikely to behave as expected. If you put say in keys
3,5,1 then when it inserts a new node, it does no re-attach the
existing items to the tree. (as well as not working, this is a memory leak)

Additionally, I feel that you are being let down by your compiler. It is not reporting useful error messages. It really helps to have another compiler sometime (e.g. gcc) [likewise if you use gcc most of the time, something like Portland or IBM etc].

Finally, it is strange to include the .cpp file in the .h file. That is because you want to use the header without including all the code. If you need a template instance, then sometimes it needs to be done
but not all the time.

I look forward to the next installment :)

StuXYZ 731 Practically a Master Poster

The problem is that you can have the inline OR the declaration.
You can't have both. So if you delete 5,6,7,8 all isl be fine.
If you wish to define the function outside of the namespace definition then delete lines 10-17.

StuXYZ 731 Practically a Master Poster

The error is almost certainly in CSimpleList.h

BUT why is the guard around the CSimpleList.h. Three lines below,
should and almost certainly are in CSimpleList.h

#ifndef CSIMPLELIST_H
#define CSIMPLELIST_H
#endif //CSIMPLELIST_H

That might be your problem, by setting the guard, you have avoided loading CSimpleList.h,
since it has a repeat of those three lines.

It is normally considered bad practice to put a guard into the src code.

StuXYZ 731 Practically a Master Poster

You seem to be doing what every condensed matter phys. student does a sometime that is to write an atomic simulation.
So I am assuming that is so. What you want is to have a multimap
that allows you to quickly obtain those particle of a particular type or
you use level (spin state maybe?), then process them. However, it is 99.99% certain that you are going to need to do it efficiently.

So use first off make your life easy and define a Atom class which holds 3D position and anything else you need. Here is a minimalistic
structure. Add cons/dest/copy etc

struct Atom
{
   double x;
   double y; 
   double z; 
};

Next:

Let us create a multimap and insert some atoms (I am using a typedef
because to keep the typing down. (let me know if you want it written completely)

typedef std::multimap<int,Atom>  mmTYPE;
mmTYPE Amap;         // Make  a multimap called Amap
Amap.insert(mmTYPE::value_type(7,Atom(3,4,5)) ;
Amap.insert(mmTYPE::value_type(8,Atom(1,2,3)) ;
Amap.insert(mmTYPE::value_type(7,Atom(6,-3,5)) ;

Note that we have two atoms (different position) at index 7.
Let us erase all atoms at level 7 AND with a negative Y position.
That is only ONE of the level 7 atoms.

mmTYPE::iterator mc=Amap.find(7);
for(;mc!=Amap.end() && mc->first==7;mc++)
   if (mc->second.y<0)
      {
        Amap.erase(mc);   
        mc=Amap.find(7);
      }

Ok the loop is messy, because the deletion invalidates the map iterator, so it has to be re-created. It is also very inefficient if
the secondary test is complex. However, if you …

StuXYZ 731 Practically a Master Poster

The lack of a . between student and majorIn is fatal.

StuXYZ 731 Practically a Master Poster

Ok the problem, that doesn't actually occur until you try to create a version of the BinaryNode (from BinarySearchTree) is that you have written:

BinaryNode(Key k, T i) : data(i), Key(k)

Note that Key is now a type [From Line 6].

You need to use key. Or please use a different word. (I like "key" for
your key name that is fine but the word "Key" as the template typename does not convey the sense of type)

Additionally, please use the references uniformly, for example if you have a key (say a string) by not having BinaryNode take a reference,
there is additional coping. Although, some compilers will help you on the optimization pass.

Hope this helps.

StuXYZ 731 Practically a Master Poster

My guess is that you have a template that cannot be expressed as a float/double type
e.g.

template<typename T>
void printout(const T& Obj)
{
  print("%2f",Obj);
}

and then

class SomethingComplex
{
....
};
SomethingComplex A;
printout(A);

There are many possible solutions but why not use the printf() in the class write function
and access by an operator<< overload. e.g.

class S
{
  ...
  public:
     void write(std::ostream&) const;  
};

ostream& operator<<(std::ostream& OX, const S& A)
{
   A.write(OX);
   return OX;
}

void
S::write(std::ostream OX) const
{
  char ss[6];
   sprintf(ss,"%2f %2f\n",internalA,internalB);
   OX<<ss;
}

ALTERNATIVE:

you might want to use the boost library (format).
e.g.

std::cout<<boost::format("%1$-2f") % Number;

BUT this doesn't get round the requirement that Number and the format type need to agree.