PDA

View Full Version : Java n00b question..




mmmdreg
Mar 11, 2007, 07:59 AM
Hey guys,

I've just picked up a course at uni dealing with OO programming using Java..

I have a really basic question here that.. while the logic could be done by a sleeping child, I'm not entirely sure of the syntax that comes about from using classes..

public class Arguments {

public static void main(String[] args) {
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "]: " + args[i]);
}
} else {
System.out.println("No arguments.");
}
}
}

The purpose of this class is to print out the arguments entered at the command line.
Write a Java application to calculate the factorial of an integer n, using iteration (not recursion). The factorial function n! is given as
0! = 1
n! = n * (n - 1) !
The input value is given as a command line argument to the Java application. Write a FactorialDemo class based on the Arguments class above to call the Factorial Class and accept the input value(s) from the command line.

Any chance someone could give me a shove in the right direction here? I'd be tempted to chuck the factorial algorithm straight into the above class and print it out instead of printing the arg's, but I think the point of it is to not do that..

Thanks in advance guys.



robbieduncan
Mar 11, 2007, 08:22 AM
There appear to be a few lessons you are trying to demonstrate you have learnt here:

1) The use of iteration (loops)
2) What recursion is (so as you don't use it). This may simply have been stated to stop you using code of the Internet as any normal factorial calculator will be recursive :D
3) The definition of classes and the instanciation of them into Objects...

So with that said there appear to be a few things you need to do:

1) Create a new class (so in a new file) called FactorialDemo that is basically the same as the one you have been provided with modification to check that there is one argument and that it is an integer.

2) After that has been done the main method should create an instance of the Factorial Class and call the calculation method, or if the method is static just call it.

It's not clear from this if you have been supplied with the Factorial Class or not. If you have not you need to create it too...

mmmdreg
Mar 11, 2007, 08:58 AM
There was also a second part to the question:

public class Card {
// the following are symbolic constants
public static final byte CLUBSUIT = 0;
public static final byte DIAMONDSUIT = 1;
public static final byte HEARTSUIT = 2;
public static final byte SPADESUIT = 3;
public byte suit; // range: CLUBSUIT - SPADESUIT
public byte rank; // range: 2 - 14
// 11 Jack, 12 Queen, 13 King, 14 Ace

public class Deck {
public Card[] cards = new Card[52];
// initialization block
{
int i = 0;
for (byte suit = Card.CLUBSUIT; suit <= Card.SPADESUIT; suit++) {
for (byte rank = 2; rank <= 14; rank++) {
cards[i] = new Card();
cards[i].suit = suit;
cards[i].rank = rank;
i++;
}
}
}
Implement the toString( ) method for the Card class. Each suit of cards should be represented by a single letter:
S for spades, H or hearts, D for diamonds, C for clubs
When the rank of a card is no higher than 10, it should be represented by its numeric value. When the rank of a card is higher than 10, it should be represented as
J for jack, Q for queen, K for king, A for ace
For example, the King of Spades should be represented as SK. {HINT: for clarity and ease use the SWITCH statement to assign the suite code).


Implement a shuffle ( ) method for the Deck class to shuffle the deck of cards. Use Math.random( ) to emulate the randomness of shuffling. Then implement a deal( ) method to deal the top four cards into four hands. Use the toString( ) method to display on the terminal window the value of the four cards dealt.

The code I churned out for each part is as follows:
public string toString(byte suit, byte rank) {
string output = "";

switch (suit) {
case 0:
output += "C";
case 1:
output += "D";
case 2:
output += "H";
case 3:
output += "S";
default:
;
}

switch (rank) {
case 2:
output += "2";
case 3:
output += "3";
case 4:
output += "4";
etcetcetc.....
default:
;
}
}

public void shuffle() {
Card theCard;
theCard = new Card();
public Card[] shuffledCards = new Card[52]
int i = 0, j = 52;

while (i < 51) {
boolean hasBeenUsed = true;

while (hasBeenUsed = true) {
theCard = cards[Math.floor(Math.random()*j)];

if (theCard.rank != 0) {
hasBeenUsed = false;
}
}

shuffledCards[i] = theCard;
cards[j].rank = 0; //kill the card so it won't be included again
j--;
i++;
}

}

public void deal(Card[] shuffledCards) {
byte suit, rank;
string output = "";

for (int i = 0; i < 4; i++) {
suit = shuffledCards[i].suit;
rank = shuffledCards[i].rank;
output = shuffledCards.toString(suit, rank);
System.out.println("Hand " + i + ": " + output);
}
}

I'm pretty sure the logic to what I've done is sound.. Would anyone be able to check on the syntax though?

Thanks again.. =) =)

robbieduncan
Mar 11, 2007, 09:07 AM
I'm a little pushed for time right now so I'll only comment on the toString():

1) It's more optimal to use StringBuffer when you're building a value like that.

