ending String, recursive, and searching for occurances - java

What my codes does is pass two string and a count in the method countSubstring.
countSubString count the occurances of strTwo in strOne.
But I am have difficulty because I don't understand a few things:
public class CountingSubString
{
int CountSubString(String strOne, String strTwo, int count)
{
int i = 0;
int foundAtIndex = strOne.indexOf(strTwo, i);
if(foundAtIndex == -1)
{
i++;
}
else//(foundAtIndex != -1)
{
count++;
int newStartIndex = foundAtIndex + strTwo.length();
String StringFromString = strOne.substring(newStartIndex, strOne.length()-1);
count = count + countSubString(StringFromString, strTwo, count);
return count;
}
return count;
}
public class TestCountingSubString
{
public static void main(String[] argv)
{
String s2 = new String("abab");
String s3 = new String("ab");
String s4 = new String("aabbaa");
String s5 = new String("aa");
countingSubString CountOfString = new countingSubString();
int count = CountOfString.countSubString(s2, s3, 0);
System.out.println(count);
}
}
Question 1) let consider a case where string1 = c, and string2 = aa.
aa is not contained in c.
How do I make a base case for this case?
My attempt:
Question 2) In java how does a string end?
If I have string1 = "aabbaa", and string2 = "aa".
I get aa from index 0 and 1, so I return index 0. compute string2.length() + 0 = 2.
Now I substring string 1 at beginIndex: 2 to endindex: string2.length-1 to get new string to obtain "bbaa".
Searching again, I obtain string aa at index 2 and 3.
How do I make my recursive end after the string aa?

Why are you complicating things. It's java, use its features.
String string1 = "abab";
Pattern p = Pattern.compile("ab");
Matcher m = p.matcher(string1);
int count = 0;
while (m.find()){
count +=1;
}
System.out.println(count);
Also for your understanding, substring function has following format
public String substring(int beginIndex, int endIndex)
where
beginIndex -- the begin index, inclusive.
endIndex -- the end index, exclusive.
Safety condition as asked in Question 1
if (strOne == null || strOne.equals("") || strTwo.length() < sub.length())
return 0;
Solution to Question 2
int index = strOne.indexOf(strTwo);
if(index!=-1){
count++;
count+= countSubString(strOne.substring(index+1),strTwo,0);
}
So complete solution is
class countingSubString
{
int countSubString(String strOne, String strTwo, int count)
{
if (strOne == null || strOne.equals("") || strOne.length() < strTwo.length())
return 0;
int index = strOne.indexOf(strTwo);
if(index!=-1){
count++;
count+= countSubString(strOne.substring(index+1),strTwo,0);
}
return count;
}
}
Also remove public modifier from class countingSubString as there can be only one public class in one file. And also follow naming convention so class name should be
CountingSubString instead of countingSubString

You can use a recursive function as follows. I modified the class and function names a little bit.
You don't need to pass 'count' parameter to countSub function, since it will be eventually returned recursively.
public class Count
{
public static void main(String[] argv) {
String s2 = new String("ababab");
String s3 = new String("ab");
String s4 = new String("aabbaa");
String s5 = new String("aa");
int count = countSub(s2, s3);
System.out.println(count);
}
public static int countSub(String strOne, String strTwo) {
int foundAtIndex = strOne.indexOf(strTwo);
if(foundAtIndex == -1) {
return 0;
} else {
int newStartIndex = foundAtIndex + strTwo.length();
String newString = strOne.substring(newStartIndex, strOne.length());
return (1 + countSub(newString, strTwo));
}
}
}

Related

Getting distinct subsequences of a string equal to a particular string via recursion

Code logic
In order to find all subsequences of String s that are equal to String t, I made a recursive method getSub() to get all the subsequences of input string s and added it to the list. Now I loop through the list (in numDistinct method) and try to see all those subsequences in the list that matches the string t. In case there is a match count should be incremented and later returned.
BUT
Question
In the following code count never increases, which means the if condition (in numDistinct method) does not work as it was intended. Why t which is a string and list.get(i) which should also return a string doesn't seem to work with equals method?
public static int numDistinct(String s, String t) {
int count = 0;
ArrayList<String> list = new ArrayList<>();
getSub(s, list);
StdOut.println(list);
for (int i = 0; i < list.size(); i++) {
if (t.equals(list.get(i))) {
count++;
}
}
return count;
}
private static int getSub(String s, ArrayList<String> list) {
if (s.length() == 0) {
list.add(" ");
return 1;
}
int smallOutput = getSub(s.substring(1), list);
char[] cha = s.toCharArray();
for (int i = 0; i < smallOutput; i++) {
list.add(cha[0] + list.get(i));
}
return 2 * smallOutput;
}
public static void main(String[] args) {
String s = "rabbbit";
String t = "rabbit";
StdOut.println(numDistinct(s, t));
}
The way you are creating the strings in the list ensures there is a space character at the end of each string. As such, none of them are equal to t.
if (s.length() == 0) {
list.add(""); // remove the space from this line
return 1;
}

