in Valid Anagram program not passing all test cases - java

Given two strings s and t , write a function to determine if t is an anagram of s.
Example 1:
Input: s = "anagram", t = "nagaram"
Output: true
Example 2:
Input: s = "rat", t = "car"
Output: false
example 3
"aad"
"cab"
Output
true
Expected
false
my 3 test case is giving output true why?
class Solution {
public boolean isAnagram(String s, String t) {
if (s.isEmpty() && t.isEmpty()) {
return true;
}
if (s.length() != t.length()) {
return false;
}
char[] a = s.toCharArray();
char[] b = t.toCharArray();
Arrays.sort(a);
Arrays.sort(b);
for (int i = 0; i <= a.length; i++) {
for (int j = 0; j <= b.length; j++) {
if (a[i] == b[j]) {
return true;
}
}
}
return false;
}
}

By using a nested for loop, you will iterate over every possible pair (i, j) with i and j an in idex in a and b respectively. Furthermore you use i++ and j++ twice, and thus you will skip the even indices. You can not return true from the moment a[i++] == b[j++] matches. In order to know if something is an anagram, you need to iterate over all elements. You can return false from the moment a[i] != b[i] however. Finally the bound should be i < a.length, not i <= a.length.
You thus need one for loop where you make a single increment and compare a[i] with b[i]:
public boolean isAnagram(String s, String t) {
if(s.length() != t.length()){
return false;
}
char[] a = s.toCharArray();
char[] b = t.toCharArray();
Arrays.sort(a);
Arrays.sort(b);
for(int i = 0; i < a.length; i++) {
if(a[i] != b[i]) {
return false;
}
}
return true;
}

You are just comparing the first letter of cab and rat which is a, and returning True, actually you need to check all letters.
Hence make the condition negative and swap the returns.
if(a[i++] !=b[j++]){
return false;
}
return true;
The above code will return false, when characters aren’t equal, hence the last line is reached only when all chars are equal.

Related

Return true if arrays contain the same items

I am looking to return true if all the elements in A are found within B and false otherwise. Currently, I have written the code below but the function seems to only return false.
public static boolean con(int[] a, int[] b) {
if (a == null || a.length == 0) {
return false;
}else if (b == null || b.length == 0) {
return false;
}
for (int i = 0; i < a.length; i++)
{
for (int j = i + 1; j < b.length;j++)
{
if (a[i] == (b[j])) {
return true;
}
}
}
return false;
}
It is easy to make mistakes when you program with indices. Luckily, in this case there is no need to do that:
public static boolean con(int[] a, int[] b) {
loop: for (int ai : a) {
for (int bi : b) {
if (ai == bi) {
continue loop;
}
}
return false;
}
return true;
}
Always use the strengths of the language, not the weaknesses.
There are a couple of issues in your code as pointed out in the comments that are causing your code to return false, however, the other issue is that your return true if a[i] == (b[j]) which will be true and cause a return if the first element in the array is a match regardless of the rest of the array and if it matches or not.
Here is a working version with comments that help explain what has been changed:
public static boolean con(int[] a, int[] b) {
//Use a flag to track if the integers are found
Boolean flag = true;
//return false for null or 0 length
if (a == null || a.length == 0 || b == null || b.length == 0) {
return false;
}
//Check integers
for (int i = 0; i < a.length; i++){
//Use an inner flag to track each integer
Boolean innerFlag = false;
//Start the inner loop from 0 and incriment it
//Only use j = i if you need the integers to be in order?
for (int j = 0; j < b.length; j++){
if (a[i] == (b[j])) {
//we can not return from the method until all elements are checked
//so set the flag instead and break so the next element can be checked
innerFlag = true;
break;
}
}
//if an element does not exist we can set the flag false and break and return immediatly
if (innerFlag == false){
flag = false;
break;
}
}
return flag;
}
Why you use the int j = i + 1 and not just j to compare all b from the beginning of the array with j = 0... anyway if you change that and test it with two equals filled array it will give true at the first element, and if the array are different will give you true when both coincide, but you are not storing the results in any place,
I think what you could do is add a counter with the length of a:
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
if (a[i] == (b[j])) {
count--;
if(count == 0)
return true;
}
It kinda work, test it thoroughly and tell me.
If you really want to do it manually, you could use something like this:
private static boolean containsAll(Integer[] arrayA, Integer[] arrayB) {
Set<Integer> matches = new HashSet<>();
boolean containsAll = false;
for (int i = 0; i < arrayA.length; i++) {
for (int j = 0; j < arrayB.length; j++) {
if (arrayA[i] == arrayB[j]) {
matches.add(arrayA[i]);
}
}
}
if (matches.size() == arrayA.length) {
containsAll = true;
}
return containsAll;
}
Since a set can only store unique values, even if arrayB has duplicated elements, it will still work. It won't work if arrayA has duplicated elements, though.

