I have to convert 2D into 2 of Diamonds. I can not use if statements.
If the person enters 10C then it prints out 10 of clubs.

I've contemplated trying taking the string length, taking the position end of the string and using the D,C,S,H in the switch statements

But if the user enters AH, it must print out Ace of Hearts. the A is not a numerical value to be stored as an INT, making it hard

So far I've gotten the input.
I don't believe enums would be a smart move here, or even how to implement them.

My thought would be to take the length of string, take the last position put it into the first switch statement, concatenate with (0,(1 - length))

My only question would be how to determine if it was an INT or a CHAR.

position = input.length() - 1;
		
		suit = input.charAt(position);

this allowed me to get the suit.

Now I need to get the first part.

I'm thinking isLetterorisDigit.

any recommendations?

Ur idea was good. I thought in this situations you can fix some of the position to determine whether it is an int or char... Because it can't possible to determine by using length of the string.

well the first part of the string at position 0 (most times it will be at position 0) can be seen as either A,K,Q,J and a switch statement can be used there, but when that doesn't work it should send out the character in the default case.

Just my thoughts.

i'm having trouble converting it over.

Well. U r used every thing in swithmode right. So write some default case in swithc that is exit when it should send out the characters.

> I don't believe enums would be a smart move here

Enums are a natural fit here IMO. It's a different thing if you are confused on how to get things rolling with enums. One possible OO solution would be:

  • Create a enum CardSuit (e.g. SPADE, HEART, DIAMOND, CLUB)
  • Create an enum CardRank (e.g. ACE, KING, TWO, THREE etc)
  • Create an interface CardParser having a method Card parseCard(String representation)
  • Create a concrete class AbbreviatedNameCardParser which parses the passed in String and create a Card instance out of it
  • Create a Card class which has two members; suit and rank both of enum types. Add a toString method which would print out the entire card name based on the suit and rank.

Edited 6 Years Ago by ~s.o.s~: n/a

I agree with ~s.o.s~, except why define a CardParser interface? Why not just have a CardParser class that's smart enough to parse any sensible representation? If you onlyhave one class, then why bother with the interface. If you have 2 or mnore pareser classes how will you code the logic for which one to use?

You might have multiple ways of representing cards; for e.g. 4H or IV Hearts or 4 Hearts or 4 1 (where 1 is a code for hearts). Given the multiple ways in which a single card can be expressed, why not have a contract defined which deals with parsing a card based on the representation? In the absence of a CardParser interface, the parser class would contain a lot of IF's to check for the format which the user has used and then parse the Card accordingly, something which can be elegantly dealt with by polymorphism. A generic parser class would be something of a "god" class is the sense that it would need to "know" about "all" the possible representations.

Also, it would violate the basic principle of "cohesion". Any new representation added or any change in existing one would require a change in the method which is already dealing with other representations thereby increasing the possibility of a change impact. But that's just me, YMMV. :-)

I don't want to hijack this thread, so just a quick (final) comment - even with multiple parsing classes, when dealing with a user input you will still need to know which class to use to parse it, so that just moves the "god" code to a less generic place. However, I do agreee with your second para re cohesion - good point. Maybe it would be better to use a parser that also takes a format definiton string, like SimpleDateFormat?
Final comment for TheComputerGuy - if ever there was an open-and-shut case for using enums it's CardRank and Suit. Right now I can't think of a single better example of when to use enums - even the Planets example used by Sun in the original documentation looks shaky now that Pluto has ceased to be a planet!

My only question is that I don't need 2-10 to reprint in a word format,
If the user enters 2D = 2 of Diamonds
If the user enters JD = Jack of Diamonds

I would figure that it would an enum would not be needed.

sos is right here in principle, and you'd probably do well to try to implement it as he suggests. However, I'm guessing this is a first-year class assignment, and maybe you want to keep it simple. Okay, use two switch statements, one on input.charAt(0) and the other on input.charAt(input.length()-1)


You know for sure that the last character in the input string is one of four (ignoring case). You know that character 0 is a digit from 1-9 or one of five letters. There is no 1 of spades, so if character 0 is 1, you can return "Ten of " - your professor, hopefully, will dock you for not doing error checking, but we're doing this simple.

Ok, so you have the following