Java:How do I make the "char" parameter into a String parameter in this specific java method?

public static int getNthOccurrence(int n, char find, String str)
{
int counter=0;
for(int i=0;i<str.length();i++)
{
if(str.charAt(i)==find)
{
counter++;
if(counter==n)
return i;
}
}
return -1;
}
I have already seen this thread Java: method to get position of a match in a String?
The code runs that:
int n=getNthOccurrence(3,'n',"you arent gonna find me");
output: 13
You can make a char into a String by simply doing this
String theString = yourChar + "";
Your code could look something like this !spoiler below!
public static int getNthOccurrence(int n, char find, String str)
{
String f = find + "";
int counter = 0;
for (String c : str.split("")){
if (c.equals(f)) n--;
if (n < 1 ) return counter;
counter++;
}
return -1;
}
}
Once you've changed the parameter type to String:
public static int getNthOccurrence(int n, String find, String str)
Use String.indexOf(String, int):
i = -find.length();
for (int count = 0; count < n; ++count) {
i = str.indexOf(find, i + find.length());
if (i < 0) break;
}
return (i >= 0) ? i : -1;
(Note that String.indexOf(char, int) is a preferable way to do it with char, as in the case of the original code).

Counting number of occurrences of word in java

I want to count the number of occurrences of particular word in a source string.
Let's say src="thisisamangoterrthisismangorightthis?"
word="this"
So what I am doing is, first search for index of word in src. It's at index 0. Now I am extracting the part from this index location to end of src.
i.e., now src="isamangoterrthisismangorightthis?" and search for word again.
But I am getting array out of bound exception.
public static int countOccur(String s1, String s2)
{
int ans=0;
int len1=s1.length();
int len2=s2.length();
System.out.println("Lengths:"+len1+" " +len2);
while(s1.contains(s2))
{
ans++;
int tmpInd=s1.indexOf(s2);
System.out.println("Now Index is:"+tmpInd);
if((tmpInd+len2)<len1){
s1=s1.substring(tmpInd+len2, len1);
System.out.println("Now s1 is:"+s1);
}
else
break;
}
return ans;
}
Try this to count the word in a string,
private static int countingWord(String value, String findWord)
{
int counter = 0;
while (value.contains(findWord))
{
int index = value.indexOf(findWord);
value = value.substring(index + findWord.length(), value.length());
counter++;
}
return counter;
}
When you use a method that throws ArrayIndexOutOfBoundsException, it's always a good idea to check the bounds. See String#substring:
IndexOutOfBoundsException - if the beginIndex is negative, or endIndex
is larger than the length of this String object, or beginIndex is
larger than endIndex.
You should cover all cases:
if(tmpInd + len2 >= s1.length() || len1 >= s1.length() || ... ) {
//Not good
}
Or, better, you should consider your logic to avoid this situation in the first place.
Try and use indexOf(), it will take care of bounds etc for you:
public static int countOccurrences(final String haystack, final String needle)
{
int index = 0;
int ret = 0;
while (true) {
index = haystack.indexOf(needle, index);
if (index == -1)
return ret;
ret++;
}
// Not reached
throw new IllegalStateException("How on earth did I get there??");
}
Rather than doing a substring on your String use this method
public int indexOf(int ch, int fromIndex)
then just check if the result is -1
Your might use replace to solve the problem
String s = "thisisamangoterrthisismangorightthis?";
String newS = s.replaceAll("this","");
int count = (s.length() - newS.length()) / 4;
import java.io.*;
import java.util.*;
public class WordCount
{
public static class Word implements Comparable<Word>
{
String word;
int count;
#Override
public int hashCode()
{
return word.hashCode();
}
#Override
public boolean equals(Object obj)
{
return word.equals(((Word)obj).word);
}
#Override
public int compareTo(Word b)
{
return b.count - count;
}
}
public static void findWordcounts(File input)throws Exception
{
long time = System.currentTimeMillis();
Map<String, Word> countMap = new HashMap<String, Word>();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(input)));
String line;
while ((line = reader.readLine()) != null) {
String[] words = line.split("[^A-ZÅÄÖa-zåäö]+");
for (String word : words) {
if ("".equals(word)) {
continue;
}
Word wordObj = countMap.get(word);
if (wordObj == null) {
wordObj = new Word();
wordObj.word = word;
wordObj.count = 0;
countMap.put(word, wordObj);
}
wordObj.count++;
}
}
reader.close();
SortedSet<Word> sortedWords = new TreeSet<Word>(countMap.values());
int i = 0;
for (Word word : sortedWords) {
if (i > 10) {
break;
}
System.out.println("Word \t "+ word.word+"\t Count \t"+word.count);
i++;
}
time = System.currentTimeMillis() - time;
System.out.println("Completed in " + time + " ms");
}
public static void main(String[] args)throws Exception
{
findWordcounts(new File("./don.txt"));
}
}

