Check whether string contains sub string, without using the java predefined methods - java

I need to find whether a given sub string contains within a given string.But the constraint is I cannot use any predefined Java methods.
I have tried as follows.
public void checkAvailability()
{
len=st.length();
for(int i=0;i<len;i++)
{
for(int j=0;j<substr.length();j++)
{
if(st.charAt(i)==substr.charAt(j))
{
if(j!=substr.length()-1 && i!=st.length()-1)
{
if(st.charAt(i+1)==substr.charAt(j+1))
{
available=true;
//j++;
count++;
}
}
}
}
}
if(available)
{
System.out.println("The character is available " + count + " times");
}
else
{
System.out.println("The character is not availabe");
}
}
But it doesn't give the correct answer. Can somebody help please?
Thank you in advance...

There are a few mistakes in your code - I'll describe an algorithm without writing the code to avoid spoiling the learning exercise for you:
The outer loop needs to go from 0 to st.length()-substr.length()
The inner loop needs to check st.charAt(i+j) and substr.charAt(j)
The inner loop needs to stop as soon as you find a mismatch; set a mismatch flag, and break
If the inner loop completes without finding a mismatch, then i is the position of the first match.
Note that this is the most straightforward algorithm. It does not perform well when the st is long, and substr has lots of "false positives" In general, you can do better than that, for example, by using the KMP algorithm.

Related

Prompting a String value and check if it matches with a specific pattern. How can I solve it by using for loop and substring method?

I am doing an assignment which asks me check the given phone number whether it matches the pattern(the pattern is ddd-ddd-dddd) and the numbers are within 0 to 9. I want to use for loop and substring method, but I have no idea how to use them. This code is what I've done so far.
public static boolean phoneNum(String s){
boolean a = false;
boolean b = false;
String phone = s.substring(1,4)+s.substring(5,8)+s.substring(9);
for(int i =0; i<phone.length(); i++){
y = Character.isDigit(s1.charAt(i));
}
if(s.charAt(4)=='-' && s.charAt(8)=='-' && b==true){
a = true;
return a;
}
return a;
}
If I can add for loop, where should it be?
You are asking how to improve the quality of this code, so let's give some ideas:
change its name to meet java conventions, like isValidPhoneNumber()
you don't need to "carry forward" the results of a previous check. Your method should simply return false immediately whenever it finds a condition to be violated. If all tests pass, you then simply return true in the end.
In other words: what makes your code hard to read and overly complicated are those single character named boolean variables. They mainly add confusion. And keep in mind that your code is ignoring that y variable for example. And even if y is just a typo that could still be simplified.
And to make that clear: avoid using names like a or b. These names mean nothing. They don't tell the reader anything about the purpose of that variable.

Writing ArrayList of objects to textfile using filter

(Disclaimer: I am not done writing the coding, so I have been using lousy names to
identify things.)
I have an ArrayList of PersonObjects called PersonIndex.
The parameters of the PersonObjects are as follows: Name, Age, Gender, Height.
What I am trying to do is process the list and depending on what the last name starts with, it gets written to a different text file.
Because it is in bad taste to try combining three write methods to one writer, I have three different ones which are then called into a single method.
That method is as follows:
public void fullWriteNames(){
writeNamesA2K();
writeNamesL2R();
writeNamesS2Z();
}
I know the general layout of the writer method which is as follows:
String stopper = "stop";
try{
personWriter = new FileWriter(fileName2, true);
personWriter.write(*stuff to write*);
personWriter.close();
}
catch(IOException ioException){
System.out.println("Error.");
}
The issue I am having is how to use an if statement by the .write line to filter the objects. I know I need to use .startsWith, but otherwise I am clueless.
Any help would be appreciated. If there is any coding I left out here which would be relevant, please let me know.
Since characters are really just numbers, you could do something like this:
public void fullWriteNames() {
char first = lastname.charAt(0);
if (first >= 'A' && first <= 'K')
writeNamesA2K();
else if (first >= 'L' && first <= 'R')
writeNamesL2R();
else if (first >= 'S' && first <= 'Z')
writeNamesS2Z();
}
I'm assuming here that the lastname variable is your PersonObject's last name.
You could use a regular expression to match a group
List<String> names = new ArrayList<>(25);
names.add("Apple");
names.add("apple");
names.add("bannas");
names.add("Kings");
names.add("Nov");
names.add("Nov");
names.add("Yak");
for (String name : names) {
if (name.matches("[A-Ka-k].*")) {
System.out.println("[A-K] " + name);
} else if (name.matches("^[L-Rl-r].*")) {
System.out.println("[L-R] " + name);
} else if (name.matches("^[S-Zs-z].*")) {
System.out.println("[S-Z] " + name);
}
}
This might allow you to set up a write method which could take a "filter" parameter and make the decisions what to do based on the filter
public void writeToFile(List<Person> listOfNames, File fileToWrite, String filter) {
...
}
Which you could call using something like...
writeToFile(listOfPeople, fileForGroupAToK, "[A-Ka-k].*");
Personally, though, I might be tempered to generate groups of lists based on the filter which might be a little faster then iterating over the entire list 3 times...but that's me ;)

