Reputation: 356
public boolean typeMatch(char c1, char c2) {
if (c1 == '{' || c1 == '}') {
return (c2 == '{' || c2 == '}');
} else if (c1 == '(' || c1 == ')') {
return (c2 == '(' || c2 == ')');
} else if (c1 == '[' || c1 == ']') {
return (c2 == '[' || c2 == ']');
} else {
return false;
}
}
I have the above code in my program and I was wondering if there is a better way to implement this method without using a lot of if/else statements.
Upvotes: 2
Views: 229
Reputation: 234857
Elliott's solution is going to be much better than mine, but I thought I'd have some fun.
private static final Map<Character, Set<Character>> pairMap;
public boolean typeMatch(char c1, char c2) {
Set<Character> s = pairMap.get(c1);
return s != null && s.contains(c2);
}
static {
pairMap = new HashMap<>();
register(makeSet('{', '}'));
register(makeSet('(', ')'));
register(makeSet('[', ']'));
}
private static Set<Character> makeSet(char... chars) {
Set<Character> s = new HashSet<>(chars.length, 1.0f);
for (char c : chars) {
s.add(c);
}
return s;
}
private static void register(Set<Character> s) {
for (Character c : s) {
pairMap.put(c, s);
}
}
The memory requirements for this solution are gross. The only thing it has to recommend it is that it will scale better in terms of execution time if you need to handle a very large number of character equivalence classes instead of the three pairs. Plus it can be generalized to handle other types besides char
(or, to be accurate, Character
).
Upvotes: 3
Reputation: 30088
There's already an accepted answer here, and it's a good one, but it's very specific to the problem at hand.
For folks who got here by searching for a more generic solution, I'd like to offer my favorite pattern for doing away with if/else chains:
boolean result = false;
do {
if(condition1) {
result = true;
break;
}
if(condition2) {
break;
}
// etc.
} while(false);
return result;
This, of course, is generalizable to any return type.
Upvotes: 0
Reputation: 201537
You could extract your symbol pairs (open and close) into a char[][]
, and then loop through that array to test for matches. Something like,
static final char[][] pairs = { { '{', '}' }, { '(', ')' }, { '[', ']' } };
public boolean typeMatch(char c1, char c2) {
for (char[] pair : pairs) {
if (c1 == pair[0] || c1 == pair[1]) {
return c2 == pair[0] || c2 == pair[1];
}
}
return false;
}
Alternatively, it may be easier to read1 if we implement that with String
(s) and String.indexOf(int)
2. Something like,
public boolean typeMatch(char c1, char c2) {
String[] pairs = { "{}", "()", "[]" };
for (String pair : pairs) {
if (pair.indexOf(c1) != -1) {
return pair.indexOf(c2) != -1;
}
}
return false;
}
1And that's never a bad thing.
2The linked Javadoc says, in part, In either case, if no such character occurs in this string, then -1
is returned.
Upvotes: 5
Reputation: 31699
private static final String PAIRS = "{}()[]";
public boolean typeMatch(char c1, char c2) {
int indexOfC1 = PAIRS.indexOf(c1);
int indexOfC2 = PAIRS.indexOf(c2);
return indexOfC1 >= 0 && indexOfC2 >= 0 && (indexOfC1 / 2 == indexOfC2 / 2);
}
A bit on the tricky side, perhaps...
Upvotes: 1
Reputation: 11440
Not the most readable but I was having some fun with trying to do this with bit wise operators and I figured I would post it
public boolean typeMatch(char c1, char c2) {
int xor = c1 ^ c2;
if(xor == 6) { // 2 apart
return c1 == '{' || c1 == '}' || c1 == '[' || c1 == ']';
} else if(xor == 1) { // 1 apart
return c1 == '(' || c1 == ')';
} else if(xor == 0) { // same
return c1 == '(' || c1 == ')' ||
c1 == '{' || c1 == '}' || c1 == '[' || c1 == ']';
}
return false;
}
It should be quite fast at least...
Upvotes: 0