Java read integer from middle of the string

Is it possible in Java to efficiently read an integer from random position of the string? For instance, I have a
String s = "(34";
if (s.charAt(0) == '(')
{
// How to read a number from position = 1 to the end of the string?
// Of course, I can do something like
String s1 = s.substring(1);
int val = Integer.parseInt(s1);
}
but it dynamically creates a new instance of string and seems to be too slow and performance hitting.
UPDATE
Well, to be precise: I have an array of strings in form "(ddd" where d is a digit. So I do know that a number starts always from pos = 1. How do I efficently read these numbers?
Integer.parseInt(s1.replaceAll("[\\D]", ""))
Answered before the update:
I'm not an expert in regex, but hope this "\\d+" is useful to you. Invoke the below method with pattern: "\\d+".
public static int returnInt(String pattern,String inputString){
Pattern intPattern = Pattern.compile(pattern);
Matcher matcher = intPattern.matcher(inputString);
matcher.find();
String input = matcher.group();
return Integer.parseInt(input);
}
Answered after the update:
String is a final object, you cannot edit it, so if you want to get some digit value from it, you have the 2 ways:
1. Use your code, that will work fine, but if you care about performance, try 2nd way.
2. Divide your string on digits and add them to get the result:
public static void main(String[] args) {
String input = "(123456";
if(input.charAt(0) == '(') {
System.out.println(getDigit(input));
}
}
private static int getDigit(String s) {
int result = 0;
int increase = 10;
for(int i = 1; i < s.length(); i++) {
int digit = Character.getNumericValue(s.charAt(i));
result*=increase;
result += digit;
}
return result;
}
Output:
123456
If you don't want to allocate a new String then you can use the code in this other SO answer:
int charArrayToInt(char[] data, int start, int end) throws NumberFormatException {
int result = 0;
for (int i = start; i < end; i++) {
int digit = ((int)data[i] & 0xF);
if ((digit < 0) || (digit > 9)) throw new NumberFormatException();
result *= 10;
result += digit;
}
return result;
}
You can call it with charArrayToInt(s.toCharArray(), 1, s.length())

Find the Number of Occurrences of a Substring in a String

