I am trying to solve the following via recursion: In a phone we have each digit mapped to a number.
Example:
1 2(ABC) 3(DEF)
4(GHI) 5(JKL) 6(MNO)
7(PRS) 8(TUV) 9(XYZ)
* 0 #
I need to print out all the possible sequences of a phone number (example: 637-8687
).
I did the following that seems to solve it:
static Map<String, String> digits;
static{
digits = new HashMap<String, String>();
digits.put("2", "ABC");
digits.put("3", "DEF");
digits.put("4", "GHI");
digits.put("5", "JKL");
digits.put("6", "MNO");
digits.put("7", "PRS");
digits.put("8", "TUV");
digits.put("9", "XYZ");
}
public static void printSequences(String phoneNumber, Map<String, String> associations){
if(phoneNumber == null || phoneNumber.isEmpty()){
throw new IllegalArgumentException();
}
if(associations == null || associations.isEmpty()){
throw new IllegalArgumentException();
}
String[] letters = new String[phoneNumber.length()];
for(int i = 0; i < phoneNumber.length(); i++){
String seq = associations.get(phoneNumber.charAt(i) + "");
if(seq == null)continue;
letters[i] = seq;
}
printSequences(letters, 0, letters.length, "");
}
private static void printSequences(String[] letters, int start, int end, String prefix) {
if(start == end){
System.out.println(prefix);
return;
}
String sequence = letters[start];
if(sequence == null)
return;
for(int i = 0; i < sequence.length(); i++){
printSequences(letters, start + 1, end, prefix + sequence.charAt(i));
}
}
The String[] letters
has all the relevant digits (extracted from a Map
). In this case it is [MNO, DEF, PRS, TUV, MNO, TUV, PRS]
for phone 6378687
.
This code seems to work but does not for 637-8687
. For 637-8687
it actually prints nothing at all!
I am trying to practice recursion, so could you please help me out with this one? Also, is recursion actually the best approach on such a problem?
1 Answer 1
Here are some comments from my side:
The
end
parameter is unnecessary. You can just test forstart >= letters.length
instead. Also, you might want to rename start.It might make sense to wrap your algorithm in a callable method such as
private void printSequences(String[] letters)
, which just kicks off the recursion by callingprintSequences(letters, 0, "")
.As to your bug, it depends on how exactly you are calling the method above (what is start and end).
Your test for
letters[start] == null
does not seems necessary if theletters
array is well-behaved (i.e., does not containnull
).Recursion is a decent way to solve this problem.
Your bug comes from the fact that when you process "-" as a digit, you generate
null
inletters
. When processingletters
, you don't call your function recursively but just return. That way, nothing is ever printed, which explains the behavior you describe. The proper way to handle that case would be to call the method recursively without appending anything to the prefix (or to make sure there are no null entries inletters
, which I believe is the better way, see point 7).I would use a
List<String>
for letters. That way you don't end up withnull
entries.Your
IllegalArgumentException
should describe the problem. For instance, it could say "Got illegal phoneNumber".Your
digits
map should map characters to strings, not strings to strings. That way you don't have to coerce the character into string withphoneNumber.charAt(i) + ""
.
-
\$\begingroup\$ Is recursion the best option for this problem? \$\endgroup\$user384706– user3847062012年12月25日 19:06:34 +00:00Commented Dec 25, 2012 at 19:06
-
\$\begingroup\$ Yes, recursion is IMO a decent way to solve this. \$\endgroup\$Dino– Dino2012年12月25日 19:09:28 +00:00Commented Dec 25, 2012 at 19:09
-
\$\begingroup\$ Posted complete code \$\endgroup\$user384706– user3847062012年12月25日 19:25:45 +00:00Commented Dec 25, 2012 at 19:25
-
\$\begingroup\$ Updated my answer, found your bug. \$\endgroup\$Dino– Dino2012年12月25日 19:58:42 +00:00Commented Dec 25, 2012 at 19:58
Q
on7
andW
on9
! \$\endgroup\$