for loop gets to the end of the string - java

I'm practicing Java at CodingBat.com, and I have a problem.
zipZap("azbcpzpp") returns "azbcpzpp". Expected to return "azbcpzp"
Thanks
// http://codingbat.com/prob/p180759
// Look for patterns like "zip" and "zap" in the string -- length-3,
// starting with 'z' and ending with 'p'. Return a string where for
// all such words, the middle letter is gone, so "zipXzap" yields "zpXzp".
public String zipZap(String str) {
if (str.length() < 2)
return str;
String result = str.substring(0, 1);
for (int i=1; i < (str.length()-1) ; i++) {
if ((str.charAt(i-i) != 'z') || (str.charAt(i+1) != 'p'))
result += str.charAt(i);
}
result += str.substring(str.length()-1);
return result;
}

Change the if condition to if ((str.charAt(i - 1) != 'z') || (str.charAt(i + 1) != 'p')). Otherwise you always check if the char at index 0 is equal to 'z', because i-i is always 0.
public static String zipZap(String str)
{
if (str.length() < 2)
return str;
String result = str.substring(0, 1);
for (int i = 1; i < (str.length() - 1); i++)
{
if ((str.charAt(i - 1) != 'z') || (str.charAt(i + 1) != 'p'))
result += str.charAt(i);
}
result += str.substring(str.length() - 1);
return result;
}
Input: azbcpzpp
Output: azbcpzp

public String zipZap(String str) {
String temp="";
if(str.length()<=2){
return str;
}
for(int i=0;i<str.length();i++){
if(str.charAt(i)=='z' && str.charAt(i+2)=='p'){
temp=temp+str.charAt(i);
temp=temp+str.charAt(i+2);
i=i+2;
}
else {
temp=temp+str.charAt(i);
}
}
return temp;
}

public String zipZap(String str)
{
String res="";
if (str.length()<3) return str;
for (int i=0;i<str.length()-2;i++) {
if (str.charAt(i)=='z' && str.charAt(i+2)=='p'){
res = res + str.charAt(i)+str.charAt(i+2);
i+=2;
}
else
res = res + str.charAt(i);
}
if (str.charAt(str.length()-3)!='z')
res = res + str.substring(str.length()-2);
return res;
}

public String zipZap(String str) {
String g="";
if(str.length()<=2){
return str;
}
for(int i=0;i<str.length();i++){
if(str.charAt(i)=='z' && str.charAt(i+2)=='p'){
g=g+str.charAt(i);
g=g+str.charAt(i+2);
i=i+2;
}
else {
g=g+str.charAt(i);
}
}
return g;
}

peek left check for 'z' AND peek right check for 'p', if condition meets then skip loop iteration; else add the character at the index.
public static String zipZap(String str) {
StringBuilder answer = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if (!((i > 0 && str.charAt(i - 1) == 'z') &&
(i < str.length() - 1 && str.charAt(i + 1) == 'p'))) {
answer.append(str.charAt(i));
}
}
return answer.toString();
}

Related

Is the logic in my program close in terms of arriving to the solution?

I'm trying to count the number of times a letter appears in a string (aabcccccaaa) and placing the number of times that it does into a new string along with the corresponding letter. The problem's that I get a StringIndexOutOfBoundsException.
I kind of have a clue why but I think it's mainly because my logic is flawed with this problem.
Am I on the right track? What am I doing wrong and how can I fix it?
For example, the output should be a2b1c5a3
Here's my code:
public class Problem {
public static void main(String []args) {
String str = "aabcccccaaa";
System.out.println(compressBad(str));
}
public static String compressBad(String str) {
int countConsecutive = 0;
String compressedString = "";
for(int i = 0; i < str.length(); i++) {
if(str.charAt(i) != str.charAt(i + 1)) {
countConsecutive++;
compressedString += "" + str.charAt(i) + countConsecutive;
countConsecutive = 0;
}
}
return compressedString;
}
}
This line str.charAt(i + 1) will read out of bounds when i is the last index, i+1 is now out of bounds.
For what it's worth, here's what I would do :
public static String compressBad(final String str) {
if (str == null || str.length() < 0) {
return "";
}
int countConsecutive = 0;
StringBuilder sb = new StringBuilder();
char previousLetter = str.charAt(0);
for (char c : str.toCharArray()) {
if (c == previousLetter) {
countConsecutive++;
} else {
sb.append(previousLetter).append(countConsecutive);
previousLetter = c;
countConsecutive = 1;
}
}
sb.append(previousLetter).append(countConsecutive);
return sb.toString();
}

How do I avoid exception in the second iteration?