String.charAt(string.length() - 1)

This about this logically, you know that the LAST character is always the suit, and you know the length of the string, this cannot get any easier :).

Look at it like this:

0 1 - INDEX
2 D - STRING

This is how I break down strings. String.Length() would return 2 here correct, 2 - 1 = 1, which is the index of the suit's location (ALWAYS) as along as the suit is 1 char, that is the index, length() - 1. Strings have another method in their API, which I believe is subString(), it takes 2 params I believe beginning index and starting index. Keyword here, INDEX, do NOT use counting and say that 2 is at index 1, it is WRONG, 2 is at index 0 right? The thing about substring, it takes the char at the beginning index, UP to the chars at the last index, excluding the last index, at least that is how I recall my experience with it, so really, you only need length() - 1.

String.subString(0, length() - 1); // Notice 0 is the beginning

If this code is wrong, the solution will obviously then be length() - 2, but that is 0, and a subString from 0 to 0 is nothing, so I am almost 100% sure that the above code would work. Think about your strings, and like Norm1R(not in this thread but usually) always suggests, WRITE your logic down, create a flow chart even, break stuff down BEFORE you code :). Good luck ;)

WR - Your substring trick does get you the correct substring. However, to just get through most of the test cases, it's simplest to just look at first and last characters. This passes 2C, 7H, AS, KD, and 10C. It'll fail to reject bad input (11C will come out as Ten of Clubs), so it's not a very good solution - but you can catch that easily enough by switching on input.charAt(1) if chartAt(0) == '1'. Two cases to consider if charAt(0)=='1'. '0' returns "Ten" and anything else (default) returns "Bad Input", since only a zero can follow a '1' in this problem.

If you use the substring method, you've still got to go into the substring so you can get a char to switch on (remember, no ifs allowed) and the problem pretty much breaks down to the same as this. Mine's simpler. :)


(although The Computer Guy should probably take the time to try to understand how the substring works, because there's a lot of cases where substrings are much better than getting individual chars out of a string)

Edited 6 Years Ago by jon.kiparsky: n/a

The charAt(1) and charAt(0) works just fine, and if the Char at 0 is 0, then it is 10 also makes sense too, but I was just saying that these substrings work for ANY case that he wants, all his cases seem to have a common one digit ending, but the beginning could be ONE, 1, or codes, anything. Your solution is great too , I was just offering methods. Also, you dont NEED ifs on a String,

You should know that IFS and Strings do not get along very well:

String s = "Hello";
if(s == "Hello) { System.out.println(s); }

That code wouldn't print anything, you can use Strings and equals, as well as compareTo:

String s = "Hello";
if(s.compareTo("Hello") == 0)
{
   if(s.equals("Hello"){ System.out.println(s); }
}

That will print s, you dont NEED s, but the problem is Strings dont get along with switch too, that is really the only problem lol :D

> That code wouldn't print anything, you can use Strings and equals

That code will always print "Hello" since both s and the literal "Hello" would refer to the same interned string.

Well see I can figure out how to get the position 0, my only issue is how to convert using the ASCII code.

User enters: JD
Prints out: Jack of Diamonds
User enters: 4D
Prints out: 4 of Diamonds

x.substring(0) can't convert to an INT if it's a Char.

that's where I'm stuck.

So do you need String to char, or char to int? If it is int, then I am sure you can just use Integer.parseInt(arg); :)

Well I can't take a CharAT if it's a 5 for example. The cards can be 2-10, or J,Q,K,A

char values returned by charAt() are convertable to ints and can be used in a switch statement. With an ugly nested bunch of switch statements you can parse the card's value.
Can you use methods for example to get the suit name?

Nothing ugly or nested needed. You switch on input.charAt(0) for the card, and on input.charAt(input.length()) for the suit. If you want, you add one nested switch or ternary to deal with the case of input[0]='1' - you'd use an if, except it's not allowed. (you could use a while, I guess, if you wanted to be goofy - there's all sorts of ways to if without an if)

Computer Guy - what you don't seem to be getting is that charAt gets you a char, which includes the digits, and which you can use in a switch statement. Converting to an int causes you a bunch of mess, and I can't see any gain in it.

This question has already been answered. Start a new discussion instead.