"Exception:java.lang.StringIndexOutOfBoundsException: String index out of range" - java

Here is the problem: Return true if the string "cat" and "dog" appear the same number of times in the given string. Examples: catDog("catdog") → true; catDog("catcat") → false; catDog("1cat1cadodog") → true
public boolean catDog(String str) {
int countCat=0;
int countDog=0;
for (int i=0; i<str.length();i++)
{
if (str.charAt(i)== 'c'&& str.length()>=3)
{
if (str.substring(i,i+3).equals("cat"))
countCat++;
}
}
for (int i=0; i<str.length();i++)
{
if (str.charAt(i)== 'd' && str.length()>=3)
{
if (str.substring(i,i+3).equals("dog"))
countDog++;
}
}
if (countCat == countDog)
return true;
else
return false;
}

In your for loops conditions you are checking if entire String has length greater or equal 3 instead of checking only part from i till end. Try maybe with
str.length() - i >= 3
instead of
str.length() >= 3

str.substring(i,i+3).equals("cat")
i might be the last and i+3 will give an error

Why don't you simply use StringUtils#countMatches?
StringUtils.countMatches(myStr, "cat") == StringUtils.countMatches(myStr, "dog");
Don't get lost with the indexes. However, if you don't want to use this method, debugging your code is the best thing you can do.

Okay, this is what I might do:
The problem was with your check str.length() >= 3. It should have been i + str.length().
I also suggest some changes to your code to get rid of duplication. Here I extracted the part that counts the number of appearances of a substring and moved it to its own method. The part that checks if count of cat equals count of dog now calls said method twice.
public static void main(String[] args) {
System.out.println(catDog("catdog"));
System.out.println(catDog("catcat"));
System.out.println(catDog("1cat1cadodog"));
System.out.println(catDog("catdogcatc"));//Would previously throw error.
}
public static boolean catDog(String str) {
int countCat = countAppearances(str, "cat");
int countDog = countAppearances(str, "dog");
return countCat == countDog;
}
private static int countAppearances(String str, String key) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == key.charAt(0) && i + key.length() <= str.length()) {
if (str.substring(i, i + key.length()).equals(key)) {
count++;
}
}
}
return count;
}

You need to update your first condition before spiting you string like:
if (str.charAt(i)== 'c' && (str.length() - i) >= 3)
{
if (str.substring(i,i+3).equals("cat"))
countCat++;
}

public boolean catDog(String str) {
int catCount = 0, dogCount = 0;
//run a for loop to check cat count
//run loop till 2nd last character
for (int i = 0; i < str.length() - 2; i++) {
//now check if the charaters at positions matches "cat"
//if matches then increment cat count
if (str.charAt(i) == 'c' && str.charAt(i + 1) == 'a' && str.charAt(i + 2) == 't') {
catCount++;
} else if (str.charAt(i) == 'd' && str.charAt(i + 1) == 'o' && str.charAt(i + 2) == 'g') {
//else check if the charaters at positions matches "dog"
//if matches then increment dog count
dogCount++;
}
}
//check cat count and dog count
if (catCount == dogCount) {
return true;
} else {
return false;
}
}

Related

Rewriting a for loop as recursive method?

