Iterating over a string array - java

Return true if the string "cat" and "dog" appear the same number of times in the given string.
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()-3;i++){
if(str.substring(i).startsWith("cat")){
countCat++;
}
if(str.substring(i).startsWith("dog")){
countDog++;
}
}
if(countCat==countDog){
return true;
}
else{
return false;
}
}
I am having trouble writing this method. Does anybody know why my code doesn't work correctly?
Edit: The code compiles, however it gives the wrong output. For example if i put in "catdog" it returns false.

with the examples you posted, its because of your for loop which should be for(int i=0;i<str.length();i++){. you can also use str.length()-1 and str.length()-2 to get the right result. -3 will give the wrong result. little example: string is catdog1dog. result should be false. lets have a look at the substring which will be created with -3:
catdog1dog
atdog1dog
tdog1dog
dog1dog
og1dog
g1dog
1dog
as you can see with -3 the last substring is wrong and therefore the result too. that is because if you look at substring, you will see that the start is at char 0 and not at 1 therefore str.length()-1 is the last character in your string. sorry if my explanations isn't that good

As suggestsed in this question, I would recomment using StringUtils.countMatches from Apache Commons Lang?
Credit to #A_M

Although your problem can be solved through other strategies, I think you might only subtract 2 to str.length() instead of 3.
I hope be useful!

I would do something like this:
public boolean catDog(String str){
return countWords(str, "cat") == countWords(str, "dog");
}
private int countWords(String original, String word){
int counter = 0;
boolean searching = true;
while(searching){
if(original.indexOf(word) >= 0){
counter++;
original = original.substring(original.indexOf(word) + word.length());
}
else{
searching = false;
}
}
return counter;
}

Related

palindromeRearrangin CodeSignal hidden tests

I am trying to solve this . I passed 18 tests from 20 . 2 of them are hidden and I cant understand what are those 2 scenarios. Please tell me if you see something wrong here . I saw many solutions on the WEB, but I want to understand what is wrong with my own code.
For inputString = "aabb", the output should be
palindromeRearranging(inputString) = true.
We can rearrange "aabb" to make "abba", which is a palindrome.
Here is my code:
boolean palindromeRearranging(String str) {
Stack<Character> stack=new Stack<>();
for (int i = 0; i < str.length(); i++) {
if(stack.contains(str.charAt(i))){
stack.pop();
continue;
}
stack.push(str.charAt(i));
}
if(stack.size()>1) return false;
return true;
}
When you're by using condition stack.contains(str.charAt(i)),
find out that current checking character str.charAt(i) is already present in Stack,
you need to remove that particular repeating character instead of the last character present in Stack.
so only stack.pop() is a mistake in code.
One of those scenarios in my case :
"abcabc" . Should return true, but instead it returns false. I sorted the String first then my algorithm worked :)

String index out of range: -1 error with loops

I checked old topics with this problem and couldn't fix it.
This method is meant to compare two strings, and if every letter/character of the first string is found in the second string (not necessarily vice versa), then the method should return "true" (even if the second string has extra letters).
My idea is to check the letter at every index of the first string, see if it's in the second string, and if it is, delete that letter in both strings. When the first string runs out of letters (length equals zero) then the boolean should return true.
I think my loops or substring reaches out of range at some point.
public boolean isFound(String first, String second) {
StringBuilder sb1 = new StringBuilder(first);
StringBuilder sb2 = new StringBuilder(second);
first.toCharArray();
second.toCharArray();
for (int i = 0; i < first.length(); i++) {
int k = (first.substring(i, i + 1)).indexOf(second, i);
if (sb1.length() > 0) {
sb1.deleteCharAt(k);
sb2.deleteCharAt(k);
}
}
if (sb1.length() == 0) {
return true;
} else {
return false;
}
}
Ex: "at" and "tack" should return true, "tree" and "ere" should return false.
EDIT
After reviewing the comments, my new code is now this. It always returns false, though even with "tree" and "tree".
public boolean isFound(String first, String second){
StringBuilder sb2 = new StringBuilder(second);
for(int i=0;i<first.length();i++){
int k = sb2.indexOf(first,i);
if (k==-1)
return false;
else sb2.deleteCharAt(k);
}
return true;
}
You have a number of problems in your code.
You only need one StringBuilder version, that of second
The calls to toCharArray() are superfluous
You should not search for each character of first in second but in the mutable version of it sb2.
You are using indexOf wrong. This method should be called on the StringBuilder object to search for the first argument, you have it swapped.
The pseudocode that you can use is
isSuperAnagram(String first, String second) {
sb = StringBuilder(second)
for all chars in first {
k = search index of current char of first in sb
if(k == -1) // char is not in sb
return false
else
remove char at index k from sb
}
return true
}
please review your algorithm and code/usage of APIs
` first.toCharArray();`
second.toCharArray();
wont convert first,second to array, this API would return a character array.
(first.substring(i,i+1)).indexOf(second,i); will search the whole substring2 in first.substring.
review the algo/code correct this accordingly.please take care of all the edge/corner cases.
ideal method will be to use a hashmap.(on cost of extra space)
There is simple logic you can implement it your code
for(int i=0;i<sb1.length;i++)
{
for(int j=0;j<sb2.length;j++)
{
if(sb1.[i]==sb2.[j])
{
count++;
break;
}
if(count>=sb1.length)
{
System.out.print("match");
}
}
}
if you want more condition then post it below my post i wrote for only your follow example
Ex: "at" and "tack" should return true, "tree" and "ere" should return false.