2) Your switches will do the wrong thing as you are not breaking on each case. So if the card is a Club you'll get "CDHS" then the rank (same problem)

3) You can deal with all of the ranks less than or equal to 10 in one go:


public string toString(byte suit, byte rank) {
StringBuffer output = new StringBuffer(0);

switch (suit) {
case 0:
output.append("C");
break;
case 1:
output.append("D");
break;
case 2:
output.append("H");
break;
case 3:
output.append("S");
break;
default:
;
}

switch (rank) {
case 2:
case 3:
<repeat for 4,5,6,7,8,9>
case 10:
output.append((new Integer(rank)).toString());
break;
case 11:
output.append("J");
break;
etcetcetc.....
default:

return output.toString();
}


Edit to add: also note Class names are capitalised to string is an error. It must be String. You can check the syntax yourself: compile it!

mmmdreg
Mar 11, 2007, 09:27 AM
Thanks so much mate,

You've always been an awesome help on these forums =)

On a side note, I just noticed we joined mere months apart..

lazydog
Mar 11, 2007, 10:59 AM
Hi, I hope you don't mind me commenting on your shuffle code but I noticed a couple of things that might be of help.

The first thing is:-

Card theCard;
theCard = new Card();

For your code to compile theCard needs to be initialised with a value which is exactly what you do. However in this particular case initialising it with a constructor is a bit wasteful since you never use the value from new Car();. It would be sufficient I think to do this instead:-


Card theCard = null ;


Next, this line has a bug which might drive you mad trying to find!


while (hasBeenUsed = true)
{

}


hint, ==

Also, I think you might have trouble compiling the line for choosing a random card. The problem is random() returns a double which floor() then converts to a long. To index your card array you need an int. The fix for this is to make the inner value of your calcualtion a float and then use round(). This return an int for indexing an array. But if you do this you'll jave to adjust the value of 'j' because you are rounding the value down.

Lastly, the way you shuffle the pack is okay, but the algorithm isn't ideal Each time a random card is chosen, there is one less card in the pack to choose from and so the chances of finding another card is less. The net result is that the number of times the inner while loop will run will increase with each card. A better way perhaps would be for each card, 0…51, pick another card at random and swap them around. This way you know the shuffle routine will finish in a fixed number of iterations.


Yup, I haven't been on the forum long but I've noticed that Robbie is v. helpful!

ben

EDIT: I've noticed you have a j-- so ignore what I said about shuffling!

MarkCollette
Mar 11, 2007, 10:59 AM
Typically toString doesn't take arguments. So instead of:
public class Card {
public String toString(byte suit, byte rank) {
switch(suit) {
...
}
switch(rank) {
...
}
}
public void doSomething() {
toString(this.suit,this.rank);
}
}

You should instead do:
public class Card {
public String toString() {
switch(this.suit) {
...
}
switch(this.rank) {
...
}
}
public void doSomething() {
toString();
}
}

Not saying that you need to use "this.suit" instead of "suit", I was just doing that to illustrate a point.

Have you covered arrays?


public String toString(byte suit, byte rank) {
final String[] SUITS = new String[] {
"C", "D", "H", "S"
};
final String[] RANKS = new String[] {
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"
};

StringBuffer output = new StringBuffer(8);
output.append( SUITS[suit] );
output.append( RANKS[rank] );
return output.toString();
}

dcr
Mar 11, 2007, 01:50 PM
Here's some help, since you've basically just asked us to do your assignment...

Go to your instructor's office hours:
http://online.mq.edu.au/pub/COMP229/staff.html

other interesting reading:
http://www.comp.mq.edu.au/undergrad/policies/plagiarism_policy.htm

mmmdreg
Mar 11, 2007, 03:42 PM
Here's some help, since you've basically just asked us to do your assignment...

Go to your instructor's office hours:
http://online.mq.edu.au/pub/COMP229/staff.html

other interesting reading:
http://www.comp.mq.edu.au/undergrad/policies/plagiarism_policy.htm

Yeah thanks for that. If you searched properly you'd realise that it's not an assignment.. just a tutorial to help me learn so I can do the assignments later.. But in any case, you'll notice that I did the work as I saw fit, and asked for tips as that was the limit of my knowledge.. But I'm not interested in launching into an argument so let's end that stream of converstion right here.. period. edit: just noticed you have a habit of referring students to their lecturers as well..

Mark and lazydog, thanks for the information you contributed =)

robbieduncan
Mar 11, 2007, 03:43 PM
Thanks so much mate,

You've always been an awesome help on these forums =)

On a side note, I just noticed we joined mere months apart..

No worries! I notice others have kindly picked up where I left off. And I assumed that you'd been around longer: you've been here ever since I remember :D

Just remember: programming should be something you enjoy (at least as an intellectual challenge). If it stops being that give it up as there will be others who are still enjoying it who will take up your place...