I am having trouble rewriting the following code as a recursive method rather than using the for loop. The for loop tests to see if the String 'noSpaces' is a palindrome (the same forwards as it is backwards). The noSpaces String has no punctuation, spaces, or differences in capitalization.
Thanks for the help
public boolean isRegularPalindrome(String noSpaces) {
noSpaces = noSpaces.toUpperCase();
String[] letters = new String[noSpaces.length()];
for (int i = 0; i < letters.length; i++) {
letters[i] = Character.toString(noSpaces.charAt(i));
}
for (int i = 0; i < letters.length / 2; i++) {
if (!letters[i].equals(letters[letters.length - i - 1])) {
return false;
}
}
return true;
}
There you go:
public static boolean isPalindrome(String input) {
if (input.charAt(0) != input.charAt(input.length() - 1)) {
// Missmatch. Not a palindrome!
return false;
} else if (input.length() > 1){
// If there is more to test, continue.
return isPalindrome(input.substring(1, input.length() - 1));
} else {
// All chars were tested, or 1 char input. Palindrome!
return true;
}
}
Writing a recursive algorithm for anything requires base cases. For a palindrome, this would be a string of length 0 or length 1 -- if the string is length 0 or 1, it is a palindrome.
If the base cases aren't met, you check the first character against the last character.
If the characters aren't the same, return false.
If the characters are the same, return the recursive call to the string except for the first and last characters.
The code should look something like this.
public boolean isPalindrome(string str){
if (str.length == 0)
return true;
else if (str.length == 1)
return true;
else if(str.charAt(0) != str.charAt(str.length - 1)
return false;
else
return isPalindrome(str.substring(1, length - 1));
}

How to replace a char in a string without using Replace() in Java?

I've been having trouble with this assignment:
Given a string, replace the first occurrence of 'a' with "x", the second occurrence of 'a' with "xx" and the third occurrence of 'a' with "xxx". After the third occurrence, begin the replacement pattern over again with "x", "xx", "xxx"...etc.; however, if an 'a' is followed by more than 2 other 'a' characters in a row, then do not replace any more 'a' characters after that 'a'.
No use of the replace method is allowed.
aTo123X("ababba") → "xbxxbbxxx"
aTo123X("anaceeacdabnanbag") → "xnxxceexxxcdxbnxxnbxxxg"
aTo123X("aabaaaavfaajaaj") → "xxxbxxxaaavfaajaaj"
aTo123X("pakaaajaaaamnbaa") → "pxkxxxxxxjxxaaamnbaa"
aTo123X("aaaak") → "xaaak"
My code's output is with a's included, x's added but not the correct amount of x's.
public String aTo123X(String str) {
/*
Strategy:
get string length of the code, and create a for loop in order to find each individual part of the String chars.check for a values in string and take in pos of the a.
if one of the characters is a
replace with 1 x, however, there aren't more than 2 a's immediately following first a and as it keeps searching through the index, add more x's to the original string, but set x value back to 1 when x reaches 3.
if one of characters isn't a,
leave as is and continue string.
*/
String xVal = "";
String x = "x";
String output = "";
for (int i = 0; i < str.length(); i++){
if( str.charAt(i) == 'a'){
output += x;
str.substring(i+1, str.length());
}
output += str.charAt(i);
}
return output;
}
This is the code that does the same. I've commented the code to explain what it does
public class ReplaceChar {
public static void main(String... args){
String[] input =new String[]{"ababba","anaceeacdabnanbag","aabaaaavfaajaaj"};
StringBuilder result = new StringBuilder();
for (int i= 0; i < input.length;i++){
result.append(getReplacedA(input[i]));
result.append("\n");
}
System.out.println(result);
}
private static String getReplacedA(String withA){
// stringBuilder for result
StringBuilder replacedString = new StringBuilder();
// counting the number of time char 'a' occurred in String for replacement before row of 'aaa'
int charACount = 0;
// get the first index at which more than two 'aa' occurred in a row
int firstIndexOfAAA = withA.indexOf("aaa") + 1;
// if 'aaa' not occurred no need to add the rest substring
boolean addSubRequired = false;
// if the index is 0 continue till end
if (firstIndexOfAAA == 0)
firstIndexOfAAA = withA.length();
else
addSubRequired = true;
char[] charString = withA.toCharArray();
//Replace character String[] array
String[] replace = new String[]{"x","xx","xxx"};
for(int i = 0; i < firstIndexOfAAA; i++){
if (charString[i] == 'a'){
charACount++;
charACount = charACount > 3 ? 1 : charACount ;
// add the number x based on charCount
replacedString.append(replace[charACount - 1]);
}else{
replacedString.append(charString[i]);
}
}
// if the String 'aaa' has been found previously add the remaining subString
// after that index
if (addSubRequired)
replacedString.append(withA.substring(firstIndexOfAAA));
// return the result
return replacedString.toString();
}
}
Output:
xbxxbbxxx
xnxxceexxxcdxbnxxnbxxxg
xxxbxxxaaavfaajaaj
EDIT : Some Improvement You can make for some corner cases in the getReplacedA() function:
Check if char 'a' is there or not in the String if not just return the String No need to do anything further.
Use IgnoreCase to avoid the uppercase or lowercase possibility.
Firstly, string is immutable, so the below statement does nothing
str.substring(i+1, str.length());
I guess you wanted to do:
str = str.substring(i+1, str.length());
However, even after fix that, your program still doesn't work. I can't really comprehend your solution. 1) you are not detecting more than 3 a's in a row. 2) you are not appending "xx" or "xxx" at all
Here is my version, works for me so far:
public static void main(String[] args) {
System.out.println(aTo123X("ababba")); // "xbxxbbxxx"
System.out.println(aTo123X("anaceeacdabnanbag")); // "xnxxceexxxcdxbnxxnbxxxg"
System.out.println(aTo123X("aabaaaavfaajaaj")); // "xxxbxxxaaavfaajaaj"
}
public static String aTo123X(String str) {
String output = "";
int aOccurrence = 0;
String[] xs = {"x", "xx", "xxx"};
for (int i = 0; i < str.length(); ++i) {
if (str.charAt(i) == 'a') {
output += xs[aOccurrence % 3]; // append the x's depending on the number of a's we have seen, modulus 3 so that it forms a cycle of 3
if (i < str.length() - 3 && str.charAt(i + 1) == 'a' && str.charAt(i + 2) == 'a' && str.charAt(i + 3) == 'a') {//if an 'a' is followed by more than 2 other 'a' characters in a row
output += str.substring(i + 1);
break;
} else {
++aOccurrence; // increment the a's we have encountered so far
}
} else {
output += str.charAt(i); // append the character if it is not a
}
}
return output;
}
public class NewClass {
public static void main(String[] args) {
System.out.println(aTo123X("ababba")); // "xbxxbbxxx"
System.out.println(aTo123X("anaceeacdabnanbag")); // "xnxxceexxxcdxbnxxnbxxxg"
System.out.println(aTo123X("aabaaaavfaajaaj")); //xxxbxxxaaavfaajaaj
}
public static String aTo123X(String str) {
String output = "";
int aCount = 0;
int inRow = 0;
for (int i = 0; i < str.length();) {
if (str.charAt(i) == 'a') {
if (inRow <= 1) {
inRow++;
aCount++;
if (aCount == 1) {
output += "x";
} else if (aCount == 2) {
output += "xx";
} else {
output += "xxx";
aCount = 0;
}
boolean multiple = ((i + 1) < str.length()) && (str.charAt(i + 1) == 'a')
&& ((i + 2) < str.length()) && (str.charAt(i + 2) == 'a');
if (multiple) {
i++;
while (i < str.length()) {
output += str.charAt(i++);
}
return output;
}
} else {
output += str.charAt(i);
}
} else {
output += str.charAt(i);
inRow = 0;
}
i++;
}
return output;
}
}
I am pointing out problems in your code in form of comments in the code itself.
public String aTo123X(String str) {
//You are not using xVal variable in your code, hence it's obsolete
String xVal = "";
//You don't need x variable as you can simply use string concatenation
String x = "x";
String output = "";
for (int i = 0; i < str.length(); i++) {
/**
* Here, in "if" block you have not implmented any logic to replace the 2nd and
* 3rd occurence of 'a' with 'xx' and 'xxx' respectively. Also, substring() returns
* the sub-string of a string but you are not accepting that string anywhere, and
* you need not even use sub-string as "for" loop will cycle through all the
* characters in the string. If use sub-string method you code will only process
* alternative characters.
*/
if( str.charAt(i) == 'a') {
output += x;
str.substring(i+1, str.length());
}
/**
* Because of this statement a's are also returned, because this statement gets
* in both scenarios, whether the current character of string is a or not.
* But, this statement should get executed only when current character of the
* string is 'a'. So, in terms of coding this statement gets executed no matter
* "if" loop is executed or not, but it should get executed only when "if" loop
* is not executed. So, place this statement in else block.
*/
output += str.charAt(i);
}
return output;
}
I have implemented the logic for you. Here is Solution for your problem, just copy and run it. It passes all the specified test cases.
public String aTo123X(String str) {
String output = "";
int count = 1;
boolean flag = true;
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i) == 'a' && flag == true) {
switch(count) {
case 1: output += "x";
count++;
break;
case 2: output += "xx";
count++;
break;
case 3: output += "xxx";
count = 1;
break;
}
if ((str.charAt(i+1) == 'a' && str.charAt(i+2) == 'a') == true) {
flag = false;
}
}
else {
output += str.charAt(i);
}
}
return output;
}
I use Map To store where to replace
public static void main(String[] args) {
System.out.println(aTo123X("ababba"));//xbxxbbxxx
System.out.println(aTo123X("anaceeacdabnanbag"));//xnxxceexxxcdxbnxxnbxxxg
System.out.println(aTo123X("aabaaaavfaajaaj"));//xxxbxxxaaavfaajaaj
}
public static String aTo123X(String str){
String res = "";
int nthReplace = 1; //Integer to store the nth occurence to replace
//Map to store [key == position of 'a' to replace]
//[value == x or xx or xxx]
Map<Integer, String> toReplacePos = new HashMap<>();
//The loop to know which 'a' to replace
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i) == 'a'){
toReplacePos.put(i, nthReplace % 3 == 1 ? "x": (nthReplace % 3 == 2 ? "xx": "xxx"));
nthReplace++;
//Break if an 'a' is followed by more than 2 other 'a'
try {
if((str.charAt(i+1) == 'a')
&& (str.charAt(i+2) == 'a')
&& (str.charAt(i+3) == 'a')){
break;
}
} catch (StringIndexOutOfBoundsException e) {
}
}
}
//Do the replace
for (int i = 0; i < str.length(); i++) {
res += toReplacePos.containsKey(i) ? toReplacePos.get(i) : str.charAt(i);
}
return res;
}
I have edited my answer. This one is giving the correct solution:
public static void main (String[] args) throws InterruptedException, IOException, JSONException {
System.out.println(aTo123X("ababba")); //xbxxbbxxx
System.out.println(aTo123X("anaceeacdabnanbag")); //xnxxceexxxcdxbnxxnbxxxg
System.out.println(aTo123X("aabaaaavfaajaaj")); //xxxbxxxaaavfaajaaj
}
public static String aTo123X(String str) {
String x = "x";
String xx = "xx";
String xxx = "xxx";
int a = 1;
int brek = 0;
String output = "";
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i) == 'a' && a == 1) {
output += x;
str.substring(i+1, str.length());
a = 2;
try {
if(str.charAt(i+1) == 'a' && str.charAt(i+2) == 'a')
brek += 1;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(str.charAt(i) == 'a' && a == 2) {
output += xx;
str.substring(i+1, str.length());
a = 3;
try {
if(str.charAt(i+1) == 'a' && str.charAt(i+2) == 'a')
brek += 1;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(str.charAt(i) == 'a' && a == 3) {
output += xxx;
str.substring(i+1, str.length());
a = 1;
try {
if(str.charAt(i+1) == 'a' && str.charAt(i+2) == 'a')
brek += 1;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
output += str.charAt(i);
brek = 0;
}
if(brek>0) {
output += str.substring(i+1);
break;
}
}
return output;
}

Why is this becoming an infinite loop?

All i need this method to do is take a string lets say "aaxbb" and it will return true because there is an 'aa' and a 'bb',
If the string given is length = 0 or length = 1 it should fail.
The issue i'm having is that which i do not know.. i know that in my terminal after hasAdjacentPair's first test case Pass's, i get a blinking curser meaning that somehwere in this method i'm not kicking out of one of my loops for it to continue to check the string for any more adjacent pairs
the first test case passes while its an empty string "" = because it returned false
the second test case passes while its "a" = because it returned false
We are also not allowed to use Arrays :(
public boolean hasAdjacentPair(String str)
{
boolean result = false;
if (str.length() == 0)
{
result = false;
}
if (str.length() == 1)
{
result = false;
}
while (str.length() != 0)
{
for (int i = 0; i < str.length() - 1; ++i)
{
char adjChar = str.charAt(i);
char nextAdjChar = str.charAt(i + 1);
if (adjChar == nextAdjChar)
{
result = true;
}
}
}
return result;
}
Changed my while loop while (str.length() != 0) to while (str.length() != 0 && str.length() != 1) this enabled test 2 to work
EDIT 2 : After i completely took out the while (str.length() != 0) All 5 of my test cases pass :) so i guess it was just that?
while (str.length() != 0)
is always true and loop never end. Instead of if..if..while structure use either switch on length of string or if-else.
You could try something like this
if (str.length() == 0)
{
result = false;
}
else if (str.length() == 1)
{
result = false;
}
else
{
for (int i = 0; i < str.length() - 1; ++i)
{
char adjChar = str.charAt(i);
char nextAdjChar = str.charAt(i + 1);
if (adjChar == nextAdjChar)
{
result = true;
break;
}
}
If you checking for atleast one pair make use of break statement as you already know that you got the result
try this alternative:
boolean c = false;
//Your other code
while (str.length() != 0 && c == false)
{
for (int i = 0; i < str.length() - 1; ++i)
{
char adjChar = str.charAt(i);
char nextAdjChar = str.charAt(i + 1);
if (adjChar == nextAdjChar)
{
result = true;
}
}
c = true;
}
//Your other code
Is there a reason you have a while loop checking for the str length? The str is not modified in the loop.
What you most likely want is an if, else if, else structure.
You can most likely return true within the adjChar == nextAdjChar if statement and return false at the end of your function.

Recursive Substrings out of bounds error

I have to create a recursive method to display all substrings of a given string before the letter 'A' or 'a', and ignore that letter in the process. The termination condition works fine. However, in the continue condition I am thrown a indexoutofbounds error and I'm not entirely sure why. As far as I can tell I stop the loop before the index reaches the string's length. but I will post it here in case I missed something.
class Tree
{
void subStrings(String s)
{
if(s.length() == 1)
{
if(s.charAt(0) == 'A' || s.charAt(0) == 'a')
{
System.out.println("Cannot shorten substring.");
}
else
{
System.out.println(s);
}
}
else
{
String subString = "";
int i = 0;
while(s.charAt(i) != 'A' && i < s.length())//bad line
{
subString += s.charAt(i);
i++;
}
if(subString.equals(""))
subStrings(s.substring(i));
else
{
System.out.println(subString);
subStrings(s.substring(i));
}
}
}
int treeHeight(String tree)
{
return 0;
}
}
Even Robby's refactoring won't get you where you won't on account of some other issues. For what concerns your exception you must iterate to i < s.length() - 1 since you're incrementing the index in the loop, and charAt method you use inside the loop starts at index 0.
Checked further and you should change your substring(i) to subStrings(s.substring(0, i)) otherwise you would end up with the same string in recursion. The following should work for you
void subStrings(String s)
{
if(s == null || s.length() == 0 || s.charAt(0) == 'A' || s.charAt(0) == 'a')
{
System.out.println("Cannot shorten substring.");
return;
}
if(s.length() != 1)
{
String subString = "";
int i = 0;
while(s.charAt(i) != 'A' && s.charAt(i) != 'a' && i < s.length() - 1)//bad line
{
subString += s.charAt(i);
i++;
}
if(subString.equals(""))
subStrings(s.substring(i));
else
{
System.out.println(subString);
subStrings(s.substring(0, i));
}
}
}
You need to reverse these two conditions:
while(s.charAt(i) != 'A' && i < s.length()) { /*...*/ }
So, it should be:
while(i < s.length() && s.charAt(i) != 'A') { /*...*/ }
Otherwise you get an out of bounds exception when the string is empty and you try to access the first character (at position 0).
If you just want to split a string using a or A as a delimiter, you might as well do:
String[] substrings = str.split("[aA]");
If it absolutely has to be implemented using a recursive method, instead of processing the string character by character, you could use indexOf to find the position of the next a or A. It could look something like this:
public static void subStrings(String s) {
int i = s.toLowerCase().indexOf('a');
if (i >= 0) {
System.out.println(s.substring(0, i));
if (i + 1 < s.length()) {
subStrings(s.substring(i + 1));
}
}
}

Count y and z at end of a word

This is the problem: Given a string, count the number of words ending in 'y' or 'z' -- so the 'y' in "heavy" and the 'z' in "fez" count, but not the 'y' in "yellow" (not case sensitive). We'll say that a y or z is at the end of a word if there is not an alphabetic letter immediately following it. (Note: Character.isLetter(char) tests if a char is an alphabetic letter.)
countYZ("fez day") → 2
countYZ("day fez") → 2
countYZ("day fyyyz") → 2
This is my code:
public int countYZ(String str) {
int count = 0;
for (int i=0; i<str.length(); i++){
if (Character.isLetter(i) && (Character.isLetter(i+1)==false || i+1==str.length()) && (Character.toLowerCase(str.charAt(i))=='y' || Character.toLowerCase(str.charAt(i))=='z')){
count++;
}
}
return count;
}
I know it's messy, but I'm just trying to figure out why it's not working right now. It returns "0" each run through. In the if statement, I'm checking for: is i a letter? is i+1 a letter or the end of the string? and finally if i is 'y' or 'z'. Appreciate the help!
You could use a regex:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public int countYZ(String str) {
int count = 0;
Pattern regex = Pattern.compile("[yz](?!\\p{L})", Pattern.CASE_INSENSITIVE);
Matcher regexMatcher = regex.matcher(str);
while (regexMatcher.find()) {
count++;
}
return count;
}
Explanation:
[yz] # Match the letter y or z
(?!\p{L}) # Assert that no letter follows after that
Use split() and endsWith()
public static int countYZ(String str) {
int count = 0;
String temp[] = str.split(" ");
for (int i = 0; i < temp.length; i++) {
if (temp[i].trim().endsWith("y") || temp[i].trim().endsWith("z"))
count++;
}
return count;
}
Output: for all your cases as required
countYZ("fez day") → 2
countYZ("day fez") → 2
countYZ("day fyyyz") → 2
try this fix
for (int i = 0; i < str.length(); i++) {
if ((Character.toLowerCase(str.charAt(i)) == 'y' || Character
.toLowerCase(str.charAt(i)) == 'z')
&& i == str.length() - 1
|| !Character.isLetter(str.charAt(i + 1))) {
count++;
}
}
Try This
public class CountXY {
/**
* #param args
*/
public static int countXY(String str){
int count = 0;
String strSplit[] = str.split(" ");
for(String i:strSplit){
if(i.endsWith("y")||i.endsWith("z")||i.endsWith("Y")||i.endsWith("Z")){
count++;
}
}
return count;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "Abcy Asdz z z z y y y yyu ZZ Y ";
System.out.println("Count::"+countXY(str));
}
}
public static int countYZ(String str) {
String[] array = str.split("[^a-zA-Z]");
int count = 0;
for (String s : array) {
if (s.toLowerCase().trim().endsWith("y") || s.toLowerCase().trim().endsWith("z"))
count++;
}
return count;
}
Your code is not working because following two conditions
Character.isLetter(i) --> here you are checking isLetter for the i which is int
(Character.isLetter(i+1)==false -> it will cause indexout of error
Please check following I have check its working fine, its just modified version of your code
public class FirstClass {
public static void main(String args[]) {
String string="fez day";
int count = 0;
String[] strcheck = string.split(" ");
for (String str : strcheck) {
if (Character.isLetter(str.charAt(str.length()-1)) &&(Character.toLowerCase(str.charAt(str.length()-1))=='y' || Character.toLowerCase(str.charAt(str.length()-1))=='z')){
count++;
}
}
System.out.println(count);
}
}
Hope this will help, Good Luck
You can try this too
public static void main(String[] args){
System.out.println(countYZ("abcxzy"));
}
public static int countYZ(String str) {
int countYandZ=0;
String[] arr=str.split(" ");
for (String i:arr){
if(("Y".equalsIgnoreCase(String.valueOf(i.charAt(i.length()-1))))||("Z".equalsIgnoreCase(String.valueOf(i.charAt(i.length()-1))))){
countYandZ++;
}
}
return countYandZ;
}
Here's what I've done:
public int countYZ(String str) {
//Initialize a return integer
int ret = 0;
//If it has at least 2 characters, we check both ends to see how many matching instances we have.
if (str.length() >= 2)
{
if (!Character.isLetter(str.charAt(1)) && (str.charAt(0) == 'y' || str.charAt(0) == 'Y' || str.charAt(0) == 'z' || str.charAt(0) == 'Z'))
{
ret++;
}
if (Character.isLetter(str.charAt(str.length() - 2)) && (str.charAt(str.length()-1) == 'y' || str.charAt(str.length()-1) == 'Y' || str.charAt(str.length()-1) == 'z' || str.charAt(str.length()-1) == 'Z'))
{
ret++;
}
}
//If it has more than 3 characters, we check the middle using a for loop.
if (str.length() >= 3)
{
for (int i = 2; i < str.length(); i++)
{
char testOne = str.charAt(i-2);
char testTwo = str.charAt(i-1);
char testThree = str.charAt(i);
//if the first char is a letter, second is a "YZyz" char, and the third is not a letter, we increment ret by 1.
if (Character.isLetter(testOne) && (testTwo == 'y' || testTwo == 'Y' || testTwo == 'z' || testTwo == 'Z') && (!Character.isLetter(testThree)))
{
ret++;
}
}
}
return ret;
}
public int countYZ(String str) {
int count=0;
if ( str.charAt(str.length() - 1) == 'z'||
str.charAt(str.length() - 1) == 'y'||
str.charAt(str.length() - 1) == 'Z'||
str.charAt(str.length() - 1) == 'Y' ) {
count += 1;
}
for (int i = 0; i < str.length(); i++) {
if ( i > 0 ) {
if ( !( Character.isLetter(str.charAt(i)) ) ) {
if ( str.charAt(i - 1) == 'y' ||
str.charAt(i - 1) == 'z' ||
str.charAt(i - 1) == 'Y' ||
str.charAt(i - 1) == 'Z' ) {
count += 1;
}
}
}
}
return count;
}
This allows the words to be separated by anything other than a letter. whitespace, numbers, etc.
public int countYZ(String str) {
int count = 0;
String newStr = str.toLowerCase();
for (int i =0; i < newStr.length(); i++){
if (!Character.isLetter(newStr.charAt(i))){
if (i > 0 && (newStr.charAt(i-1) == 'y' || newStr.charAt(i-1) == 'z'))
count++;
}
}
if (newStr.charAt(str.length()-1) == 'z' || newStr.charAt(str.length()-1) == 'y')
count++;
return count;
}

Categories

Resources