I'm trying to display the number of times a letter appears within a string and outputting it in a new string (compressedString).
For example: aabcccccaaa should display a2b1c5a3.
So far, I got a2 to display only because I've included the break statement. If I took that out, then I would get StringIndexOutOfBoundsException.
My question is: How would I continue going through the whole string to obtain the rest of the aforementioned output without getting StringIndexOutOfBoundsException?
I ran it through debugger but it still isn't clear to me.
public class Problem {
public static void main(String []args) {
String str = "aabcccccaaa";
System.out.println(compressBad(str));
}
public static String compressBad(String str) {
int countConsecutive = 0;
String compressedString = "";
for(int i = 0; i < str.length(); i++) {
countConsecutive++;
if(str.charAt(i) != str.charAt(i + 1)) {
compressedString += "" + str.charAt(i) + countConsecutive;
break;
}
}
return compressedString;
}
}
modify your for loop to terminate when i < str.length() - 1--this is because you are comparing the character at i to the character at i + 1, which makes your loop go out of bounds.
Try this
public class Problem {
public static void main(String []args) {
String str = "aaabc";
System.out.println(compressBad(str));
}
public static String compressBad(String str) {
int countConsecutive = 0;
String compressedString = "";
for(int i = 0; i < str.length(); i++) {
countConsecutive++;
//avoid index out of bounds error
if(str.length() == (i + 1)){
compressedString += ""+ str.charAt(i) + countConsecutive;
countConsecutive = 0;
break;
}
else if(str.charAt(i) != str.charAt(i + 1)){
compressedString += ""+ str.charAt(i) + countConsecutive;
countConsecutive = 0;
}
}
return compressedString;
}
}
The other answers have good solutions, but I thought I would just add what I came up with:
public class Problem {
public static void main(String []args) {
String str = "aabcccccaaa";
System.out.println(compressBad(str));
}
public static String compressBad(String str) {
if (str.length() == 1) return str + "1"; // Handles single character strings
int countConsecutive = 0;
String compressedString = "";
for (int i = 0; i < str.length(); i++) {
if (i > 0) {
countConsecutive++;
if (str.charAt(i) != str.charAt(i-1)) {
compressedString += "" + str.charAt(i-1) + countConsecutive;
countConsecutive = 0;
}
if (i == str.length()-1) {
countConsecutive++; // Needs to be incremented for the last character
compressedString += "" + str.charAt(i) + countConsecutive;
}
}
}
return compressedString;
}
}
Your condition should be like this:
if(i+1 < str.length() && str.charAt(i) != str.charAt(i + 1))
because when you are is at last index of your string then also you are comparing i'th index with i+1 th index.
But after correcting this, still, this code will not give you the expected output.
This is how I would change the code.
public static String compressBad(String str) {
String compressedString = "";
if (str != null && str.length() > 0) {
int countConsecutive = 1;
char prevChar = str.charAt(0);
for (int i = 1; i < str.length(); i++) {
if (str.charAt(i) != prevChar) {
// End of a run. Update compressedString and reset counters
compressedString += String.valueOf(prevChar) + countConsecutive;
prevChar = str.charAt(i);
countConsecutive = 1;
continue;
}
countConsecutive++;
}
compressedString += String.valueOf(prevChar) + countConsecutive;
}
return compressedString;
}
Mukit09 has already mentioned the reason for your StringIndexOutOfBoundsException.
I offer you a more efficient implementation, using String Builder for concatenating strings:
private static String comppressedString(String str) {
if(str == null || str.equals("")) {
return str;
}
if(str.length() == 1) {
return str + "1";
}
StringBuilder sb = new StringBuilder();
sb.append(str.charAt(0)); // Add first letter
int j = 1; // Counter for current sequence length.
for (int i = 0; i < str.length() - 1; i++) {
if(str.charAt(i) != str.charAt(i + 1)) { // end of characters sequence.
sb.append(j); // Add length of previous sequence.
if(j > 1) {
j = 1; // Minimum sequence length is 1
}
sb.append(str.charAt(i+1)); // Add character of next sequence.
} else {
j++; // increase counter, in order to get the length of the current sequence.
}
}
sb.append(j); // Add length of last sequence.
return sb.toString();
}
public static void main(String[] args) {
System.out.println(comppressedString("")); // empty string
System.out.println(comppressedString("a")); // a1
System.out.println(comppressedString("ab")); // a1b1
System.out.println(comppressedString("abba")); // a1b2a1
System.out.println(comppressedString("aabcccccaaa")); // a2b1c5a3
}

Merged String Checker at codewars

At a job interview, you are challenged to write an algorithm to check if a given string, s, can be formed from two other strings, part1 and part2.
The restriction is that the characters in part1 and part2 are in the same order as in s.
The interviewer gives you the following example and tells you to figure out the rest from the given test cases.
For example:
'codewars' is a merge from 'cdw' and 'oears':
See: https://www.codewars.com/kata/merged-string-checker/train/java
This is my java code,but couldn't pass all test.Excuse me, where is wrong?Thank you!
public static boolean isMerge(String s, String part1, String part2) {
s = s.replace(" ","");
part1 = part1.replace(" ","");
part2 = part2.replace(" ","");
int index1 = 0;
int index2 = 0;
char[] cp1 = part1.toCharArray();
char[] cp2 = part2.toCharArray();
for (int i = 0; i < s.length(); ) {
char is = s.charAt(i);
if (index1 < cp1.length && cp1[index1] == is) {
index1++;
i++;
continue;
}
if (index2 < cp2.length && cp2[index2] == is) {
index2++;
i++;
continue;
}
return false;
}
return s.length() == index1 + index2;
}
The problem is that if for example you have:
S = cdwzzzcdw
part1 = cdw
part2 = cdwzzz
What happens is that first you try to match the whole part1 with the beginning of S, and part won't be able to match the rest of the string. But if you have considered part2 first, the it would be properly done.
So, the bottom line is that you should consider all the possibilites. I assume a dyanmic programming approach would work. Here is a pseudocode in C++:
bool rec(idx1, idx2, idxS ){
if(idx1 == part1.length && idx2 == part2.length){
if(idxS == S.length) return true; //everything matched
return false; //S has remaining
}
if(idxS == S.length){ //length part1 + part2 is more than S
return false;
}
if(mark[idx1][idx2][idxS] == true) //computed before
return dp[idx1][idx2][idxS];
mark[idx1][idx2][idxS] = true;
dp[idx1][idx2][idxS] = false;
if(idx1 < part1.length && part1[idx1] == S[idxS]){
if(rec(idx1 + 1, idx2, idxS + 1) == true) {
dp[idx1][idx2][idxS] = true;
}
}
if(idx2 < part2.length && part2[idx2] == S[idxS]){
if(rec(idx1, idx2 + 1, idxS + 1) == true){
dp[idx1][idx2][idxS] = true;
}
}
return dp[idx1][idx2][idxS];
}

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;
}

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