java recursion, finding occurrence of target in string

I am trying to get more familiar with recursion in java. I am trying to count number of times character occurs in a given string.
public class apptest {
public static void main(String[] args) {
apptest c = new apptest();
String input = "aaa";
char p = 'a';
c.freq(input, p);
}
public int freq(String c, char p) {
if (c.length() == 0) {
return 0;
} else if (c.charAt(0) == p) {
return 1 + freq(c.substring(1, c.length()), p);
} else
return freq(c.substring(1, c.length()), p);
}
}
I am not getting any output. and completely confused on how to solve a problem like this. I looked online and found the freq(c.substring(1, c.length()),p); part but going through the code it doesn't make sense.. seems like on every pass its still going to deal with 'aa' and not necessarily shrink it.. what am I not seeing?
Your code looks good, but you're not getting output because you're not printing it!
Simply add a System.out.println(...) to your main method.
System.out.println("Frequency is: " + c.freq(input, p));
For this part:
I looked online and found the freq(c.substring(1, c.length()),p); part but going through the code it doesn't make sense.. seems like on every pass its still going to deal with 'aa' and not necessarily shrink it.
The line c.substring(1, c.length()) shrinks the String c so that what gets passed into the recursive call has one less character to process and thus, helping the recursive call to eventually reach the termination condition of c.length() == 0. So, it is safe to assume that freq method's implementation is correct.

Java: Contains() method

Trying to implement contains() method without using built-in method contains().
Here is my code:
public static boolean containsCS(String str, CharSequence cs) {
//char[] chs = str.toCharArray();
boolean result = false;
int i=0;
while(i<str.length()) {
int j=0;
while(j<cs.length()) {
if(NEED TO CHECK IF THERE IS AN INDEX OUT OF BOUNDS EXCEPTION) {
result = false;
break;
}
if(str.charAt(i+j)==cs.charAt(j)) {
result|=true; //result = false or true ->>>>> which is true.
j++;
} else {
result = false;
break;
}
}
i++;
}
return false;
}
Let's say:
String str = "llpll"
Charsequence cs = "llo"
I want to make sure this method works properly in the above case where the Charsequence has one or more char to check but the String runs out length. How should I write the first if statement?
if (i+cs.length() > str.length()){
OUT OF BOUNDS
}
Well if it were me first thing I'd check is that the length of my char sequence was <= to the length of my string.
As soon as you chop that logic path out.
If the lengths are equal you can just use ==
Then it would occur that if you chopped up str
into cs length parts, you could do a straight comparison there as well.
e.g str of TonyJ and search for a three character sequence would pile through
Ton
ony
nyJ
One loop, one if statement and a heck of a lot clearer.
I would suggest using this and using the contains method therein.
Edit - For the reading impaired:
The linked method is not from java.lang.String or java.lang.Object
If you'd bother to actually look at the links, you would see that it is the Apache Commons-Lang API and the StringUtils.contains(...) method that I reference, which very clearly answers the question.
If this is for your homework, which I suspect it is, then I suggest you take a look at the API for the String class to see what other methods are available to help find the location of one String within another.
Also consider looking at the source code for String to see how it implements it.
I'm sure you already know this, but it is in fact possible to see the actual source code of the built-in classes and methods. So I'd take a look there for a start. The String class is especially interesting, IMO.