Searching char arrays to see if the char matches

I have two char arrays that takes two strings as the input. If the char on either side has the matching char, for example after translating the char Arrays into string char A and B both have at least one H or R, then it will return true. If not then return false.
>char[] A = foo(A).toCharArray();
>
>char[] B = foo(B).toCharArray();
>
>System.out.println("String "+A+": "+Arrays.toString(A));
>
>System.out.println("String "+B+": "+Arrays.toString(B));
>String A: [H, , R, ]
>
>String B: [R, , R, R]
>>This will return true
>String A: [ , H, , R]
>
>String B: [H, H, , H]
>>This will return true
>String A: [H, , H, ]
>
>String B: [R, , R, ]
>>This will return false
I'm confused how to make such rule?
You can use java.util.Set here which will give the result in one iteration. Using java.util.TreeSet further reduce the execution time as it eliminates duplicates
public static void main(String[] args) {
char[] A = "HR".toCharArray();
char[] B = "RRR".toCharArray();
Set<Character> set = new TreeSet<>();
boolean flag = false;
for(char c : A) {
set.add(c);
}
for(char c : B) {
if(set.contains(c)) {
System.out.println(true);
flag = true;
break;
}
}
if(!flag) {
System.out.println(false);
}
}
That you can do is use a For to iterate in the matriz and verify if the current item is 'R' or 'H'.
boolean returnedValue = false;
for(int i = 0; i< B.length; i++){
char currentItem = B[i];
if(currentItem == 'R' || currentItem == 'H'){
returnedValue = true;
}
}
return returnedValue;
Use the first loop to take each element from the first array.
Use the second loop to check the first element inside the second array.
Check if the current value in the first array is equal to H or R.
If it is, check if it's in the second array and return true.
public static boolean check() {
String s1 = "ABHEEF", s2 = "RDDFVW";
char[] arr1 = s1.toCharArray();
char[] arr2 = s2.toCharArray();
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if(arr1[i] == 'H' || arr1[i] == 'R') {
if(arr1[i] == arr2[j])
return true;
}
}
}
return false;
}
Well its simple all you have to do is to add a nested loop
for(int i = 0; i < A.length; i++){
for(int j = 0; j < B.length; j++){
if(if B[j] ==A [i]){
return true
}
}
}
return false;
Using Java 1.8 you could do something like following:
//#Momir Sarac
String text1 = "b9H ello";
String text2 ="avn1c fk";
// 32 is for empty space character here, you could do i != ' ' and it would be the same
//turn text1 into intstream each int corresponding to it's char value
//filter empty space ints
//get only distinct out of them
//take a look for any match if some int is contained within text2
boolean result = text1.chars().filter(i->i != 32).distinct().anyMatch(character->text2.contains(String.valueOf(character)) || text2.lastIndexOf(character) != -1);
//print it on screen
System.out.printf("Two texts %s same letter(s).", result ? "have" : "don't have");

CodingBat commonTwo method, help examine the output?

