I am trying to make an assembly language parser, and from the given string I have to find all the valid commands. For a command to be valid, the following conditions have to be met:
the first letter is a lowercase English letter
next, it contains a sequence of zero or more of the following
characters: lowercase English letters, digits, and colons.
Next, it contains a forward slash /
Next, it contains a sequence of zero or more of the following
characters: lowercase English letters, digits.
Next, it contains a backward slash \
Next, it contains a sequence of one or more lowercase English letters.
e.g. given a command abc:/b1c\xy
there are six valid commands:
abc:/b1c\xy
bc:/b1c\xy
c:/b1c\xy
abc:/b1c\x
bc:/b1c\x
c:/b1c\x
I don't know anything about regular expression can someone please help me with it.
Following steps are to be followed to solve your problem.
Step 1: We need to find all possible subsets in increasing order for the given string.
For e.g. abc --> {a,b,ab,bc,abc} in increasing order.
Step 2: Now we have to check whether the string you find out is following the regex pattern or not.
Credits: I am going to use the regex pattern given by Varun Chaudhary.
Step 3 : If it matches I will return 1 and keep adding count for all possible valid subsets of your string.
Step 4: Print the result.
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main
{
static int regexWork(String command) {
int count =0;
Pattern COMMAND_PATTERN = Pattern.compile("[a-z]{1}[a-z0-9:]*\\/[a-z0-9]*\\\\[a-z]+");
Matcher matcher = COMMAND_PATTERN.matcher(command);
//If matches returns 1
while (matcher.find())
count=1;
return count;
}
// Finding all subsets of given set[]
static void printSubsets(char set[])
{
int count =0;
int n = set.length;
// Pick starting point
for (int len = 1; len <= n; len++)
{
// Pick ending point
for (int i = 0; i <= n - len; i++)
{
StringBuffer sb = new StringBuffer();
// Print characters from current
// starting point to current ending
// point.
int j = i + len - 1;
for (int k = i; k <= j; k++)
sb.append(set[k]+"");
count+=Main.regexWork(sb.toString());
}
}
System.out.println(count);
}
// Driver code
public static void main(String[] args)
{
String set ="abc:/b1c\\xy"; //Can be any string for which you are checking
printSubsets(set.toCharArray()); //Passing char array
}
}
I suppose you can use the following regex that satisfies your conditions -
[a-z]{1}[a-z0-9:]*\/{1}[a-z0-9]*\\[a-z]+
JAVA CODE -
String command = "abc:/b1c\\xy";
Pattern COMMAND_PATTERN = Pattern.compile("[a-z]{1}[a-z0-9:]*\\/[a-z0-9]*\\\\[a-z]+");
Matcher matcher = COMMAND_PATTERN.matcher(command);
while (matcher.find())
count++;
System.out.println("MATCH COUNT = " + count);
Related
Lets say I have String word = "hello12".
I need to have all possible combinations of special characters instead of numbers (characters I get when use shift+number). So, the result I want to get is hello12, hello!2, hello1#, hello!#.
What I did is created switch with all cases (1 = '!', 2 = '#'...) but I can't get how to code all the combinations. All I could code is change all the numbers with special symbols (code is below)
char[] passwordInCharArray;
for(int i=0; i<passwordList.length; i++){
for(int j = 0; j<passwordList[i].length(); j++){
if(Character.isDigit((passwordList[i].charAt(j)))){
passwordInCharArray = passwordList[i].toCharArray();
passwordInCharArray[j] = getSpecialSymbol(passwordList[i].charAt(j));
passwordList[i]=String.valueOf(passwordInCharArray);
}
}
}
Theory
Combinatory is often easier to express with recursive methods (methods that call themselves).
I think that the algorithm is more understandable with an example so let's take String word = hello12.
We will iterate on each character until a digit is found. The first one is 1. At this point, we can imagine the word been split in two by a virtual cursor:
hello is on the left side. We know that it won't change.
12 is on the right side. Each character is likely to be a digit and thus to change.
To retrieve all the possible combinations, we want to:
Keep the first part of the word
Compute all the possible combinations of the second part of the word
Append each of these combinations to the first part of the word
The following tree represents what we want to compute (the root is the first part of the word, each branch represent a combination)
hello
├───1
│ ├───2 (-> hello12)
│ └───# (-> hello1#)
└───!
├───2 (-> hello!2)
└───# (-> hello!#)
You want to write an algorithm that gathers all the branches of this tree.
Java Code
/!\ I advise you to try to implement what I described above before taking a look at the code: that's how we improve ourselves!
Here is the corresponding Java code:
public static void main(String[] args) {
Set<String> combinations = combinate("hello12");
combinations.forEach(System.out::println);
}
public static Set<String> combinate(String word) {
// Will hold all the combinations of word
Set<String> combinations = new HashSet<String>();
// The word is a combination (could be ignored if empty, though)
combinations.add(word);
// Iterate on each word's characters
for (int i = 0; i < word.toCharArray().length; i++) {
char character = word.toCharArray()[i];
// If the character should be replaced...
if (Character.isDigit(character)) {
// ... we split the word in two at the character's position & pay attention not be exceed word's length
String firstWordPart = word.substring(0, i);
boolean isWordEnd = i + 1 >= word.length();
String secondWordPart = isWordEnd ? "" : word.substring(i + 1);
// Here is the trick: we compute all combinations of the second word part...
Set<String> allCombinationsOfSecondPart = combinate(secondWordPart);
// ... and we append each of them to the first word part one by one
for (String string : allCombinationsOfSecondPart) {
String combination = firstWordPart + getSpecialSymbol(character) + string;
combinations.add(combination);
}
}
}
return combinations;
}
Please leave a comment if you want me to explain the algorithm further.
Building on the code from: Generate All Possible Combinations - Java, I've come up with this implementation that does what you need. It will find the index of all digits in your string and then generate all possibilities in which they can be replaced with the special characters.
import java.util.*;
public class Comb {
public static List<String> combinations(String pass) {
String replace = ")!##$%^&*(";
char[] password = pass.toCharArray();
List<Integer> index = new ArrayList<Integer>();
List<String> results = new ArrayList<String>();
results.add(pass);
//find all digits
for (int i = 0; i < password.length; i++) {
if (Character.isDigit(password[i])) {
index.add(i);
}
}
//generate combinations
int N = (int) Math.pow(2d, Double.valueOf(index.size()));
for (int i = 1; i < N; i++) {
String code = Integer.toBinaryString(N | i).substring(1);
char[] p = Arrays.copyOf(password, password.length);
//replace the digits with special chars
for (int j = 0; j < index.size(); j++) {
if (code.charAt(j) == '1') {
p[index.get(j)] = replace.charAt(p[index.get(j)] - '0');
}
}
results.add(String.valueOf(p));
}
return results;
}
public static void main(String... args) {
System.out.println(combinations("hello12"));
}
}
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.
I want a regex to match a single letter in a string (from A to Z in order):
It should find the letter 'A', if there are no 'A's, it should find the letter 'B', then 'C', and so on...
Examples ->
BCDAE
CBDE -> Since there's no 'A's, it matches with B
YXZ
BAAC -> Since there're two 'A's, it finds the leftmost
character first.
Extra Information:
I'd provide an example, as some users don't seem to like questions without code.
Given a lower case string remove k characters from that string. First
remove all letter 'a', followed by letter 'b', then 'c', etc..
.This was my solution:
public static String remove(String s, int k) {
for (int c : s.chars().sorted().limit(k).toArray())
s = s.replaceFirst(Character.toString((char) c), "");
return s;
}
But I'd like to try this with a regex like:
public static String remove(String s, int k) {
while (k-- > 0)
s = s.replaceFirst(MY_MAGIC_REGEX_STR, "");
return s;
}
Regex might not be the best tool suited for this problem. I think the easiest thing to do here is to just convert your input string to an array of characters, and then walk down that array, keeping track of what the minimum (smallest) character is:
public char findLowestChar(String input) {
char[] array = input.toCharArray();
char chr = 'Z'; // works so long as input is non-empty
for (int i=0; i < array.length; ++i) {
if (array[i] < chr) {
chr = array[i];
}
}
return chr;
}
I am assuming here that the input string would always have at least one letter A-Z in it. If not, and you also wanted to implement this inside a method, then you should also handle the empty input case.
Edit:
You just substantially changed your question. But it turns out the above code can still be part of the updated answer. You can now iterate k times, and at each step run the above code to find the lowest letter. Then, do a String#replaceAll to remove all occurrences of that letter.
String input = "BCDAE";
// remove k=4 characters, starting with (maybe) A, from the input string
for (int k=0; k < 4 && input.length() > 0; ++k) {
char lowest = findLowestChar(input);
input = input.replaceAll(String.valueOf(lowest), "");
}
The following regex works as desired:
(?i)A|B(?!.*[A-A])|C(?!.*[A-B])|D(?!.*[A-C])|E(?!.*[A-D])|F(?!.*[A-E])|G(?!.*[A-F])|H(?!.*[A-G])|I(?!.*[A-H])|J(?!.*[A-I])|K(?!.*[A-J])|L(?!.*[A-K])|M(?!.*[A-L])|N(?!.*[A-M])|O(?!.*[A-N])|P(?!.*[A-O])|Q(?!.*[A-P])|R(?!.*[A-Q])|S(?!.*[A-R])|T(?!.*[A-S])|U(?!.*[A-T])|V(?!.*[A-U])|W(?!.*[A-V])|X(?!.*[A-W])|Y(?!.*[A-X])|Z(?!.*[A-Y])
The regex consists of 26 terms (one term per letter) which are concatenated via the alternation-operator (|). The A(?!B) is the negative look ahead operator which match A if A is not followed by B.The (?i) simply triggers case insensitivity.
On the whole the regex finds first all A's from left to right, than all B's from left to right and so on.
Because of the length of the regex it is more comfortable to generate it programmatically:
// Generate regEx
String regEx = "(?i)" + "A" + "|";
for (char i = 'B'; i <= 'Z'; i++ ) {
regEx += i + "(?!.*[A-" + (char)(i-1) + "])" + "|";
}
regEx = regEx.substring(0, regEx.length() - 1);
System.out.println(regEx);
For the following example:
String example = "AAAZZZHHAAAZZHHHAAZZZHH";
// Output
while(example.length() != 0) {
System.out.println(example);
example = example.replaceFirst(regEx, "");
}
the output is:
AAAZZZHHAAAZZHHHAAZZZHH
AAZZZHHAAAZZHHHAAZZZHH
AZZZHHAAAZZHHHAAZZZHH
ZZZHHAAAZZHHHAAZZZHH
ZZZHHAAZZHHHAAZZZHH
ZZZHHAZZHHHAAZZZHH
ZZZHHZZHHHAAZZZHH
ZZZHHZZHHHAZZZHH
ZZZHHZZHHHZZZHH
ZZZHZZHHHZZZHH
ZZZZZHHHZZZHH
ZZZZZHHZZZHH
ZZZZZHZZZHH
ZZZZZZZZHH
ZZZZZZZZH
ZZZZZZZZ
ZZZZZZZ
ZZZZZZ
ZZZZZ
ZZZZ
ZZZ
ZZ
Z
I am trying to make a program to find the longest a palindrome within a string.
E.g., Banana -> anana
I have made a for loop to reverse the inputted string and I can make it check each time if it is a palindrome but I'm not sure it will work since the palindrome may not start at the first letter of the string.
Right now, my programs output is the following:
a
an
ana
anan
anana
ananab
In this case it would work but if the input was, say, abracadabra, the two palindromes within would be ace and ada but the program would not find it properly.
Here is my code:
public class Palindrome {
public static void main(String[] args) {
String string = "banana";
String reverse = "";
int length = string.length() - 1;
for (int i = length; i >= 0; i--) {
reverse = reverse + string.charAt(i);
System.out.println(reverse);
}
}
}
My method considers all possible substrings of the input string. For each substring it uses StringBuilder.reverse() to reverse the substring and then compare it to the original substring to determine if it was a palindrome.
private static Collection<String> longestPalindromesIn(String input) {
// longest palindromes found until now
Set<String> result = new HashSet<>();
// length of longest palindrome found until now (all strings in result have this length)
// initialize to a negative value to make sure that the first palindrome found will appear to be longer
int longest = -1;
// iterate over all possible substrings
for (int start = 0; start <= input.length(); start++) {
for (int end = start; end <= input.length(); end++) {
String currentSubstring = input.substring(start, end);
// only consider if at least as long as the longest palindrome already found
if (currentSubstring.length() >= longest) {
if (isPalindrome(currentSubstring)) {
if (currentSubstring.length() > longest) {
// discard palindromes shorter than the one we have just found
result.clear();
longest = currentSubstring.length();
}
result.add(currentSubstring);
}
}
}
}
return result;
}
private static boolean isPalindrome(String candidate) {
// the following is the easy way of reversing a string;
// you may use your own code instead if you prefer
StringBuilder reverse = new StringBuilder(candidate);
reverse.reverse();
return candidate.equals(reverse.toString());
}
For input banana the method returns a set of a single string, anana.
abracadabra gives two palindromes, aca and ada.
abca gives a, b and c. If there is no interesting palindrome (length 2 or more), the method just returns each letter. Once each, since the result is a Set and hence filters out duplicates.
If input is the empty string "", output is the empty string too. It is a palindrome after all.
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.