Formatting
Your code is hard to read when formatted like this:
static boolean isSub(String str, String sub){
int j=0;
int x=str.length();
int y=sub.length();
for(int i=0;i<x && j<y;i++){
if(str.charAt(i)==sub.charAt(j)) j++;
}
return (j==y);
}
Any IDE can automatically reformat this nicely as:
static boolean isSub(String str, String sub) {
int j = 0;
int x = str.length();
int y = sub.length();
for (int i = 0; i < x && j < y; i++) {
if (str.charAt(i) == sub.charAt(j)) {
j++;
}
}
return (j == y);
}
Naming
The single-letter variables x
and y
are not easy to follow.
Consider this alternative:
static boolean isSub(String source, String sub) {
int subIndex = 0;
int sourceLen = source.length();
int subLen = sub.length();
for (int i = 0; i < sourceLen && subIndex < subLen; i++) {
if (source.charAt(i) == sub.charAt(subIndex)) {
subIndex++;
}
}
return subIndex == subLen;
}
Efficiency
A minor optimization is to first check if the source string is longer than the sub:
static boolean isSub(String source, String sub) {
int sourceLen = source.length();
int subLen = sub.length();
if (sourceLen < subLen) {
return false;
}
int subIndex = 0;
for (int i = 0; i < sourceLen && subIndex < subLen; i++) {
if (source.charAt(i) == sub.charAt(subIndex)) {
subIndex++;
}
}
return subIndex == subLen;
}
Considering that the same source string is reused across multiple isSub
tests, there's an opportunity to build some sort of index from the source string.
For example, as a simple optimization, you could build a hash set of characters, so that you can check with an \$O(1)\$ operation if a character in sub cannot appear in the source and return false immediately.
A more advanced index would also consider the search position in the source string. So for example if the source string is "haystackkkkkkkkkk" and the sub is "aaa", then after seeing the 2nd "a", the index can tell you that there will be no more "a" and you can return false immediately.
Scanner
No need to wrap System.in
in a InputStreamReader
, this works just as well:
Scanner scanner = new Scanner(System.in);