I am creating a method in a class that counts the number of vowels in a string. First, I created a method isVowel() that tested if a letter was a variable and returned a boolean value. Then I used the isVowel() method to create the countVowels() method. However, the code I wrote for the countVowels() method doesn't seem to be working but my isVowel() method does work and returns a correct value when tested on a letter. Any idea what I am doing wrong?
public int countVowels() {
int i = 0;
int counter = 0;
while (i < text.length()) {
String letter = text.substring(i, i + 1); // the ith letter
if (isVowel(letter) == true) {
counter++;
} else {
counter = counter + 0;
}
i++;
}
return counter;
}
It's unclear what exactly the problem is. However, a for loop would better suit the task at hand rather than a while loop.
i.e.
public int countVowels(){
int counter = 0;
for(int i = 0; i < text.length(); i++){
String letter = text.substring(i, i + 1);
if(isVowel(letter))
counter++;
}
return counter;
}
then your isVowel method should be something along the lines of:
public boolean isVowel(String c){
String vowels = "aeiouAEIOU";
return vowels.contains(c);
}
Related
I trying to write one string Anagram program but stuck while checking the boundary conditions.
I know there are lots of ways and programs available on internet related to String Anagrams using single loops or using collections framework, but I need the solution for my code that how can I involve boundary cases for the code.
public class StringAnagram {
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "abc";
String strAnagram = "cba";
boolean areAnagrams = ifAnagrams(str, strAnagram);
System.out.println(areAnagrams);
}
private static boolean ifAnagrams(String str, String strAnagram) {
// TODO Auto-generated method stub
int count = 0;
char[] a = strAnagram.toCharArray();
if (str.length() != strAnagram.length()) {
return false;
}
for (int i = 0; i < str.length(); i++) {
{
System.out.println("str.charAt(i) in outer loop :" + str.charAt(i));
for (int j = 0; j < strAnagram.length(); j++) {
if (str.charAt(i) == strAnagram.charAt(j)) {
System.out.println("str.charAt(i) : " + str.charAt(i));
System.out.println("strAnagram.charAt(j) : " + strAnagram.charAt(j));
count++;
}
}
}
System.out.println(count);
if (count == str.length()) {
return true;
}
}
return false;
}
}
Code is working fine if I am inputting the input likes -
"abc" or "abcd" where each char in string is occuring only one time, but it fails when input is like "aab" can be compared to "abc" and it will show strings are anagrams.
So, how this condition I can handle in my code. Please advice.
The problem with your solution is that it only checks if each character in the first string is present in the second string. There are 2 more conditions you need to consider:
If each character in the second string is also present in the first string
If character count for each character in the first and the second string matches
Your current solution will return True for input of ("aaa", "abc") while it should return False. Implementing the first condition I mentioned above will fix this problem.
After you implement the first condition, your solution will return True for input of ("abb", "aab") while it should return False. Implementing the second condition I mentioned above will fix this problem.
Here is a simple way to make this work:
Map<Character, Integer> charCount = new HashMap<Character, Integer>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (charCount.containsKey(c)) {
charCount.put(c, charCount.get(c)+1);
} else {
charCount.put(c, 1);
}
}
for (int i = 0; i < strAnagram.length(); i++) {
char c = strAnagram.charAt(i);
if (!charCount.containsKey(c)) return false;
if (charCount.get(c) == 0) return false;
charCount.put(c, charCount.get(c)-1);
}
for (char k : charCount.keySet()) {
if (charCount.get(k) != 0) return false;
}
return true;
Since there are no nested loops, the time complexity is O(n). Even though a Map is used, the space complexity is O(1), since it is guaranteed that the total number of keys will not exceed the number of all possible characters.
This solution is even better than sorting in terms of time and space complexity.
This may still be wildly inefficient. Again I apologize for initially overlooking your requirement that no collection frameworks could be included.
public class StringAnagram {
public static void main(String[] args) {
// TODO Auto-generated method stub
// String str = "abc";
// String strAnagram = "cba";
String str = "abcdd";
String strAnagram = "dccba";
boolean areAnagrams = ifAnagrams(str, strAnagram);
System.out.println(areAnagrams);
}
private static boolean ifAnagrams(String str, String strAnagram) {
int count = 0;
char[] a = strAnagram.toCharArray();
char[] b = str.toCharArray();
String alphaString = "abcdefghijklmnopqrstuvwxyz";
char[] alpha = alphaString.toCharArray();
System.out.println(a);
System.out.println(b);
System.out.println("");
if (str.length() != strAnagram.length()) {
return false;
}
for (int i=0; i < alpha.length; i++) {
int countA = 0;
int countB = 0;
for(int j = 0; j < a.length; j++){
if (a[j] == alpha[i]) {
countA++;
}
if (b[j] == alpha[i]) {
countB++;
}
}
if (countA != countB) {
return false;
}
}
return true;
}
}
This alternate solution makes use of a string that contains all the letters in the alphabet, and iterates through them to check if both strings have the same count of each letter. No frameworks this time :)
This question already has answers here:
Find the Number of Occurrences of a Substring in a String
(27 answers)
Closed 7 years ago.
Given a string, return true if the string "bat" and "ball" appear the same number of times.
MyApproach
I followed the above approach.I have taken the string "bat" and "ball".I searched in the string whether the pattern "bat" exist or not.I checked each character of the original string and compared with the characters of the bat.Similarly I searched for the pattern ball.It will return true
When both bat and ball appear same number of times.
Below is my Code with the Output.
public boolean equal(String str)
{
String str1="bat";
String str2="ball";
int l=str.length();
int l1=str1.length();
int l2=str2.length();
if((l<l1) || (l<l2))
{
return false;
}
else
{
int m=0;
int n=0;
int countbat=0;
int countball=0;
int p=0;
int j=0;
str=str.toLowerCase();
str1=str1.toLowerCase();
str2=str2.toLowerCase();
while(j<l)
{
char c=str.charAt(j);
char c1=str1.charAt(p);
if(c==c1){
p++;
if(p==l1){
countbat++;
p=0;
}
}
else{
p=0;
}
j++;
}
while(m<l)
{
char c=str.charAt(m);
char c2=str1.charAt(n);
if(c==c2){
n++;
if(n==l2){
countball++;
n=0;
}
}
else
{
n=0;
}
m++;
}
if(countbat==countball)
return true;
else
return false;
}
}
Parameters Actual Output Expected Output
'bat+ball=cricket' null true
I am not able to get the correct output.Can anyone tell me
why?
Change char "c2=str1.charAt(n);" to "char c2=str2.charAt(n);" (second while loop)
Your approach is not clear until you explain it briefly. Try this. With this your looping will be very less if you have a big string to search for ball and bat.
String name = "ball bat ball bat bat ball bat bat";
int batCount = 0;
int ballCount = 0;
int index = 0;
int startIndex = 0;
while(index != -1){
index = name.indexOf("bat", startIndex);
startIndex = index + 1;
if(index != -1){
batCount++;
}
}
index = 0;
startIndex = 0;
while(index != -1){
index = name.indexOf("ball", startIndex);
startIndex = index + 1;
if(index != -1){
ballCount++;
}
}
System.out.println(batCount); //Outputs 5
System.out.println(ballCount); //Outputs 3
Extract a method to count the occurences of one String in another. Something like,
private static int countWord(String str, String word) {
int count = 0;
for (int i = 0; i < str.length() - word.length() + 1; i++) {
if (str.substring(i, i + word.length()).equals(word)) {
count++;
}
}
return count;
}
Then you can implement your equal method like
public static boolean equal(String str) {
return countWord(str, "ball") == countWord(str, "bat");
}
I'm extremely new to the whole idea of recursion, and it's blowing my mind a bit to be honest. I'm trying to turn this function I wrote into a recursive one...
public static int to_number(String s)
{
int total = 0;
int n=s.length();
for(int i = 0 ; i < n ; i++) {
char c = s.charAt(i);
if (Character.isDigit(c)){
int value=Character.getNumericValue(c);
total +=value;
}
}
System.out.println(total);
return total;
}
It reads in a string, such as "3aaa6a3", iterates through the string, if the char is a digit, it adds it to total, and so on. What I have so far...
public static int to_number(String s)
{
int total = 0;
int n=s.length();
int i=0;
if (i == n){
return 0; //if gone through the whole string
}
char c = s.charAt(i);
if (Character.isDigit(c)){
int value=Character.getNumericValue(c);
total +=value;
}
System.out.println(total);
i++;
to_number(); //trying to call the same function
return total;
}
I feel like I'm close, but just not getting it. Thanks for your time and effort!
Not gonna give you the code, but as a recursive function, you want to process the first character of the input string, then call yourself with the remaining string, i.e. to_number(s.substring(1)), and combine the result. Recursion ends when input string is empty.
try this
public void intToNum(String s, int total[])
{
if(s.isEmpty())
return;
char c = s.charAt(0);
if (Character.isDigit(c)){
int value=Character.getNumericValue(c);
total[0] +=value;
}
intToNum(s.substring(1),total);
}
and in your main, call the function as
int [] total = new int[1];
intToNum(input,total);
System.out.println(total[0]);
or another approach is
public int intToNum(String s)
{
if(s.isEmpty())
return 0;
char c = s.charAt(0);
if (Character.isDigit(c)){
int value=Character.getNumericValue(c);
return value + intToNum(s.substring(1));
}
return intToNum(s.substring(1));
}
This answer contains the solution. Just look at it when you are stuck. I also encourage you to read and understand the code instead of just copying it. This is one of the most important concepts in programming, so make sure you understand it and are familiar with it. :)
How it works: The method receives a string. If the string is longer than 1 character, the method splits it in half, calls itself on the two substrings and adds the two results. Those calls will do the same thing, until the string fragments are only 1 (or 0) characters long. In that case, it just returns their value (or 0, if there is no value).
public class RecursionVsIteration {
public static void main(String[] args) {
String str = "2.938fyfh0293urhp2398rpod8723uoihr98y";
System.out.println("Iterative: " + toNumberIterative(str));
System.out.println("Recursive: " + toNumberRecursive(str));
}
public static int toNumberIterative(String s) {
int total = 0;
int n = s.length();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
int value = Character.getNumericValue(c);
total += value;
}
}
return total;
}
public static int toNumberRecursive(String s) {
int n = s.length();
// termination criteria
if (n == 0) { // emtpy string
return 0;
}
if (n == 1) { // on character string
char c = s.charAt(0);
return Character.isDigit(c) ? Character.getNumericValue(c) : 0;
}
// recursive call (split the string in half and call the method on both substrings)
return toNumberRecursive(s.substring(0, n / 2)) + toNumberRecursive(s.substring(n / 2, n));
}
}
This is for a past homework assignment that I wasn't able to complete in time. I am a new programmer struggling with this method of the program CharacterSearch. I'm stuck on which boolean logic to use for my if statement, as well as how to find matches in the phrase using the pre-defined character variable. And example test is: character = "x" , phrase = "Xerox". Whereas X and x are different. The expected output should be count = 1.
Edit: This problem should be answered without using arrays or lists.
/**
* Counts and returns the number of times the letter for this class
* occurs in the phrase. The class is case sensitive.
*/
public int letterCount(String phrase)
{
Scanner jf = new Scanner(phrase);
count = 0;
for (int i = phrase.length(); i > 0; i--)
{
jf.findInLine(character);
if(jf.hasNext())
{
count++;
jf.next();
}
}
return count;
}
There you go:
/**
* Counts and returns the number of times the letter for this class
* occurs in the phrase. The class is case sensitive.
*/
public int letterCount(String phrase)
{
int count = 0;
// for every character in phrase ...
for (int i = 0; i < phrase.length(); i++)
{
// ... if it is the right one ...
if(phrase.charAt(i) == character)
{
// ... increment the counter
count++;
}
}
return count;
}
You don't need any Scanner, and the code is fairly easy, readable and comprehensible.
Pretty much a duplicate of Simple way to count character occurrences in a string
I can't leave a comment yet because my rep is too low but I wanted to give you a solution you could use.
public int letterCount(String phrase)
{
count = 0;
for (int i = 0 ; i < phrase.length(); i++)
{
String myLetter = phrase.substring(i, i + 1);
if (myLetter.equals(character))
{
count++;
}
}
return count;
}
I figured out that I was iterating in the wrong direction, but more importantly I was not declaring a sub-string to check if my character matched the individual letters within the phrase.
Use String's substring with a compare().
public int letterCount(String phrase, String match)
{
int count = 0;
for(int i=0;i<phrase.length()-1;i++){ //-1 avoid out-of-bound exception
String letter = phrase.substring(i, i+1);
if(letter.compareTo(match) == 0){
count++;
}
}
return count;
}
I am having difficulties with my method returning true. It is a boolean method that takes two words and tries to see if one can be turned into the other by transposing two neighboring letters. I have had no troubles getting the false boolean. When the code gets to the for loop with an if statement in it it runs fine but does not return true when the if statement is satisfied. For some reason it continues through the for loop. For example, when comparing "teh" and "the" when the loop hits 1 the if statement is satisfied but does not return true, the for lo
public static boolean transposable(String word1, String word2)
{
ArrayList<Character> word1char = new ArrayList<Character>();
ArrayList<Character> word2char = new ArrayList<Character>();
int word1length = word1.length();
int word2length = word2.length();
int count = 0;
String w1 = word1.toUpperCase();
String w2 = word2.toUpperCase();
if(word1length != word2length)
{
return false;
}
for(int i = 0; i < word1length; i++)
{
char letter1 = w1.charAt(i);
word1char.add(letter1);
char letter2 = w2.charAt(i);
word2char.add(letter2);
}
for(int i = 0; i < word1length; i++)
{
char w1c = word1char.get(i);
char w2c = word2char.get(i);
if(w1c == w2c)
{
count++;
}
}
if(count < word1length - 2)
{
return false;
}
for(int i = 0; i < word1length; i++)
{
char w1c = word1char.get(i);
char w2c = word2char.get(i+1);
if(w1c == w2c)
{
return true;
}
}
return false;
}
op just keeps running. What am I doing wrong?
As pointed out in the comments this doesn't seem to be the easiest way around this problem. Here is a solution which tries to follow your logic and includes the use of toUpperCase() and ArrayLists.
Going over your code it looks like you were getting a bit lost in your logic. This is because you had one method trying to do everything. Break things down into smaller methods and you also will benefit by not having to repeat code and it keeps things much cleaner. The code below is tested with Java8 (although there is no reason why this should not work with Java 7).
public static void main(String args[]) {
String word1 = "Hello";
String word2 = "Hlelo";
transposable(word1, word2);
}
private static boolean transposable(String word1, String word2) {
// Get an ArrayList of characters for both words.
ArrayList<Character> word1CharacterList = listOfCharacters(word1);
ArrayList<Character> word2CharacterList = listOfCharacters(word2);
boolean areWordsEqual;
// Check that the size of the CharacterLists is the same
if (word1CharacterList.size() != word2CharacterList.size()) {
return false;
}
// check to see if words are equal to start with
areWordsEqual = checkIfTwoWordsAreTheSame(word1CharacterList, word2CharacterList);
System.out.print("\n" + "Words are equal to be begin with = " + areWordsEqual);
if (!areWordsEqual) {
/*
This loop i must start at 1 because you can't shift an ArrayList index of 0 to the left!
Loops through all the possible combinations and checks if there is a match.
*/
for (int i = 1; i < word1CharacterList.size(); i++) {
ArrayList<Character> adjustedArrayList = shiftNeighbouringCharacter(word2CharacterList, i);
areWordsEqual = checkIfTwoWordsAreTheSame(word1CharacterList, adjustedArrayList);
System.out.print("\n" + "Loop count " + i + " words are equal " + areWordsEqual + word1CharacterList + adjustedArrayList.toString());
if (areWordsEqual) {
break;
}
}
}
return areWordsEqual;
}
// takes in a String as a parameter and returns an ArrayList of Characters in the order of the String parameter.
private static ArrayList<Character> listOfCharacters(String word) {
ArrayList<Character> wordCharacters = new ArrayList<Character>();
String tempWord = word.toUpperCase();
for (int wordLength = 0; wordLength < tempWord.length(); wordLength++) {
Character currentCharacter = tempWord.charAt(wordLength);
wordCharacters.add(currentCharacter);
}
return wordCharacters;
}
// takes in two character arrayLists, and compares each index character.
private static boolean checkIfTwoWordsAreTheSame(ArrayList<Character> characterList1, ArrayList<Character> characterList2) {
// compare list1 against list two
for (int i = 0; i < characterList1.size(); i++) {
Character currentCharacterList1 = characterList1.get(i);
Character currentCharacterList2 = characterList2.get(i);
if (!currentCharacterList1.equals(currentCharacterList2)) {
return false;
}
}
return true;
}
// this method takes in an ArrayList of characters and the initial index that we want to shift one place to the left.
private static ArrayList<Character> shiftNeighbouringCharacter(ArrayList<Character> characterListToShift, int indexToShiftLeft) {
ArrayList<Character> tempCharacterList = new ArrayList<Character>();
int indexAtLeft = indexToShiftLeft - 1;
// fill the new arrayList full of nulls. We will have to remove these nulls later before we can add proper values in their place.
for (int i = 0; i < characterListToShift.size(); i++) {
tempCharacterList.add(null);
}
//get the current index of indexToShift
Character characterOfIndexToShift = characterListToShift.get(indexToShiftLeft);
Character currentCharacterInThePositionToShiftTo = characterListToShift.get(indexAtLeft);
tempCharacterList.remove(indexAtLeft);
tempCharacterList.add(indexAtLeft, characterOfIndexToShift);
tempCharacterList.remove(indexToShiftLeft);
tempCharacterList.add(indexToShiftLeft, currentCharacterInThePositionToShiftTo);
for (int i = 0; i < characterListToShift.size(); i++) {
if (tempCharacterList.get(i) == null) {
Character character = characterListToShift.get(i);
tempCharacterList.remove(i);
tempCharacterList.add(i, character);
}
}
return tempCharacterList;
}
Hope this helps. If you are still struggling then follow along in your debugger. :)