Hints and Tips You can use and to compare char values whic
Hints and Tips
You can use < and > to compare char values, which have relatively straightforward meanings for letters and numbers. You can look up an ASCII table (just use Google) if you want to see what the underlying values are.
Remember to use .equals to compare String values, not ==.
Double-check indices and documentation when using charAt() and substring() on Strings, to avoid out-of-bounds indexing.
Please complete the code below. Thanks
interface StringMatcher {
public int match(String s, int start);
}
class SCM implements StringMatcher {
private final char c;
public SCM(char c) {
this.c = c;
}
public int match(String s, int start) {
if(s.length() <= start) { return -1; }
if(s.charAt(start) == this.c) { return start + 1; }
return -1;
}
}
class RCM implements StringMatcher {
private final char from, to;
public RCM(char from, char to) { this.from = from; this.to = to; }
public int match(String s, int start) {
return -1;
}
}
class STR implements StringMatcher {
private final String str;
public STR(String str) { this.str = str; }
public int match(String s, int start) {
return -1;
}
}
class SEQ implements StringMatcher {
private final StringMatcher first, second;
public SEQ(StringMatcher first, StringMatcher second) {
this.first = first;
this.second = second;
}
public int match(String s, int start) {
return -1;
}
}
public class Main {
public static void main(String[] args) {
StringMatcher ti = new STR(\"testinput\");
StringMatcher oneToSix = new RCM(\'1\', \'6\');
StringMatcher dotTxt = new STR(\".txt\");
// Write some small printout tests of these individually
StringMatcher s = new SEQ(ti, new SEQ(oneToSix, dotTxt));
int m = s.match(\"testinput1.txt\", 0);
System.out.println(m);
// You build one that matches the account pattern.
}
}
Solution
Solution:
PFB the complete solution with full explanation as multi-line comments just above the implementation of match() for all the respective classes. [ Explanation over the implementation gives a clear idea about the context rather than explaining separately ]
interface StringMatcher {
public int match(String s, int start);
}
class SCM implements StringMatcher {
private final char c;
public SCM(char c) {
this.c = c;
}
public int match(String s, int start) {
if(s.length() <= start) { return -1; }
if(s.charAt(start) == this.c) { return start + 1; }
return -1;
}
}
class RCM implements StringMatcher {
private final char from, to;
public RCM(char from, char to) { this.from = from; this.to = to; }
/*EXPLANATION:
* Here we are checking by the help of \'>\' & \'<\' operators directly
* and if the character at the given start matches the condition
* we pass the next index value
*/
public int match(String s, int start) {
if(s.length() <= start) { return -1; }
if(s.charAt(start) >=this.from && s.charAt(start) <= this.to) { return start + 1; }
return -1;
}
}
class STR implements StringMatcher {
private final String str;
public STR(String str) { this.str = str; }
/*EXPLANATION:
* Here the string s is sliced from the \'start\' up to the length of the \'final String str\'
* used while creating the object. This will provide us our substring to match,
* and if the sliced string/sub string matches the str
* we pass the next index value i.e. index where our sub string ends i.e. start + lenght of str
*/
public int match(String s, int start) {
if(s.length() <= start) { return -1; }
if(s.substring(start, start+str.length()).equals(str)){ return start+str.length();}
return -1;
}
}
class SEQ implements StringMatcher {
private final StringMatcher first, second;
public SEQ(StringMatcher first, StringMatcher second) {
this.first = first;
this.second = second;
}
/*EXPLANATION:
* Here first the string s is passed to the match() of the first StringMatcher object i.e. \'first\',
* if it returns a valid index, then the returned index is passed to the match() for the second StringMatcher i.e.\'second\'
* as \'start\' along with the string. Reason being: if the first.match() able to match then it will return the next index
* value which is the start for the next StringMatcher
*/
public int match(String s, int start) {
if(s.length() <= start) { return -1; }
int firstMatchValue = this.first.match(s, start);
int secondMatchValue = 0;
if( firstMatchValue != -1){
secondMatchValue = this.second.match(s, firstMatchValue);
if( secondMatchValue != -1){
return secondMatchValue;
}else{
return -1;
}
}else{
return -1;
}
}
}
public class Main {
public static void main(String[] args) {
StringMatcher ti = new STR(\"testinput\");
StringMatcher oneToSix = new RCM(\'1\', \'6\');
StringMatcher dotTxt = new STR(\".txt\");
// Write some small printout tests of these individually
StringMatcher s1 = new SEQ(ti, new SEQ(oneToSix, dotTxt));
int m = s1.match(\"testinput1.txt\", 0);
System.out.println(m);
StringMatcher s2 = new SEQ(new STR(\"cs11w\"), new RCM(\'b\', \'c\'));
System.out.println(s2.match(\"cs11wb\", 0));
System.out.println(s2.match(\"cs11wZ\", 0));
System.out.println(s2.match(\"stuff_cs11wb_morestuff\", 6));
// You build one that matches the account pattern.
}
}