Checking if every char in a string belongs to the given set of chars or not (JAVA)

So I need to create a method isValidDNA which works like this:
public boolean isValidDNA()
Returns true if the DNA is valid, i.e, only contains the letters,
A,T,C,G (in uppercase) and at least one of these characters.
All I could think of was this, which apparently doesn't work:
public boolean isValidDNA(){
for (int i=0;i<dna.length();i++){
if (dna.charAt(i)=='A' || dna.charAt(i)=='T' || dna.charAt(i)=='C' || dna.charAt(i)=='G' ){
return true;
}
return false;
}
}
You can use this regular expression:- [ATCG]+ In code this could look like this:
public boolean isValidDNA(){
return dna.matches("^[ATCG]+$")
}
You make a return statement immediately, which will exit during the first iteration and only check the first character.
You need to store this information in a boolean and return it after you've checked the whole string:
public boolean isValidDNA(String dna){
Boolean result = true;
// Add an extra check for the "at least one character" thing.
for (int i=0; i<dna.length(); i++){
if (dna.charAt(i)!='A' && dna.charAt(i)!='T' && dna.charAt(i)!='C' && dna.charAt(i)!='G' ){
result = false;
}
}
return result;
}
However, you would be better off using regular expressions for these problems.
Try it this way:
public boolean isValidDNA(){
boolean res = true;
for (int i=0;i<dna.length();i++){
if ((dna.charAt(i) != 'A') && (dna.charAt(i)!='T') && (dna.charAt(i)!='C') && (dna.charAt(i)!='G') ){
res = false;
break;
}
}
return res;
}
if your startpoint is that the DNA is valid, it's much more easy to test if it's really so. You only have to test each char of your dna and can stop by the first entry that doesn't satisfy your if-statement.
Using your way, you've almost got it.
Right now, you return true if you find one that's OK, and only return false if all are wrong. You can negate your if condition, and return false as soon as you find one that's not OK, and only return true if all are fine.
I'll leave the coding part up to you.
As others pointed out, regex will be a cleaner solution here.
You can try this implementation.
First declare a constant:
private static final String bases = "ATCG";
And then use it in the method like this:
public boolean isValidDNA() {
boolean isValid = true;
for (char c : dna.toCharArray()) {
if (bases.indexOf(c) < 0) {
isValid = false;
break;
}
}
return isValid;
}
Scanner sc = new Scanner(System.in);
System.out.print("Enter a DNA sequence: ");
seq=sc.nextLine();
if(seq.matches(".*[^ATCG].*")){
System.out.println("Not a valid sequence.");
System.exit(0);
}
This regular expression works so that only sequences containg A,C,T or G with no other charcters, spaces, etc included will continue

Code correction suggestion using Java libraries for strings?

I know there is an easier way of making things work to check whether a string is a palindrome or not, but I wanted to try it using library functions and I came up with the code below.
public boolean isPalindrome1(String input)
{
int length = input.length()/2;
if(input.length()%2!=0)
{
length = length + 1;
}
return(input.substring(0,length).equals(new StringBuilder(input.substring(length, input.length())).reverse().toString()));
}
I'm trying to check whether half the string is equal to the other half's reverse. But it is getting messed up for odd and even lengths. Can someone point corrections in this where it will work for odd, even lengths as well as empty string and string of length = 1.
You're already using reverse(). Why can you not compare the input String with the reverse? Isn't that exactly what you're wanting in the first place? No need to be splitting things in half in a complicated way.
you can:
return new StringBuilder(input).reverse().toString().equals(input);
here you go as you want to know :
public boolean isPalindrome(String input) {
for (int i = 0; i < input.length() / 2; i++) {
if (input.charAt(i) != input.charAt(input.length() - 1 - i)) {
return false;
}
}
return true;
}

Is there an existing library method that checks if a String is all upper case or lower case in Java?

