How should I implement a substring function in java? - java

Consider you have been told to implement a kind of the java String.substring method.
The signature of the method is as follows:
public static boolean isSubstring(String i_StringForSearch, String i_SubStringToFind)
Here is my solution, but I feel it's still not the best elegant solution I could have.(Many canonical if else's)
What do you think? Would you do it in another way?
public static boolean isSubstring(String i_StringForSearch, String i_SubStringToFind)
{
int strForSearchIndex = 0;
int subStrToFindIndex = 0;
boolean endOfStringToSearch = false;
boolean foundSubString = false;
boolean isThereASequenceOfMatching = false;
while(!endOfStringToSearch && !foundSubString)
{
if(strForSearchIndex == i_StringForSearch.length())
{
endOfStringToSearch = true;
}
else if(i_StringForSearch.charAt(strForSearchIndex) == i_SubStringToFind.charAt(subStrToFindIndex))
{
isThereASequenceOfMatching = true;
if(subStrToFindIndex == i_SubStringToFind.length() -1 )
{
foundSubString = true;
}
subStrToFindIndex++;
strForSearchIndex++;
}
else if(i_StringForSearch.charAt(strForSearchIndex) != i_SubStringToFind.charAt(subStrToFindIndex))
{
if(isThereASequenceOfMatching)
{
subStrToFindIndex = 0;
isThereASequenceOfMatching = false;
}
strForSearchIndex++;
}
}
return foundSubString;
}

Look up the Boyer-Moore and Knuth-Morris-Pratt algorithms. In tests many years ago I found BM to be slightly faster.

public static boolean isSubstring(final String i_StringForSearch, final String i_SubStringToFind) {
int j = 0;
for (int i = 0; i < i_StringForSearch.length(); i++) {
if (i_StringForSearch.charAt(i) == i_SubStringToFind.charAt(j)) {
j++;
if (j == i_SubStringToFind.length()) {
return true;
}
}
}
return false;
}

Related

How to make this method only have 1 return statement instead of 2

