How to find vowels in a given string? - java

Just a simple code I'm trying to do.
String vowels = "aeiou";
if ( word.indexOf(vowels.toLowerCase()) == -1 ){
return word+"ay";
}
I've tried using this code for checking if a word has no vowels and if so adds "ay" to it. So far no luck. I think my problem is somewhere around the indexOf method, can anyone explain it a bit more to me?

Something like this:
public String ModifyWord(String word){
String[] vowels = {"a","e","i","o","u"};
for (String v : vowels) {
if(word.indexOf(v) > -1){ // >-1 means the vowel is exist
return word;
}
}
return word+"ay"; //this line is executed only if vowel is not found
}

You could use a regular expression, and String.matches(String regex). First, a regular expression. The [AEIOUaeiou] is a vowel character class and the .*(s) are to consume any optional non-vowel(s).
String regex = ".*[AEIOUaeiou].*";
Then you can test your word like
if (word.matches(regex)) {
Note your vowels are already lowercase (no need to lowercase word here, the regular expression includes uppercase).

Related

Capitalize first letters in words in the string with different separators using java 8 stream

I need to capitalize first letter in every word in the string, BUT it's not so easy as it seems to be as the word is considered to be any sequence of letters, digits, "_" , "-", "`" while all other chars are considered to be separators, i.e. after them the next letter must be capitalized.
Example what program should do:
For input: "#he&llo wo!r^ld"
Output should be: "#He&Llo Wo!R^Ld"
There are questions that sound similar here, but there solutions really don't help.
This one for example:
String output = Arrays.stream(input.split("[\\s&]+"))
.map(t -> t.substring(0, 1).toUpperCase() + t.substring(1))
.collect(Collectors.joining(" "));
As in my task there can be various separators, this solution doesn't work.
It is possible to split a string and keep the delimiters, so taking into account the requirement for delimiters:
word is considered to be any sequence of letters, digits, "_" , "-", "`" while all other chars are considered to be separators
the pattern which keeps the delimiters in the result array would be: "((?<=[^-`\\w])|(?=[^-`\\w]))":
[^-`\\w]: all characters except -, backtick and word characters \w: [A-Za-z0-9_]
Then, the "words" are capitalized, and delimiters are kept as is:
static String capitalize(String input) {
if (null == input || 0 == input.length()) {
return input;
}
return Arrays.stream(input.split("((?<=[^-`\\w])|(?=[^-`\\w]))"))
.map(s -> s.matches("[-`\\w]+") ? Character.toUpperCase(s.charAt(0)) + s.substring(1) : s)
.collect(Collectors.joining(""));
}
Tests:
System.out.println(capitalize("#he&l_lo-wo!r^ld"));
System.out.println(capitalize("#`he`&l+lo wo!r^ld"));
Output:
#He&l_lo-wo!R^Ld
#`he`&L+Lo Wo!R^Ld
Update
If it is needed to process not only ASCII set of characters but apply to other alphabets or character sets (e.g. Cyrillic, Greek, etc.), POSIX class \\p{IsWord} may be used and matching of Unicode characters needs to be enabled using pattern flag (?U):
static String capitalizeUnicode(String input) {
if (null == input || 0 == input.length()) {
return input;
}
return Arrays.stream(input.split("(?U)((?<=[^-`\\p{IsWord}])|(?=[^-`\\p{IsWord}]))")
.map(s -> s.matches("(?U)[-`\\p{IsWord}]+") ? Character.toUpperCase(s.charAt(0)) + s.substring(1) : s)
.collect(Collectors.joining(""));
}
Test:
System.out.println(capitalizeUnicode("#he&l_lo-wo!r^ld"));
System.out.println(capitalizeUnicode("#привет&`ёж`+дос^βιδ/ως"));
Output:
#He&L_lo-wo!R^Ld
#Привет&`ёж`+Дос^Βιδ/Ως
You can't use split that easily - split will eliminate the separators and give you only the things in between. As you need the separators, no can do.
One real dirty trick is to use something called 'lookahead'. That argument you pass to split is a regular expression. Most 'characters' in a regexp have the property that they consume the matching input. If you do input.split("\\s+") then that doesn't 'just' split on whitespace, it also consumes them: The whitespace is no longer part of the individual entries in your string array.
However, consider ^ and $. or \\b. These still match things but don't consume anything. You don't consume 'end of string'. In fact, ^^^hello$$$ matches the string "hello" just as well. You can do this yourself, using lookahead: It matches when the lookahead is there but does not consume it:
String[] args = "Hello World$Huh Weird".split("(?=[\\s_$-]+)");
for (String arg : args) System.out.println("*" + args[i] + "*");
Unfortunately, this 'works', in that it saves your separators, but isn't getting you all that much closer to a solution:
*Hello*
* World*
*$Huh*
* *
* *
* Weird*
You can go with lookbehind as well, but it's limited; they don't do variable length, for example.
The conclusion should rapidly become: Actually, doing this with split is a mistake.
Then, once split is off the table, you should no longer use streams, either: Streams don't do well once you need to know stuff about the previous element in a stream to do the job: A stream of characters doesn't work, as you need to know if the previous character was a non-letter or not.
In general, "I want to do X, and use Y" is a mistake. Keep an open mind. It's akin to asking: "I want to butter my toast, and use a hammer to do it". Oookaaaaayyyy, you can probably do that, but, eh, why? There are butter knives right there in the drawer, just.. put down the hammer, that's toast. Not a nail.
Same here.
A simple loop can take care of this, no problem:
private static final String BREAK_CHARS = "&-_`";
public String toTitleCase(String input) {
StringBuilder out = new StringBuilder();
boolean atBreak = true;
for (char c : input.toCharArray()) {
out.append(atBreak ? Character.toUpperCase(c) : c);
atBreak = Character.isWhitespace(c) || (BREAK_CHARS.indexOf(c) > -1);
}
return out.toString();
}
Simple. Efficient. Easy to read. Easy to modify. For example, if you want to go with 'any non-letter counts', trivial: atBreak = Character.isLetter(c);.
Contrast to the stream solution which is fragile, weird, far less efficient, and requires a regexp that needs half a page's worth of comment for anybody to understand it.
Can you do this with streams? Yes. You can butter toast with a hammer, too. Doesn't make it a good idea though. Put down the hammer!
You can use a simple FSM as you iterate over the characters in the string, with two states, either in a word, or not in a word. If you are not in a word and the next character is a letter, convert it to upper case, otherwise, if it is not a letter or if you are already in a word, simply copy it unmodified.
boolean isWord(int c) {
return c == '`' || c == '_' || c == '-' || Character.isLetter(c) || Character.isDigit(c);
}
String capitalize(String s) {
StringBuilder sb = new StringBuilder();
boolean inWord = false;
for (int c : s.codePoints().toArray()) {
if (!inWord && Character.isLetter(c)) {
sb.appendCodePoint(Character.toUpperCase(c));
} else {
sb.appendCodePoint(c);
}
inWord = isWord(c);
}
return sb.toString();
}
Note: I have used codePoints(), appendCodePoint(int), and int so that characters outside the basic multilingual plane (with code points greater than 64k) are handled correctly.
I need to capitalize first letter in every word
Here is one way to do it. Admittedly this is a might longer but your requirement to change the first letter to upper case (not first digit or first non-letter) required a helper method. Otherwise it would have been easier. Some others seemed to have missed this point.
Establish word pattern, and test data.
String wordPattern = "[\\w_-`]+";
Pattern p = Pattern.compile(wordPattern);
String[] inputData = { "#he&llo wo!r^ld", "0hel`lo-w0rld" };
Now this simply finds each successive word in the string based on the established regular expression. As each word is found, it changes the first letter in the word to upper case and then puts it in a string buffer in the correct position where the match was found.
for (String input : inputData) {
StringBuilder sb = new StringBuilder(input);
Matcher m = p.matcher(input);
while (m.find()) {
sb.replace(m.start(), m.end(),
upperFirstLetter(m.group()));
}
System.out.println(input + " -> " + sb);
}
prints
#he&llo wo!r^ld -> #He&Llo Wo!R^Ld
0hel`lo-w0rld -> 0Hel`lo-W0rld
Since words may start with digits, and the requirement was to convert the first letter (not character) to upper case. This method finds the first letter, converts it to upper case and
returns the new string. So 01_hello would become 01_Hello
public static String upperFirstLetter(String word) {
char[] chs = word.toCharArray();
for (int i = 0; i < chs.length; i++) {
if (Character.isLetter(chs[i])) {
chs[i] = Character.toUpperCase(chs[i]);
break;
}
}
return String.valueOf(chs);
}

How to search for substrings

I'm looking for patterns like "tip" and "top" in the string -- length-3, starting with 't' and ending with 'p'. The goal is to return a string where for all such words, the middle letter is gone. So for example, "tipXtap" yields "tpXtp".
So far, I've thought about using recursion, and the replace() method, but am not sure if that is the best way to approach this problem.
Here is my code thus far:
String result = "";
if(str.length() < 3)
return str;
for(int i = 0; i <= str.length() - 2; i++){
if(str.charAt(i) == 't' && str.charAt(i + 2) == 'p'){
str.replaceAll(str.substring(i + 1, i + 2), "");
}
return str;
}
return str;
Use this Java code:
String str = "tipXtap";
str = str.replaceAll("t.p", "tp");
This uses regular expressions and the String.replaceAll function. The . (dot) character is a regex metacharacter that matches any single character.
One way of doing this.
Convert the String to a char array.
Use if conditions to validate first and third letter from the first letter. First look whether a char of a String is T and then check the char two chars away is a 'p'. You have to do this inside a loop traversing the char array.
If the validation condition is true, remove the middle element. You will have to move the element in the char array.
Convert the char array to a String and return it.
Hope this helps.
Here's a JavaScript solution to this problem using regular expressions:
foo = 'tipXtop'
foo.replace(/t\wp/g, 'tp')
The \w regex operator matches a word character like a-z, A-Z, 0-9 or _.
The g regex flag will match all instances of the regex in the string.

CodingBat Java exercise about word matching doesn't make sense

So the question goes like this:
Given a string and a second "word" string, we'll say that the word matches the string if it appears at the front of the string, except its first char does not need to match exactly. On a match, return the front of the string, or otherwise return the empty string. So, so with the string "hippo" the word "hi" returns "hi" and "xip" returns "hip". The word will be at least length 1. "
First off, I have no clue what the question is even asking. Second, I looked up a solution to it and I don't get the solution either. Can someone help me comprehend what is even happening? Is there an alternate way of doing this?
public String startWord(String str, String word) {
if (str.length() < 1) {
return "";
}
if (str.substring(1).indexOf(word.substring(1)) != 0) { // I am utterly confused here, wouldn't this always be true if it starts beyond zero?
return "";
}
return str.substring(0, word.length());
}
First off, I have no clue what the question is even asking.
You have a first string and a second string (word).
The word matches the first string if
The word matches the beginning of the first string.
The word matches the beginning of the first string even if the first letter of the word doesn't match the first letter of the front string.
If the word matches the first string, return the first word length characters of the first string. Otherwise, return an empty string.
The word will be at least length 1.
Second, I looked up a solution to it and I don't get the solution either. Can someone help me comprehend what is even happening?
Here's my solution to startWord. I hope it makes more sense.
public String startWord(String str, String word) {
String x = word.substring(1);
if (str.startsWith(x, 1)) {
return str.substring(0, word.length());
} else {
return "";
}
}
You're tasked with seeing if a string, str, starts with word. But you're not matching the first character. That's why you use "1" to specify you want only the string and word starting the second character. "0" would represent the first character. The "indexOf" method of a string searches for an instance of the word you pass in, and returns the index..the character number... where the match was found. So if it was found at the start..the first character... it'd return 0. Because you chopped off the first character of both using substring, you're just looking for a match at character 0.
If the index was not found at 0 (-1 for not found, or greater than 0 for word being found, but not in the beginning of str), then it's returning an empty string.
A slight alteration would be to chop off only the first character of "word" and see if it's found at index 1 of str. But it's simpler to chop off the first character of both and see if they line up at the start.
Another variation would be to do a "regex" pattern match, but that's going to be unnecessarily confusing for you.
Original str: "woogie"
Original word: "goog"
Is it a match?
Hack off the first character:
Shortened str: "oogie"
Shortened word: "oog"
"oog" is found to start at position 0 of "oogie", so indexOf returns 0.
public String startWord(String str, String word) {
int len1 = str.length();
int len2 = word.length();
String withoutFirst = word.substring(1,len2);
String result = "";
if(len1>=len2 && len2>0){
if(str.substring(0,len2).equals(word)){
result = word;
}else if(word.substring(1,len2).equals(str.substring(1,len2))){
result = str.substring(0,1) + word.substring(1,len2);
}
}else{
result = "";
}
return result;
}

Use regex to replace sequences in a string with modified characters

I am trying to solve a codingbat problem using regular expressions whether it works on the website or not.
So far, I have the following code which does not add a * between the two consecutive equal characters. Instead, it just bulldozes over them and replaces them with a set string.
public String pairStar(String str) {
Pattern pattern = Pattern.compile("([a-z])\\1", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
if(matcher.find())
matcher.replaceAll(str);//this is where I don't know what to do
return str;
}
I want to know how I could keep using regex and replace the whole string. If needed, I think a recursive system could help.
This works:
while(str.matches(".*(.)\\1.*")) {
str = str.replaceAll("(.)\\1", "$1*$1");
}
return str;
Explanation of the regex:
The search regex (.)\\1:
(.) means "any character" (the .) and the brackets create a group - group 1 (the first left bracket)
\\1, which in regex is \1 (a java literal String must escape a backslash with another backslash) means "the first group" - this kind of term is called a "back reference"
So together (.)\1 means "any repeated character"
The replacement regex $1*$1:
The $1 term means "the content captured as group 1"
Recursive solution:
Technically, the solution called for on that site is a recursive solution, so here is recursive implementation:
public String pairStar(String str) {
if (!str.matches(".*(.)\\1.*")) return str;
return pairStar(str.replaceAll("(.)\\1", "$1*$1"));
}
FWIW, here's a non-recursive solution:
public String pairStar(String str) {
int len = str.length();
StringBuilder sb = new StringBuilder(len*2);
char last = '\0';
for (int i=0; i < len; ++i) {
char c = str.charAt(i);
if (c == last) sb.append('*');
sb.append(c);
last = c;
}
return sb.toString();
}
I dont know java, but I believe there is replace function for string in java or with regular expression. Your match string would be
([a-z])\\1
And the replace string would be
$1*$1
After some searching I think you are looking for this,
str.replaceAll("([a-z])\\1", "$1*$1").replaceAll("([a-z])\\1", "$1*$1");
This is my own solutions.
Recursive solution (which is probably more or less the solution that the problem is designed for)
public String pairStar(String str) {
if (str.length() <= 1) return str;
else return str.charAt(0) +
(str.charAt(0) == str.charAt(1) ? "*" : "") +
pairStar(str.substring(1));
}
If you want to complain about substring, then you can write a helper function pairStar(String str, int index) which does the actual recursion work.
Regex one-liner one-function-call solution
public String pairStar(String str) {
return str.replaceAll("(.)(?=\\1)", "$1*");
}
Both solution has the same spirit. They both check whether the current character is the same as the next character or not. If they are the same then insert a * between the 2 identical characters. Then we move on to check the next character. This is to produce the expected output a*a*a*a from input aaaa.
The normal regex solution of "(.)\\1" has a problem: it consumes 2 characters per match. As a result, we failed to compare whether the character after the 2nd character is the same character. The look-ahead is used to resolve this problem - it will do comparison with the next character without consuming it.
This is similar to the recursive solution, where we compare the next character str.charAt(0) == str.charAt(1), while calling the function recursively on the substring with only the current character removed pairStar(str.substring(1).

RegEx to match strings that have only one C

I am looking for some tips on how I can take a string like:
KIGABCCA TQABCCAXT
GABCCASZYU GZTTABCCA MHNBABCCA CLZGABCA ABCCALZH
ABCCADQRNS VIZABCCA GABCCAG
UEKABCCA KBTOABCCA GABCCAMFFJ HABCCAISOJ OFJJABCCA HPABCCA
WBXRABCCA
ABCCAKH
VABCCAJX WBDOABCCA ABCCAWM GCABCA QHRABCCA
ABCCAMDDD WPABCCAD OGABCCA
TVABCCA JGLABCA
IUABCCA
and to return any entire string with only one C in it.
PLEASE NOTE: I AM NOT LOOKING FOR A SOLUTION!
Just some pointers or a description of the sort of constructs I should be looking at.
I have been labouring over it for ages, and have come close to hurting someone because of this. It is a homework question and I'm not looking to cheat, just some guidance.
I have read extensively about Reg Ex and I understand them.
I'm not looking for a beginners guide.
You want to first put a word boundary at the start and end. Then match any character that isn't C or a word boundary 0 or more times, then a C, then again, any character that isn't a C or word boundary 0 or more times. So it'll match a C on it's own, or a C with any non-C characters either (or both) side of it.
The no-C or word boundary you could do in two ways... say "any character that isn't a C or word boundary" or you could say "I want A, B or anything from D-Z". Up to you.
Search for a pattern that has the following elements, in order:
The beginning of the string or any whitespace.
Zero or more non-whitespace non-C characters.
A "C"
Zero or more non-whitespace non-C characters.
The end of the string or any whitespace.
you can create a count function. then pass each string to it. just an example
String string = "KIGABCCA"
public static boolean countChar(String string, char ch){
int count =0;
for(int i = 0; i<string.length();i++){
if(string.charAt(i) == ch ){
count++;
}
}
if ( count == 1){
return true;
}else {
return false;
}
}

Categories

Resources