Question Summary:
Given two String arrays, return an integer representing how many matches are between them (ignore duplicates).
Real Answer:
http://www.javaproblems.com/2013/11/java-ap-1-commontwo-codingbat-solution.html
My Code
public int commonTwo(String[] a, String[] b) {
int count = 0;
boolean done = false;
for (int i = 0; i<a.length-1; i++){
if(a[i].equals(a[i+1])){
i++;
for (String j:b)
if (a[i].equals(j) && !done){
done = true;
count++;
}
}
else{
for (String j:b)
if(a[i].equals(j) && !done){
done = true;
count++;
}
}
done = false;
if(i == a.length-2)
for (String j:b)
if (a[i+1].equals(j) && !done){
done = true;
count++;
}
}
return count;
}
Image of output: [1]: http://i.stack.imgur.com/0esjC.png
So what it was intended to do was to go through all of the array a,if it equals the next one then go to that index, then add to count if there's a match between the arrays. The done boolean was used to make it so it doesn't add to count if there're duplicates of b that matches a and to end it once a match is found.
Lastly,
if(i == a.length-2)
was intended to make it so if it's the second before the last index number (as the last index number won't be checked in some cases), and not the same as the last index number, then it would check for matches for the last index number after checking the one before the last essentially. I understand why both errors occur and was wondering what could be done to fix it, particularly for the second one/comments on the code. Also, a third issue I notice would be (["a"], ["a"]) → 1 but the code will result in 0.
This question can be done is linear time O(N) that is a single traversal of both arrays a and b.
You should increment i as long as same string appears.So
if(a[i].equals(a[i+1]))
i++;
should be replaced by
while(i+1<a.length&&a[i].equals(a[i+1])){
i++;}
Also you do not need to go through entire array b for a single string of array a since both are in alphabetical order.You should only compare the string from the array b as long there is no match.Once a match is found then you should remember that index and next time matching should continue from that index onwards for the array b
Also you don't need the boolean variable done.
Keeping these things in mind the correct code is:
public static int commonTwo(String[] a, String[] b) {
int count = 0;
int j=0,i;
for (i = 0; i<a.length-1&&j<b.length-1;){
//SKIP DUPLICATES FOR ARRAY a
while(i+1<a.length&&a[i].equals(a[i+1])){
i++;}
//SKIP DUPLICATES FOR ARRAY b
while(j+1<b.length&&b[j].equals(b[j+1])){
j++;}
//MATCH THE STRINGS FROM ARRAY a AND ARRAY b
while(i<a.length&&j<b.length&&a[i].compareTo(b[j])!=0)
{
//INCREMENT I IF STRING IN ARRAY a IS LESS THAN STRING IN ARRAY b
if(a[i].compareTo(b[j])<0)
++i;
//INCREMENT J IF STRING IN ARRAY b IS LESS THAN STRING IN ARRAY a
else ++j;
}
//IF ABOVE LOOP BREAKS BECAUSE OF MATCH
if(i<a.length&&j<b.length)
{count++; ++j; ++i;}
}
//IF THE LAST ELEMENT OF ARRAY a IS LEFT FOR COMPARISON
if(i==a.length-1)
{
while(j<b.length)
{
//SKIP DUPLICATES OF ARRAY b
while(j+1<b.length&&b[j].equals(b[j+1]))
++j;
if(a[i].equals(b[j]))
{++count;}
++j;
}
}
//IF THE LAST ELEMENT OF ARRAY b IS LEFT FOR COMPARISON
if(j==b.length-1)
{
while(i<a.length)
{
//SKIP DUPLICATES OF ARRAY a
while(i+1<a.length&&a[i].equals(a[i+1]))
++j;
if(a[i].equals(b[j]))
++count;
++i;
}
}
return count;
}
This is the simplest solution i could come up with that uses only one loop.
public int commonTwo(String[] a, String[] b) {
int count = 0;
int i = 0;
int j = 0;
String s = "";
while (i < a.length && j < b.length) {
if (a[i].compareTo(b[j]) < 0)
i++;
else if (a[i].equals(b[j]) && a[i] != s) {
s = a[i];
count++;
i++;
j++;
}
else j++;
}
return count;
}
public int commonTwo(String[] a, String[] b) {
int ctr = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
if (i > 0 && a[i] == b[j] && a[i] != a[i - 1]) {
ctr++;
break;
} else if (i == 0 && a[i] == b[j]) {
ctr++;
break;
}
}
}
return ctr;
}

To check if a given string contains a substring without using contains or indexOf method

