This originally was a problem I ran into at work, but is now something I’m just trying to solve for my own curiosity.
I want to find out if int ‘a’ contains the int ‘b’ in the most efficient way possible. I wrote some code, but it seems no matter what I write, parsing it into a string and then using indexOf is twice as fast as doing it mathematically.
Memory is not an issue (within reason), just sheer processing speed.
This is the code I have written to do it mathematically:
private static int[] exponents = {10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; private static boolean findMatch(int a, int b) { if (b > a) return false; if (a == b) return true; int needleLength = getLength(b); int exponent = exponents[needleLength]; int subNum; while (a >= 1) { subNum = a % exponent; if (subNum == b) return true; a /= 10; } return false; } private static int getLength(int b) { int len = 0; while (b >= 1) { len++; b /= 10; } return len; }
Here’s the string method I’m using, which seems to trump the mathematical method above:
private static boolean findStringMatch(int a, int b) { return String.valueOf(a).indexOf(String.valueOf(b)) != -1; }
So although this isn’t really required for me to complete my work, I was just wondering if anyone could think of any way to further optimize my way of doing it mathematically, or an entirely new approach altogether. Again memory is no problem, I am just shooting for sheer speed.
I’m really interested to see or hear anything anyone has to offer on this.
EDIT: When I say contains I mean can be anywhere, so for example, findMatch(1234, 23) == true
EDIT: For everyone saying that this crap is unreadable and unnecessary: you’re missing the point. The point was to get to geek out on an interesting problem, not come up with an answer to be used in production code.
This is along Kibbee’s line, but I got a little intrigued by this before he posted and worked this out:
Since 300 characters is far too little to make an argument in, I’m editing this main post to respond to Pyrolistical.
Unlike the OP, I wasn’t that surprised that a native compiled indexOf was faster than Java code with primitives. So my goal was not to find something I thought was faster than a native method called zillions of times all over Java code.
The OP made it clear that this was not a production problem and more along the lines of an idle curiosity, so my answer solves that curiosity. My guess was that speed was an issue, when he was trying to solve it in production, but as an idle curiosity, ‘This method will be called millions and millions of times’ no longer applies. As he had to explain to one poster, it’s no longer pursued as production code, so the complexity no longer matters.
Plus it provides the only implementation on the page that manages to find the ‘123’ in ‘551241238’, so unless correctness is an extraneous concern, it provides that. Also the solution space of ‘an algorithm that solves the problem mathematically using Java primitives but beats optimized native code’ might be EMPTY.
Plus, it’s not clear from your comment whether or not you compared apples to apples. The functional spec is f( int, int )-> boolean, not f( String, String )-> boolean (which is kind of the domain of
indexOf) . So unless you tested something like this (which could still beat mine, and I wouldn’t be awfully surprised.) the additional overhead might eat up some of that excess 40%.It does the same basic steps. log10( a ) encoding + log10( b ) encoding + actually finding the match, which is as well O(n) where n is the largest logarithm.