This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Occurences of substring in a string
As in the subject how to check how many times one string contains another one?
Example:
s1 "babab"
s2 "bab"
Result : 2
If i use Matcher it does only recognize first occurence:
String s1 = JOptionPane.showInputDialog(" ");
String s2 = JOptionPane.showInputDialog(" ");
Pattern p = Pattern.compile(s2);
Matcher m = p.matcher(s1);
int counter = 0;
while(m.find()){
System.out.println(m.group());
counter++;
}
System.out.println(counter);
I can do it like that, but I would like below to use Java libraries iike Scanner, StringTokenizer, Matcher etc:
String s1 = JOptionPane.showInputDialog(" ");
String s2 = JOptionPane.showInputDialog(" ");
String pom;
int count = 0;
for(int i = 0 ; i< s1.length() ; i++){
if(s1.charAt(i) == s2.charAt(0)){
if(i + s2.length() <= s1.length()){
pom = s1.substring(i,i+s2.length());
if(pom.equals(s2)){
count++;
}
}
}
}
System.out.println(count);
One liner solution for the lulz
longStr is the input string. findStr is the string to search for. No assumption, except that longStr and findStr must not be null and findStr must have at least 1 character.
longStr.length() - longStr.replaceAll(Pattern.quote(findStr.substring(0,1)) + "(?=" + Pattern.quote(findStr.substring(1)) + ")", "").length()
Since 2 matches are considered different as long as they starts at different index, and overlapping can happen, we need a way to differentiate between the matches and allow for matched part to be overlapped.
The trick is to consume only the first character of the search string, and use look-ahead to assert the rest of the search string. This allows overlapping portion to be rematched, and by removing the first character of the match, we can count the number of matches.
i think this might work if you know the word you are looking for in the string you might need to edit the regex pattern tho.
String string = "hellohellohellohellohellohello";
Pattern pattern = Pattern.compile("hello");
Matcher matcher = pattern.matcher(string);
int count = 0;
while (matcher.find()) count++;
The class Matcher has two methods "start" and "end" which return the start index and end index of the last match. Further, the method find has an optional parameter "start" at which it starts searching.
you can do it like this
private int counterString(String s,String search) {
int times = 0;
int index = s.indexOf(search,0);
while(index > 0) {
index = s.indexOf(search,index+1);
++times;
}
return times;
}
Some quick Bruce Forte solution:
String someString = "bababab";
String toLookFor = "bab";
int count = 0;
for (int i = 0; i < someString.length(); i++) {
if (someString.length() - i >= toLookFor.length()) {
if (someString.substring(i, i + toLookFor.length()).equals(toLookFor) && !"".equals(toLookFor)) {
count++;
}
}
}
System.out.println(count);
This prints out 3. Please note I assume that none of the Strings is null.
Related
Trying to search for patterns of letters in a file, the pattern is entered by a user and comes out as a String, so far I've got it to find the first letter by unsure how to make it test to see if the next letter also matches the pattern.
This is the loop I currently have. any help would be appreciated
public void exactSearch(){
if (pattern==null){UI.println("No pattern");return;}
UI.println("===================\nExact searching for "+patternString);
int j = 0 ;
for(int i=0; i<data.size(); i++){
if(patternString.charAt(i) == data.get(i) )
j++;
UI.println( "found at " + j) ;
}
}
You need to iterate over the first string until you find the first character of the other string. From there, you can create an inner loop and iterate on both simultaneously, like you did.
Hint: be sure to look watch for boundaries as the strings might not be of the same size.
You can try this :-
String a1 = "foo-bar-baz-bar-";
String pattern = "bar";
int foundIndex = 0;
while(foundIndex != -1) {
foundIndex = a1.indexOf(pattern,foundIndex);
if(foundIndex != -1)
{
System.out.println(foundIndex);
foundIndex += 1;
}
}
indexOf - first parameter is the pattern string,
second parameter is starting index from where we have to search.
If pattern is found, it will return the starting index from where the pattern matched.
If pattern is not found, indexOf will return -1.
String data = "foo-bar-baz-bar-";
String pattern = "bar";
int foundIndex = data.indexOf(pattern);
while (foundIndex > -1) {
System.out.println("Match found at: " + foundIndex);
foundIndex = data.indexOf(pattern, foundIndex + pattern.length());
}
Based on your request, you can use this algorithm to search for your positions:
1) We check if we reach at the end of the string, to avoid the invalidIndex error, we verify if the remaining substring's size is smaller than the pattern's length.
2) We calculate the substring at each iteration and we verify the string with the pattern.
List<Integer> positionList = new LinkedList<>();
String inputString = "AAACABCCCABC";
String pattern = "ABC";
for (int i = 0 ; i < inputString.length(); i++) {
if (inputString.length() - i < pattern.length()){
break;
}
String currentSubString = inputString.substring(i, i + pattern.length());
if (currentSubString.equals(pattern)){
positionList.add(i);
}
}
for (Integer pos : positionList) {
System.out.println(pos); // Positions : 4 and 9
}
EDIT :
Maybe it can be optimized, not to use a Collection for this simple task, but I used a LinkedList to write a quicker approach.
My task is splitting a string, which starts with numbers and contains numbers and letters, into two sub-strings.The first one consists of all numbers before the first letter. The second one is the remained part, and shouldn't be split even if it contains numbers.
For example, a string "123abc34de" should be split as: "123" and "abc34de".
I know how to write a regular expression for such a string, and it might look like this:
[0-9]{1,}[a-zA-Z]{1,}[a-zA-Z0-9]{0,}
I have tried multiple times but still don't know how to apply regex in String.split() method, and it seems very few online materials about this. Thanks for any help.
you can do it in this way
final String regex = "([0-9]{1,})([a-zA-Z]{1,}[a-zA-Z0-9]{0,})";
final String string = "123ahaha1234";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
matcher.group(1) contains the first part and matcher.group(2) contains the second
you can add it to a list/array using these values
You can use a pretty simple pattern : "^(\\d+)(\\w+)" which capture digits as start, and then when letters appear it take word-char
String string = "123abc34de";
Matcher matcher = Pattern.compile("^(\\d+)(\\w+)").matcher(string);
String firstpart = "";
String secondPart = "";
if (matcher.find()) {
firstpart = matcher.group(1);
secondPart = matcher.group(2);
}
System.out.println(firstpart + " - " + secondPart); // 123 - abc34de
This is not the correct way but u will get the result
public static void main(String[] args) {
String example = "1234abc123";
int index = 0;
String[] arr = new String[example.length()];
for (int i = 0; i < example.length(); i++) {
arr = example.split("");
try{
if(Integer.parseInt(arr[i]) >= 0 & Integer.parseInt(arr[i]) <= 9){
index = i;
}
else
break;
}catch (NumberFormatException e) {
index = index;
}
}
String firstHalf = example.substring(0,Integer.parseInt(arr[index])+1);
String secondHalf = example.substring(Integer.parseInt(arr[index])+1,example.length());
System.out.println(firstHalf);
System.out.println(secondHalf);
}
Output will be: 1234 and in next line abc123
Given two strings:
str1 = "abcdefacbccbagfacbacer"
str2 = "abc"
I've to find the longest substring in str1 that is formed by the subset of characters of str2, in this case it would be - 7 (acbccba). What would be the approach to solve this in least complexity. First I thought of DP. But, I guess DP is really not required for this, as we have to search for substring, and not subsequence. Then I though of suffix tree. But that would require extra pre-processing time.
What would be the best way to do this? In fact, is this problem even suitable for a suffix tree, or DP?
The easiest approach by far:
Build a hashset of the second string.
Loop over the first string and for each character, check if it is in the hashset. Keep track of the longest substring.
Running time: O(n+m) where n is the length of str1 and m is the length of str2.
(Non-tested) code:
Set<Character> set = new HashSet<>();
for (int i = 0; i < str2.length(); i++) {
set.add(str2.charAt(i));
}
int longest = 0;
int current = 0;
int longestEnd = -1;
for (int i = 0; i < str1.length(); i++) {
if (set.contains(str1.charAt(i)) {
current++;
if (current > longest) {
longest = current;
longestEnd = i + 1;
}
} else {
current = 0;
}
}
String result = "";
if (longest > 0) {
result = str1.substr(longestEnd - longest, longestEnd);
}
Just an idea: wrap second string in [] and use Pattern's match method:
Pattern p = Pattern.compile("(["+str2+"])");
Matcher m = p.matcher(str1);
m.find();
and then m.group(1) shall find it.
There is actually only one way i can think of:
Go on the chars of the string str1.
Foreach char in str1 check if its in str2
increase a counter (i) eachtime the current char in str1 was found in str2
Once the char in str1 not part of str2 save the counter (i) value if its begger than the maxfound counter in maxfound which represents the longest found sequence and reset the (i) counter.
Tested code in Perl.
use strict;
use warnings;
my $str1 = "abcdefacbccbagfacbacer";
my $str2 = "abc";
my #str1 = split ("", $str1);
my #str2 = split ("", $str2);
my #res = ();
my $index = undef;
my $max = 0;
my #max_char = ();
for(my $i = 0; $i < #str1; $i++){
if ($str1[$i] =~ /[#str2]/){
push (#res , $str1[$i]);
next;
}else{
if(#res > $max){
$max = #res;
#max_char = #res;
$index = $i;
}
#res = ();
}
}
if(#res > $max){
#max_char = #res;
$index = $i;
}
$index = $index - $#max_char - 1;
print "Longest substring = #max_char. Starting from index $index";
I want to find the positions of a particular word in an input string using java. I do not want to use regular expressions.For example if my input string is " Rama Raman Rama" and if I want to find Rama then it should give me Index number 0 and 11 as output. My code finds Rama in all the three words which I do not want. Some help?
Here is your solution :
int index=0,j=0;
String name="RAMA RAMAN RAMA";
String[] names = name.split(" ");
for(int i=0;i<names.length;i++){
if(names[i].equals("RAMA")){
if(i!=0){
while(j<i){
index += names[j++].length();
}
}
index += i;
System.out.println("Your match is at : "+index);
}
}
String name = "RAMA RAMA RAMA";
int position = name.indexOf("RAMA");
//This gives you the first position for "RAMA". If you want to have each index for each occurrence use this one:
int start = 0;
int end = 0;
while((start = name.indexOf("RAMA", end) != -1){
int position = start;
end = start;
}
You can try this
String str="Rama Raman Rama";
String[] arr=str.split(" "); // split and grab word to array
int length=0;
for(String i:arr){
if("Rama".equals(i)){
System.out.println("Index: "+length);
}
length=length+i.length()+1;// keep length count here
}
You can use the classes Pattern and Matcher. An example when you try to find the word "alpha":
String s = "alpha beta alpha anything";
Pattern p = Pattern.compile("alpha");
Matcher m = p.matcher(s);
while (m.find())
System.out.println(m.start());
It prints: 0, 11
Simply use indexOf() method. This method will let you know if word is in the text by returning index of word otherwise will return -1 means word is not found.
String str = "World is beautiful";
str.indexOf("beautiful"); // This will return value 9 as beautiful word starts at index 9
similarly
str.indexOf("beautifully"); // It will return -1 as this word doesn't exist in the text
I have ONE string field which is in format:
"TransactionID=30000001197169 ExecutionStatus=6
additionalCurrency=KMK
pin= 0000"
So they are not separated with some ; оr , they are not seperated even with one blank space.
I want to get value for Execution Status and put it in some field?
How to achieve this?
Thanks for help
This works. But I am not sure this is the most optimal.It just solves your problem.
String s = "TransactionID=30000001197169ExecutionStatus=6additionalCurrency=KMKpin=0000";
if(s!=null && s.contains("ExecutionStatus="))
{
String s1[] = s.split("ExecutionStatus=");
if(s1!=null && s1.length>1)
{
String line = s1[1];
String pattern = "[0-9]+";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find( )) {
System.out.println("Match");
System.out.println("Found value: " + m.group(0) );
} else {
System.out.println("NO MATCH");
}
}
}
In your example they are indeed seperated by blanks, but the following should be working without blanks, too. Assuming your String is stored in String arguments
String executionStatus;
String[] anArray = arguments.split("=");
for (int i; i < anArray.length; i++)
if (anArray[i].contains("ExecutionStatus")){
executionStatus = anArray[++i].replace("additionalCurrency","");
executionStatus = executionStatus.trim();
}
}
Check if it contains() ExecutionStatus=
If yes then split the string with ExecutionStatus=
Now take the Second string from array find the first occurance of non digit char and use substring()
Assuming all that white space is present in your string, this works.
String str = "\"TransactionID=30000001197169 ExecutionStatus=6\n" +
" additionalCurrency=\"KMK\"\n" +
" pin= \"0000\"\"";
int start = str.indexOf("ExecutionStatus=") + "ExecutionStatus=".length();
int status = 0;
if (start >= 0) {
String strStatus = str.substring(start, str.indexOf("additionalCurrency=") - 1);
try {
status = Integer.parseInt(strStatus.trim());
} catch (NumberFormatException e) {
}
}
At the risk of attracting "... and now you have two problems!" comments, this is probably easiest done with regexes (str is the String defined above):
Pattern p = Pattern.compile("ExecutionStatus\\s*=\\s*(\\d+)"); // Whitespace matching around equals for safety, capturing group around the digits of the status)
Matcher m = p.matcher(str);
String status = m.find() ? m.group(1) : null;