Find a char optimization

So this part of the homework wants us to take a Set of Strings and we will return a List of Strings. In the String Set we will have email addresses ie myname#uark.edu. We are to pull the first part of the email address; the name and put it in the String List.From the above example myname would be put into the List.
The code I currently have uses an iterator to pull a string from the Set. I then use the String.contains("#") as an error check to make sure the String has an # symbol in it. I then start at the end of the string and use the string.charAt("#") to check each char. Once It's found i then make a substring with the correct part and send it to the List.
My problem is i wanted to use something recursive and cut down on operations. I was thinking of something that would divide the string.length()/2 and then use String.contains("#") on the second half first. If that half does contain the # symbol then it would call the functions recursively agin. If the back half did not contain the # symbol then the front half would have it and we would call the function recursively sending it.
So my problem is when I call the function recursively and send it the "substring" once I find the # symbol I will only have the index of the substring and not the index of the original string. Any ideas on how to keep track of it or maybe a command/method I should be looking at. Below is my original code. Any advice welcome.
public static List<String> parseEmail(Set<String> emails)
{
List<String> _names = new LinkedList<String>();
Iterator<String> eMailIt=emails.iterator();
while(eMailIt.hasNext())
{
String address=new String(eMailIt.next());
boolean check=true;
if(address.contains("#"))//if else will catch addresses that do not contain '#' .
{
String _address="";
for(int i=address.length(); i>0 && check; i--)
{
if('#'==address.charAt(i-1))
{
_address=new String(address.substring(0,i-1));
check=false;
}
}
_names.add(_address);
//System.out.println(_address);//fill in with correct sub string
}
else
{
//System.out.println("Invalid address");
_names.add("Invalid address");//This is whats shownn when you have an address that does not have an # in it.
} // could have it insert some other char i.e. *%# s.t. if you use the returned list it can skip over invalid emails
}
return _names;
}
**It was suggested I use the String.indexOf("#") BUT according to the API this method only gives back the first occurrence of the symbol and I have to work on the assumption that there could be multiple "#" in the address and I have to use the last one. Thank you for the suggestion though. Am looking at the other suggestion and will report back.
***So there is a string.lastindexOf() and that was what I needed.
public static List<String> parseEmail(Set<String> emails)
{
List<String> _names = new LinkedList<String>();
Iterator<String> eMailIt=emails.iterator();
while(eMailIt.hasNext())
{
String address=new String(eMailIt.next());
if(address.contains("#"))//if else will catch addresses that do not contain '#' .
{
int endex=address.lastIndexOf('#');
_names.add(address.substring(0,endex-1));
// System.out.println(address.substring(0,endex));
}
else
{
// System.out.println("Invalid address");
_names.add("Invalid address");//This is whats shownn when you have an address that does not have an # in it.
} // could have it insert some other char i.e. *%# s.t. if you use the returned list it can skip over invalid emails
}
return _names;
}
Don't reinvent the wheel (unless you were asked too of course). Java already has a built-in function for what you are attempting String.indexOf(String str). Use it.
final String email = "someone#example.com";
final int atIndex = email.lastIndexOf("#");
if(atIndex != -1) {
final String name = email.substring(0, atIndex);
}
I agree to the previous two answers, if you are allowed to use the built-in functions split or indexOf then you should. However if it is part of your homework to find the substrings yourself you should definitely just go through the string's characters and stop when you found the # aka linear search.
You should definitely not under no circumstances try to do this recursively: The idea of divide and conquer should not be abused in a situation where there is nothing to gain: Recursion means function-call overhead and doing this recursively would only have a chance of being faster than a simple linear search if the sub-strings were searched in-parallel; and even then: the synchronization overhead would kill the speedup for all but the most gigantic strings.
Unless recursion is specified in the homework, you would be best served by looking into String.split. It will split the String into a String array (if you specify it to be around '#'), and you can access both halves of the e-mail address.

Categories