Why is the following algorithm not halting for me?
In the code below, str is the string I am searching in, and findStr is the string occurrences of which I'm trying to find.
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;
while (lastIndex != -1) {
lastIndex = str.indexOf(findStr,lastIndex);
if( lastIndex != -1)
count++;
lastIndex += findStr.length();
}
System.out.println(count);
How about using StringUtils.countMatches from Apache Commons Lang?
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(StringUtils.countMatches(str, findStr));
That outputs:
3
Your lastIndex += findStr.length(); was placed outside the brackets, causing an infinite loop (when no occurence was found, lastIndex was always to findStr.length()).
Here is the fixed version :
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;
while (lastIndex != -1) {
lastIndex = str.indexOf(findStr, lastIndex);
if (lastIndex != -1) {
count++;
lastIndex += findStr.length();
}
}
System.out.println(count);
A shorter version. ;)
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(str.split(findStr, -1).length-1);
The last line was creating a problem. lastIndex would never be at -1, so there would be an infinite loop. This can be fixed by moving the last line of code into the if block.
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;
while(lastIndex != -1){
lastIndex = str.indexOf(findStr,lastIndex);
if(lastIndex != -1){
count ++;
lastIndex += findStr.length();
}
}
System.out.println(count);
Do you really have to handle the matching yourself ? Especially if all you need is the number of occurences, regular expressions are tidier :
String str = "helloslkhellodjladfjhello";
Pattern p = Pattern.compile("hello");
Matcher m = p.matcher(str);
int count = 0;
while (m.find()){
count +=1;
}
System.out.println(count);
I'm very surprised no one has mentioned this one liner. It's simple, concise and performs slightly better than str.split(target, -1).length-1
public static int count(String str, String target) {
return (str.length() - str.replace(target, "").length()) / target.length();
}
Here it is, wrapped up in a nice and reusable method:
public static int count(String text, String find) {
int index = 0, count = 0, length = find.length();
while( (index = text.indexOf(find, index)) != -1 ) {
index += length; count++;
}
return count;
}
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;
while((lastIndex = str.indexOf(findStr, lastIndex)) != -1) {
count++;
lastIndex += findStr.length() - 1;
}
System.out.println(count);
at the end of the loop count is 3; hope it helps
public int countOfOccurrences(String str, String subStr) {
return (str.length() - str.replaceAll(Pattern.quote(subStr), "").length()) / subStr.length();
}
A lot of the given answers fail on one or more of:
Patterns of arbitrary length
Overlapping matches (such as counting "232" in "23232" or "aa" in "aaa")
Regular expression meta-characters
Here's what I wrote:
static int countMatches(Pattern pattern, String string)
{
Matcher matcher = pattern.matcher(string);
int count = 0;
int pos = 0;
while (matcher.find(pos))
{
count++;
pos = matcher.start() + 1;
}
return count;
}
Example call:
Pattern pattern = Pattern.compile("232");
int count = countMatches(pattern, "23232"); // Returns 2
If you want a non-regular-expression search, just compile your pattern appropriately with the LITERAL flag:
Pattern pattern = Pattern.compile("1+1", Pattern.LITERAL);
int count = countMatches(pattern, "1+1+1"); // Returns 2
You can number of occurrences using inbuilt library function:
import org.springframework.util.StringUtils;
StringUtils.countOccurrencesOf(result, "R-")
Increment lastIndex whenever you look for next occurrence.
Otherwise it's always finding the first substring (at position 0).
The answer given as correct is no good for counting things like line returns and is far too verbose. Later answers are better but all can be achieved simply with
str.split(findStr).length
It does not drop trailing matches using the example in the question.
public int indexOf(int ch,
int fromIndex)
Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.
So your lastindex value is always 0 and it always finds hello in the string.
try adding lastIndex+=findStr.length() to the end of your loop, otherwise you will end up in an endless loop because once you found the substring, you are trying to find it again and again from the same last position.
Try this one. It replaces all the matches with a -.
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int numberOfMatches = 0;
while (str.contains(findStr)){
str = str.replaceFirst(findStr, "-");
numberOfMatches++;
}
And if you don't want to destroy your str you can create a new string with the same content:
String str = "helloslkhellodjladfjhello";
String strDestroy = str;
String findStr = "hello";
int numberOfMatches = 0;
while (strDestroy.contains(findStr)){
strDestroy = strDestroy.replaceFirst(findStr, "-");
numberOfMatches++;
}
After executing this block these will be your values:
str = "helloslkhellodjladfjhello"
strDestroy = "-slk-djladfj-"
findStr = "hello"
numberOfMatches = 3
As #Mr_and_Mrs_D suggested:
String haystack = "hellolovelyworld";
String needle = "lo";
return haystack.split(Pattern.quote(needle), -1).length - 1;
Based on the existing answer(s) I'd like to add a "shorter" version without the if:
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int count = 0, lastIndex = 0;
while((lastIndex = str.indexOf(findStr, lastIndex)) != -1) {
lastIndex += findStr.length() - 1;
count++;
}
System.out.println(count); // output: 3
Here is the advanced version for counting how many times the token occurred in a user entered string:
public class StringIndexOf {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a sentence please: \n");
String string = scanner.nextLine();
int atIndex = 0;
int count = 0;
while (atIndex != -1)
{
atIndex = string.indexOf("hello", atIndex);
if(atIndex != -1)
{
count++;
atIndex += 5;
}
}
System.out.println(count);
}
}
This below method show how many time substring repeat on ur whole string. Hope use full to you:-
String searchPattern="aaa"; // search string
String str="aaaaaababaaaaaa"; // whole string
int searchLength = searchPattern.length();
int totalLength = str.length();
int k = 0;
for (int i = 0; i < totalLength - searchLength + 1; i++) {
String subStr = str.substring(i, searchLength + i);
if (subStr.equals(searchPattern)) {
k++;
}
}
This solution prints the total number of occurrence of a given substring throughout the string, also includes the cases where overlapping matches do exist.
class SubstringMatch{
public static void main(String []args){
//String str = "aaaaabaabdcaa";
//String sub = "aa";
//String str = "caaab";
//String sub = "aa";
String str="abababababaabb";
String sub = "bab";
int n = str.length();
int m = sub.length();
// index=-1 in case of no match, otherwise >=0(first match position)
int index=str.indexOf(sub), i=index+1, count=(index>=0)?1:0;
System.out.println(i+" "+index+" "+count);
// i will traverse up to only (m-n) position
while(index!=-1 && i<=(n-m)){
index=str.substring(i, n).indexOf(sub);
count=(index>=0)?count+1:count;
i=i+index+1;
System.out.println(i+" "+index);
}
System.out.println("count: "+count);
}
}
Matcher.results()
You can find the number of occurrences of a substring in a string using Java 9 method Matcher.results() with a single line of code.
It produces a Stream of MatchResult objects which correspond to captured substrings, and the only thing needed is to apply Stream.count() to obtain the number of elements in the stream.
public static long countOccurrences(String source, String find) {
return Pattern.compile(find) // Pattern
.matcher(source) // Mather
.results() // Stream<MatchResults>
.count();
}
main()
public static void main(String[] args) {
System.out.println(countOccurrences("helloslkhellodjladfjhello", "hello"));
}
Output:
3
here is the other solution without using regexp/patterns/matchers or even not using StringUtils.
String str = "helloslkhellodjladfjhelloarunkumarhelloasdhelloaruhelloasrhello";
String findStr = "hello";
int count =0;
int findStrLength = findStr.length();
for(int i=0;i<str.length();i++){
if(findStr.startsWith(Character.toString(str.charAt(i)))){
if(str.substring(i).length() >= findStrLength){
if(str.substring(i, i+findStrLength).equals(findStr)){
count++;
}
}
}
}
System.out.println(count);
If you need the index of each substring within the original string, you can do something with indexOf like this:
private static List<Integer> getAllIndexesOfSubstringInString(String fullString, String substring) {
int pointIndex = 0;
List<Integer> allOccurences = new ArrayList<Integer>();
while(fullPdfText.indexOf(substring,pointIndex) >= 0){
allOccurences.add(fullPdfText.indexOf(substring, pointIndex));
pointIndex = fullPdfText.indexOf(substring, pointIndex) + substring.length();
}
return allOccurences;
}
public static int getCountSubString(String str , String sub){
int n = 0, m = 0, counter = 0, counterSub = 0;
while(n < str.length()){
counter = 0;
m = 0;
while(m < sub.length() && str.charAt(n) == sub.charAt(m)){
counter++;
m++; n++;
}
if (counter == sub.length()){
counterSub++;
continue;
}
else if(counter > 0){
continue;
}
n++;
}
return counterSub;
}
🍑 Just a little more peachy answer
public int countOccurrences(String str, String sub) {
if (str == null || str.length() == 0 || sub == null || sub.length() == 0) return 0;
int count = 0;
int i = 0;
while ((i = str.indexOf(sub, i)) != -1) {
count++;
i += sub.length();
}
return count;
}
I was asked this question in an interview just now and I went completely blank. (Like always, I told myself that the moment the interview ends ill get the solution) which I did, 5 mins after the call ended :(
int subCounter=0;
int count =0;
for(int i=0; i<str.length(); i++) {
if((subCounter==0 && "a".equals(str.substring(i,i+1)))
|| (subCounter==1 && "b".equals(str.substring(i,i+1)))
|| (subCounter==2 && "c".equals(str.substring(i,i+1)))) {
++subCounter;
}
if(subCounter==3) {
count = count+1;
subCounter=0;
}
}
System.out.println(count);

Categories

Resources