In the following code the problem I am facing is how to make the inner loop start from a given index instead of 0 every time.
LOGIC:
substr = rohan;
mainstr = herohanda
The code first check the first character of substr i.e 'r' with every character of mainstr till it finds a match. When a match is found the program return to the outer loop and increments i to check if the 2nd charcater of substr (i.e o) matches the next character(the character next to the index where a match for 'r' was found) of the mainStr. The problem is how to start the inner loop from that next character. Here it is starting with the initial index (0) each time .
CODE:
public class SubstringInString {
public static void isSubstring(String subStr, String mainStr){
int flag = 0;
int counter = 0;
OUTER: for(int i = flag; i<subStr.length(); i = i+flag){
INNER: for(int j = 0; j< mainStr.length(); j=counter ){
if(subStr.charAt(i) == mainStr.charAt(j)){
counter++;
flag++;
continue OUTER;
}
else
{
if((mainStr.length() - i) >= subStr.length()){
counter ++;
flag = 0;
continue INNER;
}
else{
System.out.println("Main String does not contain the substring");
}
}
}
}
// System.out.println("Match found at " + j-subStr.length());
}
}
Please tell me what how to solve this and also if there is any better way to do the same.
Thanks in advance
Suppose we want to find out if s2 is a substring of s1.
There are 2 base cases:
length of s2 is 0: In this case, we can return true.
length of s2 is more than that of s1: We can return false.
The general approach is as follows: Iterate through each character of s1 and see if it matches with the first character of s2. If it does, then check if rest of the characters of s1 match with rest of the characters of s2. If so, return true. If the s1 is entirely explored with no matches found, return false.
Here is how it would look like in Java:
static boolean isSubstring(String s1, String s2){
int n1 = s1.length();
int n2 = s2.length();
if(n2 == 0) // Base Case 1
return true;
if(n2 > n1) // Base Case 2
return false;
for(int i = 0; i < s1.length(); i++)
if(s1.charAt(i) == s2.charAt(0)) // if first char matches
if(isRestMatch(i+1, s1, s2)) // check if rest match
return true;
return false;
}
static boolean isRestMatch(int start, String s1, String s2){
int n = s2.length();
for(int i = start, x = 1; i < n; i++, x++)
if(s1.charAt(i) != s2.charAt(x))
return false;
return true;
}
Technically, this solves the problem:
public static void isSubstring(String subStr, String mainStr){
return mainStr.matches(".*\\Q" + subStr + "\\E.*");
}
I've found this Java implementation
public String strStr(String haystack, String needle) {
int needleLen = needle.length();
int haystackLen = haystack.length();
if (needleLen == haystackLen && needleLen == 0)
return "";
if (needleLen == 0)
return haystack;
for (int i = 0; i < haystackLen; i++) {
// make sure in boundary of needle
if (haystackLen - i + 1 < needleLen)
return null;
int k = i;
int j = 0;
while (j < needleLen && k < haystackLen && needle.charAt(j) == haystack.charAt(k)) {
j++;
k++;
if (j == needleLen)
return haystack.substring(i);
}
}
return null;
}

Sorting algorithm without using compareTo

I'm working on a homework assignment that requires me to compare two strings and determine if they're in alphabetical order.
I plan to write a method that will take two strings as arguments, (String a, String b) and return either 1, 0, or -1 (so, an int) signalling whether a > b, a < b, or otherwise (the 0 case).
For example, comparing ("boogie", "orange") would return a -1. since, boogie < orange.
My code so far is
public static int compare(String a, String b) {
for (int i = 0; i < a.length(); i++) {
for (int j = 0; j < b.length(); j++) {
char cha = a.charAt(i);
char chb = b.charAt(j);
if (cha < chb) {
return -1;
} else if (cha > chb) {
return 1;
}
}
return 0;
}
}
However, I am encountering numerous errors and cannot find fixes for the bugs. I'm also having difficulty finding a code for measuring if one word is longer than another (which affects alphabetical order) Can someone help me debug the code and point me in the right direction?
Many thanks in advance.
You don't need a nestd loop, since you don't want to compare every character of one String to every character of the other String.
You only need a single loop:
public static int compare(String a, String b)
{
int len = Math.min (a.length(),b.length());
for (int i = 0; i<len; i++) {
char cha = a.charAt(i);
char chb = b.charAt(i);
if (cha < chb) {
return -1;
} else if (cha > chb) {
return 1;
}
}
if (a.length() < b.length())
return -1;
else if (a.length() > b.length())
return 1;
else
return 0;
}
As for handling Strings of different lengths, if you find that the shorter of the 2 Strings is equal to the prefix of the longer String, you return -1 if a is the shorter String and 1 if b is shorter (since the shorter String should come before the longer one).
You can compare two char by using '-' operator rather than the '>'.
For example below.
public static int compare(String a, String b) {
return a.charAt(0) - b.charAt(0);
}
In your case, something like this.
public static int compare(char cha, char chb) {
if (cha-chb < 0) {
return -1;
} else if(chb - cha > 0){
return 1;
} else if(chb - cha == 0){
return 0;
}
return 0;
}

Categories

Resources