http://codereview.stackexchange.com/questions/83601/finding-the-mth-to-last-element
If I'm interpreting the definition right, the input contains single letters, all delimited by precisely one space character, and at the end of the line is a single digit (1 to 9). This is the way it seems to make the most sense. I will assume this interpretation in my answer.
First, to make the solution testable,
I'd extract the main logic to a function that takes a line and returns the mth-to-last character or 0 (that's different from '0'
, mind you) if m
is out of range.
static char retrieveAndPrintMToLast0(String line) {
String sanitized = line.replaceAll("\\s", "");
if (!sanitized.isEmpty()) {
int limit = sanitized.length() - 1;
int targetIndex = Character.getNumericValue(sanitized.charAt(limit));
sanitized = sanitized.substring(0, limit);
if (targetIndex <= limit) {
return sanitized.charAt(limit - targetIndex);
}
}
return 0;
}
Now it's possible to add some unit tests to verify the behavior:
private char getMthToLast(String line) {
return MToLast.retrieveAndPrintMToLast(line);
}
@Test
public void test_hello_1() {
assertEquals('o', getMthToLast("h e l l o 1"));
}
@Test
public void test_hello_5() {
assertEquals('h', getMthToLast("h e l l o 5"));
}
@Test
public void test_hello_9() {
assertEquals(0, getMthToLast("h e l l o 9"));
}
With the unit tests covering my back, I can boldly go and refactor the original code:
- It seems it should be possible to calculate the right position without removing the spaces
- Removing the spaces doesn't look great in general: it's an extra
$O(N)$ operation (though I do realize we're talking about aN
that's maximum 9, but still...) - Removing the spaces would clearly not have a place in a little bit extended problem where there may be multiple character sequences, not just single letters
- Removing the spaces doesn't look great in general: it's an extra
- The
sanitized.isEmpty
check seems redundant, as that should be illegal input in the challenge
The modified implementation incorporating these ideas:
static char retrieveAndPrintMToLast(String line) {
int limit = (line.length() - 1) / 2;
int targetIndex = line.charAt(line.lastIndexOf(' ') + 1) - '0';
if (targetIndex <= limit) {
return line.charAt(line.length() - 2 * targetIndex - 1);
}
return 0;
}