I know there are plenty of upper() methods in Java and other frameworks like Apache commons lang, which convert a String to all upper case.
Are there any common libraries that provide a method like isUpper(String s) and isLower(String s), to check if all the characters in the String are upper or lower case?
EDIT:
Many good answers about converting to Upper and comparing to this. I guess I should have been a bit more specific, and said that I already had thought of that, but I was hoping to be able to use an existing method for this.
Good comment about possible inclusion of this in apache.commons.lang.StringUtils.
Someone has even submitted a patch (20090310). Hopefully we will see this soon.
https://issues.apache.org/jira/browse/LANG-471
EDIT:
What I needed this method for, was to capitalize names of hotels that sometimes came in all uppercase. I only wanted to capitalize them if they were all lower or upper case.
I did run in to the problems with non letter chars mentioned in some of the posts, and ended up doing something like this:
private static boolean isAllUpper(String s) {
for(char c : s.toCharArray()) {
if(Character.isLetter(c) && Character.isLowerCase(c)) {
return false;
}
}
return true;
}
This discussion and differing solutions (with different problems), clearly shows that there is a need for a good solid isAllUpper(String s) method in commons.lang
Until then I guess that the myString.toUpperCase().equals(myString) is the best way to go.
Now in StringUtils isAllUpperCase
This if condition can get the expected result:
String input = "ANYINPUT";
if(input.equals(input.toUpperCase())
{
// input is all upper case
}
else if (input.equals(input.toLowerCase())
{
// input is all lower case
}
else
{
// input is mixed case
}
Not a library function unfortunately, but it's fairly easy to roll your own. If efficiency is a concern, this might be faster than s.toUpperCase().equals(s) because it can bail out early.
public static boolean isUpperCase(String s)
{
for (int i=0; i<s.length(); i++)
{
if (!Character.isUpperCase(s.charAt(i)))
{
return false;
}
}
return true;
}
Edit: As other posters and commenters have noted, we need to consider the behaviour when the string contains non-letter characters: should isUpperCase("HELLO1") return true or false? The function above will return false because '1' is not an upper case character, but this is possibly not the behaviour you want. An alternative definition which would return true in this case would be:
public static boolean isUpperCase2(String s)
{
for (int i=0; i<s.length(); i++)
{
if (Character.isLowerCase(s.charAt(i)))
{
return false;
}
}
return true;
}
Not that i know.
You can copy the string and convert the copy to lower/upper case and compare to the original one.
Or create a loop which checks the single characters if the are lower or upper case.
This method might be faster than comparing a String to its upper-case version as it requires only 1 pass:
public static boolean isUpper(String s)
{
for(char c : s.toCharArray())
{
if(! Character.isUpperCase(c))
return false;
}
return true;
}
Please note that there might be some localization issues with different character sets. I don't have any first hand experience but I think there are some languages (like Turkish) where different lower case letters can map to the same upper case letter.
Guava's CharMatchers tend to offer very expressive and efficient solutions to this kind of problem.
CharMatcher.javaUpperCase().matchesAllOf("AAA"); // true
CharMatcher.javaUpperCase().matchesAllOf("A SENTENCE"); // false
CharMatcher.javaUpperCase().or(CharMatcher.whitespace()).matchesAllOf("A SENTENCE"); // true
CharMatcher.javaUpperCase().or(CharMatcher.javaLetter().negate()).matchesAllOf("A SENTENCE"); // true
CharMatcher.javaLowerCase().matchesNoneOf("A SENTENCE"); // true
A static import for com.google.common.base.CharMatcher.* can help make these more succinct.
javaLowerCase().matchesNoneOf("A SENTENCE"); // true
Try this, may help.
import java.util.regex.Pattern;
private static final String regex ="^[A-Z0-9]"; //alpha-numeric uppercase
public static boolean isUpperCase(String str){
return Pattern.compile(regex).matcher(str).find();
}
with this code, we just change the regex.
I realise that this question is quite old, but the accepted answer uses a deprecated API, and there's a question about how to do it using ICU4J. This is how I did it:
s.chars().filter(UCharacter::isLetter).allMatch(UCharacter::isUpperCase)
If you expect your input string to be short, you could go with myString.toUpperCase().equals(myString) as you suggested. It's short and expressive.
But you can also use streams:
boolean allUpper = myString.chars().noneMatch(Character::isLowerCase);
You can use java.lang.Character.isUpperCase()
Then you can easily write a method that check if your string is uppercase (with a simple loop).
Sending the message toUpperCase() to your string and then checking if the result is equal to your string will be probably slower.
Here's a solution I came up with that's a bit universal as it doesn't require any libraries or special imports, should work with any version of Java, requires only a single pass, and should be much faster than any regex based solutions:
public static final boolean isUnicaseString(String input) {
char[] carr = input.toCharArray();
// Get the index of the first letter
int i = 0;
for (; i < carr.length; i++) {
if (Character.isLetter(carr[i])) {
break;
}
}
// If we went all the way to the end above, then return true; no case at all is technically unicase
if (i == carr.length) {
return true;
}
// Determine if first letter is uppercase
boolean firstUpper = Character.isUpperCase(carr[i]);
for (; i < carr.length; i++) {
// Check each remaining letter, stopping when the case doesn't match the first
if (Character.isLetter(carr[i]) && Character.isUpperCase(carr[i]) != firstUpper) {
return false;
}
}
// If we didn't stop above, then it's unicase
return true;
}

Categories

Resources