My professor has a rule that "there should be no more than one return statement in any method". Now I've written a pretty simple method in my first project. How would I make this have only return statement without ruining functionality?
public static int find(int correctNumber, int numArray[], int lastNum) {
for (int i = 0; i < lastNum; i++) {
if (numArray[i] == correctNumber) {
return i;
}
}
return -1;
Use another variable to assign the value and then apply a break within the if clause to exit the loop.
public static int find(int correctNumber, int numArray[], int lastNum) {
int returnValue = -1;
for (int i = 0; i < lastNum; i++) {
if (numArray[i] == correctNumber) {
returnValue = i;
break;
}
}
return returnValue;
}
And you will find that many professional programmers with lots of experience find it perfectly acceptable to use multiple return statements.
For example: This is the equals override from the JDK HashMap source. That code was written by four internationally recognized computer scientists, three of which have their PhD's.
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
like this?
public static int find(int correctNumber, int numArray[], int lastNum) {
int correctIndex = -1;
for (int i = 0; i < lastNum; i++) {
if (numArray[i] == correctNumber) {
correctIndex = i;
}
}
return correctIndex;
you can try this:
public static int find(int correctNumber, int numArray[], int lastNum) {
int temNum = -1;
for (int i = 0; i < lastNum; i++) {
if (numArray[i] == correctNumber) {
temNum = i;
break;
}
}
return temNum;
}
public static int find(int correctNumber, int numArray[], int lastNum) {
int i = lastNum - 1;
while (i >= 0 && numArray[i] != correctNumber) {
i--;
}
return i;
}
This differs slightly from your code in that, if the 'correctNumber' occurs twice, it will find the higher-index instance.
It could be expressed with a for-loop but I find I prefer the while-loop.
public static int find(int correctNumber, int numArray[], int lastNum) {
int i;
for (i = lastNum-1; i >= 0 && numArray[i] != correctNumber; i--) {
}
return i;
}

Monotonic Functions in Java of Comparables

I am trying to implement an algorithm that checks if an array of comparable elements is increasing or decreasing. So far I have written this method:
class Solution {
public boolean isMonotonic(int[] A) {
int store = 0;
for (int i = 0; i < A.length - 1; ++i) {
int c = Integer.compare(A[i], A[i+1]);
if (c != 0) {
if (c != store && store != 0)
return false;
store = c;
}
}
return true;
}
}
I changed the method signature, by passing a generic method of comparables, but I'm struggling to implement the compareTo method. I am probably using the bounded generics wrong, but I'm not too sure?
My attempt:
public boolean Test(T[] n)
{
if (n.length < 3)
return true;
int direction = n[0].compareTo(n[1]);
for (int i = 1; i < n.length-1; i++){
int step = n[i].compareTo(n[i+1]);
if (step == 0)
continue;
if (direction == 0)
direction = step;
else if ( sdtep < 0 && direction > 0
|| step > 0 && direction < 0)
return false;
}
return true;
}
In order to make your method take a generic argument, change its header:
public static <T extends Comparable<? super T>> boolean isMonotonic(T[] A)
You can then compare items of the array using the Comparable::compareTo method:
int c = A[i].compareTo(A[i+1]);
Monotone function:
public static boolean isMonotone(int[] a) {
boolean monotone = true;
int i=0;
while(a[i]==a[i+1]) {
i++;
}
if(a[i]>a[i+1]) {
for(int j=0;j<(a.length-1);j++) {
if(!(a[j]>=a[j+1])){
monotone=false;
}
}
}
if(a[i]<a[i+1]) {
for(int j=0;j<(a.length-1);j++) {
if(!(a[j]<=a[j+1])){
monotone=false;
}
}
}
return monotone;
}
Strictly monotone function:
public static boolean isMonotone(int[] a) {
boolean monotone = true;
if(a[0]>a[1]) {
for(int i=0;i<(a.length-1);i++) {
if(!(a[i]>a[i+1])){
monotone=false;
}
}
}
if(a[0]<a[1]) {
for(int i=0;i<(a.length-1);i++) {
if(!(a[i]<a[i+1])){
monotone=false;
}
}
}
if(a[0]==a[1]) return false;
return monotone;
}

Java .contains cannot be used with charAt [duplicate]

This question already has answers here:
How can I check if a single character appears in a string?
(16 answers)
Closed 5 years ago.
java: incompatible types: char cannot be converted to java.lang.CharSequence
boolean checkParentheses(String str) {
Deque<Character> stack = new ArrayDeque<>();
String k = "({[";
String s = ")]}";
for (int i = 0; i < str.length();i++ ) {
if (k.contains(str.charAt(i))) {
stack.push(str.charAt(i));
} else if (s.contains(str.charAt(i))) {
if (matching(stack.peek()) == str.charAt(i)) {
return true;
}
} else {
return false;
}
}
}
what should I use instead of contains?
indexOf with -1.
Something along these lines:
boolean checkParentheses(String str) {
Deque<Character> stack = new ArrayDeque<>();
String k = "({[";
String s = ")]}";
for (int i = 0; i < str.length();i++ ) {
if (k.indexOf(str.charAt(i)) > -1) {
stack.push(str.charAt(i));
} else if (s.indexOf(str.charAt(i)) > -1) {
if (matching(stack.peek()) == str.charAt(i)) {
return true;
}
} else {
return false;
}
}
return false;
}
You could also use contains creating a new String. But that option is not that good (more ineficcient).
2nd option:
boolean checkParentheses(String str) {
Deque<Character> stack = new ArrayDeque<>();
String k = "({[";
String s = ")]}";
for (int i = 0; i < str.length(); i++) {
if (k.contains(String.valueOf(str.charAt(i)))) {
stack.push(str.charAt(i));
} else if (s.contains(String.valueOf(str.charAt(i)))) {
if (matching(stack.peek()) == str.charAt(i)) {
return true;
}
} else{
return false;
}
}
return false;
}
The second option is rather ugly.
Try using indexOf instead of contains. Contains requires a String (AKA CharSequence), but you have a char. Also you can refer : https://javamanikandan.blogspot.in/2018/01/java-string-indexof-method-example.html
and
https://javamanikandan.blogspot.in/2018/01/java-string-contains-method-explained.html
Try this
k.contains(""+str.charAt(i))
the method contains works with String objects not Char

How to solve this java.lang.NumberFormatException: For input string: "" based on my code?

I write the code for the LeetCode problem Reverse Integer. I cannot find what's wrong with my solution, but when running it in the LeetCode official site, it propagates this runtime error.
class Solution {
public int reverse(int x)
{
String resultStr = "";
int result = 0;
boolean isNegative = false;
if(x < 0)
{
isNegative = true;
}
int integer = Math.abs(x);
int divid = integer;
while(divid!= 0)
{
divid = divid/10;
resultStr += integer%10;
integer = divid;
}
result = Integer.parseInt(resultStr);
if(isNegative)
{
result = 0-result;
}
return result;
}
}
The final solution for this problem:
class Solution {
public int reverse(int x)
{
String resultStr = "";
int result = 0;
boolean isNegative = false;
if(x < 0)
{
isNegative = true;
}
int integer = Math.abs(x);
int divid = integer;
while(divid!= 0)
{
divid = divid/10;
resultStr += integer%10;
integer = divid;
}
if(resultStr.equals(""))
{
return 0;
}
else
{
try
{
result = Integer.parseInt(resultStr);
if(isNegative)
{
result = 0-result;
}
return result;
}
catch(Exception e)
{
return 0;
}
}
}
}

Struggling to understand equals in Figure Group

I have this class which consists in a group that can contain Circle and Triangle.
public class FiguresGroup {
private static final int NUM_FIGURES = 10;
private Figure[] figuresList = new Figure[NUM_FIGURES];
private int numF = 0;
public void add(Figure f) { figuresList[numF++] = f; }
public String toString() {
String s = "";
for (int i = 0; i < numF; i++) {
s += "\n" + figuresList[i];
}
return s;
}
private boolean found(Figure f) {
for (int i = 0; i < numF; i++) {
if (figuresList[i].equals(f)) return true;
}
return false;
}
private boolean included(FiguresGroup g) {
for (int i = 0; i < g.numF; i++) {
if (!found(g.figuresList[i])) return false;
}
return true;
}
private boolean equals(FiguresGroup g) {
if (g.included(this) && this.included(g)) return true;
}
I don't know how I can implement equals. I tried what you see here but it doesn't work.
For 2 groups to be equal one has to contain every element from the other and vice versa. How to make this work?
You missed a condition on numF of the two objects,
and the equals implementation has a compilation error.
Also note that the found method (depended upon by included) depends on correct implementation of Figure.equals.
If it's correctly implemented, then FiguresGroup.equals could be fixed this way:
private boolean equals(FiguresGroup g) {
return numF == g.numF && g.included(this) && this.included(g);
}
Also, FiguresGroup.equals doesn't override Object.equals, which is confusing. In fact, you're probably already confused by this. When you call figuresGroup.equals outside this class, the code compiles,
even though this method is private,
because actually Object.equals will be called instead of this private method.
You can fix that by overriding Object.equals:
#Override
public boolean equals(Object obj) {
if (!(obj instanceof FiguresGroup)) {
return false;
}
FiguresGroup other = (FiguresGroup) obj;
return numF == other.numF && other.included(this) && this.included(other);
}

Categories