Comparing Array values in JAVA (checking if words are anagrams) - java

How to check if the two arrays have same values, ignoring their position. The arrays can have multiple of same value.
Example 1
String[] a = {"m","o","m","d","a","d"};
String[] b = {"d","a","d","m","o","m"};
//This should result true.
Example 2
String[] a = {"m","o","m","d","a","d"};
String[] b = {"d","a","d","m","o"};
//This should result false because second array has only one m and first array has two
I hope my condition is understood by example.
I am trying to check if the words are anagrams. I have made array out of words. But could not check if the arrays have same values. My code is as follows:
public class AreAnagrams {
public static boolean areAnagrams(String a, String b) {
//throw new UnsupportedOperationException("Waiting to be implemented.");
if(a.length() != b.length()) return false;
String[] test = new String[a.length()];
String[] testb = new String[b.length()];
for(int i=0; i<a.length(); i++){
test[i] = a.substring(i,i+1);
testb[i] = b.substring(i,i+1);
}
return test.equals(testb);
}
public static void main(String[] args) {
System.out.println(areAnagrams("momdad", "dadmom"));
}
}

You can sort the two arrays with Arrays.sort() and then compare the sorted arrays with Arrays.equals() to find out if they have the same values.

Related

How to determine if two strings are permutable in java?

I am trying to determine if two strings are a permutation of each other. When I enter the following strings (see code below), the program should print that the two string are permutable. However, this is not the statement that I can see on my screen. Can anyone help me? Here is my code:
public static void main(String[] args) {
String str1 = "abcrdt";
String str2 = "barcdt";
char[] arr1 = str1.toCharArray();
Arrays.sort(arr1);
char[] arr2 = str2.toCharArray();
Arrays.sort(arr2);
if (isPermutation(arr1, arr2)) {
System.out.print("The strings are permutable.");
} else {
System.out.print("The strings are not permutable.");
}
}
static boolean isPermutation(char[] arr1, char[] arr2) {
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i <= arr1.length; i++) {
for (int j = 0; j <= arr2.length; j++) {
if (arr1[i] != arr2[j]) {
return false;
}
}
}
return true;
}
Your implemented logic inside the for loop originated the bug. You are using a nested loop where you are checking for each index of arr1 if there is any mismatch of the char with any character in arr2, you're returning false.
For example, if the first char from arr1 is a, you're checking whether it is mismatched with any of the chars from arr2. That's why you're getting retuned false.
Also, even if your logic were okay inside the loop, you'd get an ArrayIndexOutOfBoundException anyways, as you're iterating from index 0 to index including arr.length, where the zero indexed arrays have a valid index upto arr.length-1
To solve this, you can simply check whether their constructed string from sorted array are same:
public static void main(final String[] args) {
final String str1 = "abcrdt";
final String str2 = "barcdt";
if (isPermutation(str1.toCharArray(), str2.toCharArray())) {
System.out.print("The strings are permutable.");
} else {
System.out.print("The strings are not permutable.");
}
}
static boolean isPermutation(final char[] str1, final char[] str2) {
Arrays.sort(str1);
Arrays.sort(str2);
return new String(str1).equals(new String(str2));
}
Again, you can make this code more minimal if you omit the isPermutation and do a direct check in the if condition:
public static void main(final String[] args) {
final String str1 = "abcrdt";
final String str2 = "barcdt";
char[] arr1 = str1.toCharArray();
Arrays.sort(arr1);
char[] arr2 = str2.toCharArray();
Arrays.sort(arr2);
if (new String(arr1).equals(new String(arr2))) {
System.out.print("The strings are permutable.");
} else {
System.out.print("The strings are not permutable.");
}
}
As #chrylis-cautiouslyoptimistic- has already hinted at the problem, but this was not solved, here the solution:
You were thinking too deep into the problem, leading to an overly complex solution.
Check this out, this works just fine and is a lot easier:
import java.util.Arrays;
public class Permutat0r {
public static void main(final String[] args) {
final String str1 = "abcrdt";
final String str2 = "barcdt";
final char[] arr1 = str1.toCharArray();
Arrays.sort(arr1);
final char[] arr2 = str2.toCharArray();
Arrays.sort(arr2);
if (isPermutation(arr1, arr2)) {
System.out.print("The strings are permutable.");
} else {
System.out.print("The strings are not permutable.");
}
}
static boolean isPermutation(final char[] arr1, final char[] arr2) {
System.out.println("CA1");
for (final char c : arr1) {
System.out.println("\t" + c);
}
System.out.println("CA2");
for (final char c : arr2) {
System.out.println("\t" + c);
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
}
To check if two strings are permutable, i.e. an anagram, you have to compare two sorted arrays of characters of these strings. To do this, since Java 9, you can use the String#codePoints method. This code works with both regular characters and surrogate pairs.
public static void main(String[] args) {
// regular characters & surrogate pairs
System.out.println(checkIfAnagram("twowords", "dortwswo")); // true
System.out.println(checkIfAnagram("π”Έπ”Ήπ—–π”»π”ΌπŸ˜€", "π”Ήπ”ΈπŸ˜€π—–π”Όπ”»")); // true
}
/**
* #param str1 the first string
* #param str2 the second string
* #return whether two strings are an anagram
*/
public static boolean checkIfAnagram(String str1, String str2) {
// check if the input strings are not null
if (str1 == null || str2 == null) return false;
// sorted arrays of code points of input strings
int[] arr1 = str1.codePoints().sorted().toArray();
int[] arr2 = str2.codePoints().sorted().toArray();
// check if two sorted arrays are equal
return Arrays.equals(arr1, arr2);
}
Without using streams you can call the String#toCharArray() and Arrays.sort() methods separately. The result is the same, but there is a bit more code. This is enough for checking the equality of two arrays, but in this case the surrogate pairs will be separated after sorting, and such an array cannot be restored back to a string.
public static boolean checkIfAnagram(String str1, String str2) {
// check if the input strings are not null
if (str1 == null || str2 == null) return false;
// arrays of characters of input strings
char[] arr1 = str1.toCharArray();
char[] arr2 = str2.toCharArray();
// sorting arrays, surrogate pairs will be separated
Arrays.sort(arr1);
Arrays.sort(arr2);
// check if two sorted arrays are equal
return Arrays.equals(arr1, arr2);
}
See also: How can I check if two strings are anagrams?

Why an extra space is added to my Array List of String when I use split method on the string

I have attached my code and the output of the code. When I print the array elements, it is not showing any spaces but when these elements are transferred to the arrayList, I get these spaces before every element as if they are there because of the "/" in the actual string
This is my code
public static void main(String[] args) {
Scanner x = new Scanner(System.in);
String n= "/www/abc/pqr/./com";
String arr[] = n.split("/");
ArrayList<String> list = new ArrayList<>();
for(int i=0;i<arr.length;i++)
{
if(arr[i]!=".")
{
list.add(arr[i]);
}
}
System.out.println(list);
}
output is this :
[, www, abc, pqr, ., com]
I have also used equals() method to compare the strings but no luck with that too.
this is my updated code
public class LTI {
public static void main(String[] args) {
Scanner x = new Scanner(System.in);
String n = "/www/abc/../pqr/./com";
String arr[] = n.split("/");
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
if (!arr[i].isEmpty()) {
if (!arr[i].equals(".")) {
if (arr[i].equals("..")) {
list.remove(i);
} else {
list.add(arr[i]);
}
}
}
}
}
}
But it shows index 3 out of bounds for length 2
So I am assuming your question is aimed at these whitespaces you get in your output:
[, www, abc, pqr, ., com]
^ ^ ^ ^ ^
These "spaces" you see are not actually part of the Strings inside your list, they are added when you implicitly call toString() on the ArrayList via System.out.println(list).
See AbstractCollection#toString():
Returns a string representation of this collection. The string representation consists of a list of the collection's elements in the order they are returned by its iterator, enclosed in square brackets ("[]"). Adjacent elements are separated by the characters ", " (comma and space). Elements are converted to strings as by String.valueOf(Object).
So the actual Strings in your list do not contain these whitespaces, they are simply added for viewing convenience when printed.
Here is your updated code, that also fixes the issue of comparing the Strings correctly via equals instead of !=. I also included a isEmpty() check to remove the empty Strings from the list:
public static void main(String[] args) {
String n = "/www/abc/pqr/./com";
String arr[] = n.split("/");
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
if (!(arr[i].equals(".") || arr[i].isEmpty())) {
list.add(arr[i]);
}
}
System.out.println(list);
}
Output:
[www, abc, pqr, com]

Java Method for removing duplicates from char array

I have a char array filled by the user (arrayInput[]) with some characters, like {b, d, a, b, f, a, g, a, a, f}, and I need to create a method which returns a new char array with only the first occurrence of the character, but in the order of input. The book also says "A way to solve this problem is to create a boolean array to keep track of the characters to mantain!", but I can't imagine how the boolean array should work with the other arrays.
The main problem is that I can save in a boolean array if arrayInput contains a specific character, and even how many times, but only creating a very long ramified if-else into a for, like
if ((arrayOutput[i] == 'A') && (arrayControl[0] = false)) {
arrayControl[0] = true; }
where arrayOutput is the array I want to return from the method, arrayControl[0] is the value of 'A' in my boolean array I created into the method. A = 0, B = 1, ... Z = 25, a = 26, b = 27, ... 51 = z. For every single character, uppercase and lowercase, I created a place into the array, so I could check everything, but now I can't go any further. I don't know how to save the characters on arrayOutput, how to check if a character is already on arrayOutput and if it's already there, the array passes that specific character and go to the next one.
Also please remember I'm a newbie, so I know very little about Java. Please explain yourself the best you can. Thanks in advance!
This could work:
public static void main(String[] args) {
Main main = new Main();
char[] array = {'e','a','b','a','c','d','b','d','c','e'};
main.getCharArray(array);
}
private char[] getCharArray(char[] array) {
String _array = "";
for(int i = 0; i < array.length; i++) {
if(_array.indexOf(array[i]) == -1) // check if a char already exist, if not exist then return -1
_array = _array+array[i]; // add new char
}
return _array.toCharArray();
}
Output:
eabcd
boolean arr[26]; //considering only small letters arrive. otherwise take a larger array.
for( i=0;i<str.length;i++ )
arr[str[i]-'a']=true;
The ones at last after the loop are true are the actual character. (all duplicates eleminated).
To take into consideration the positions,
int arr[26];
//initialize all the array elemnts to 0
for( i=0;i<str.length();i++ )
if(i>=arr[str[i]-'a'])
arr[str[i]-'a']=i+1;
//Those greater than 0 are non-duplicated characters. Their poistion of first occurence= (arr[i]-1)
EDIT: I have last used java almost a year ago. The algorithm is shown properly. Sorry for my awkward java code.
This might help. Make a separate array and store only non-duplicate characters.
char[] removeDuplicates (char[] arrayInput) {
boolean exists[]=new boolean[26];
char arrayOutput[] = new char[26];
int ctr=0;
for(int i=0; i<26; i++) {
exists[i] = false;
}
for(int i=0; i<arrayInput.length; i++) {
if(!exists[arrayInput[i]-97]) {
exists[arrayInput[i]-97]=true;
arrayOutput[ctr++]=arrayInput[i];
}
}
return Arrays.copyOfRange(arrayOutput, 0, ctr);
}
If you consider using of collection framework then it would be much easier. Your array of char with duplicate is arrayInput. Now put each char from it to a HashSet like this -
HashSet<Character> uniqueCharSet = new HashSet<Character>();
for(char each : arrayInput){
uniqueCharSet.add(each);
}
Now the HashSet uniqueCharSet will contains only the unique characters from the char array arrayInput. Note here all element in uniqueCharSet are wrapper type - Character.
You can convert the HashSet uniqueCharSet to array of Character like this -
Object[] uniqueCharArray = uniqueCharSet.toArray();
And then you can use them like this -
for(Object each : uniqueCharArray){
Character c = (Character) each;
System.out.println(c);
}
Here's the method to achieve what you need:
public static void main(String[] args) {
char[] arr= {'A','B','C','A','B'};
HashSet<Character> hset=new HashSet<Character>();
for(int i=0;i<arr.length;i++) {
hset.add(arr[i]);
}
Object[] ObjChar=hset.toArray();
char[] resultArr = new char[ObjChar.length];
for(int j=0;j<ObjChar.length;j++) {
resultArr[j]=(char) ObjChar[j];
}
for(char eachChar: resultArr) {
System.out.println(eachChar);
}
}

removing duplicated words from an array

I am trying to remove duplicated words from an array, and I keep getting null values. I'm not allowed to use java sorting methods so I have to develop my own. Here's my code:
public class Duplicate{
public static void main(String[] args){
String[] test = {"a", "b", "abvc", "abccc", "a", "bbc", "ccc", "abc", "bbc"};
removeDuplicate(test);
}
public static String[] removeDuplicate(String[] words){
boolean [] isDuplicate = new boolean[words.length];
int i,j;
String[] tmp = new String[words.length];
for (i = 0; i < words.length ; i++){
if (isDuplicate[i])
continue;
for(j = 0; j < words.length ; j++){
if (words[i].equals(words[j])) {
isDuplicate[j] = true;
tmp[i] = words[i];
}
}
}
for(i=0;i<words.length;i++)
System.out.println(tmp[i]);
return tmp;
}
}
I tried doing
if(words == null)
words == "";
But it doesn't work. I also want to return the tmp array with a new size.
For example, test array length = 9, after removing the duplicates,I should get a new array with a length of 7.Thank you for your help.
EDIT:
result i get:
a
b
abvc
abccc
null
bbc
ccc
abc
null
You're getting nulls because the result array contains fewer words than the input array. However, you're constructing the arrays of the same length.
You don't have to sort to solve this problem. However, if you're not allowed to use the tools provided by java.utils, then this is either a poorly contrived test question or whomever told you not to use the Java utility classes is poorly informed.
You can solve without sorting by doing (assuming Java 1.5+):
public class Duplicate {
public static void main(String[] args) {
String[] test = {"a", "b", "abvc", "abccc", "a", "bbc", "ccc", "abc", "bbc"};
String[] deduped = removeDuplicate(test);
print(deduped);
}
public static String[] removeDuplicate(String[] words) {
Set<String> wordSet = new LinkedHashSet<String>();
for (String word : words) {
wordSet.add(word);
}
return wordSet.toArray(new String[wordSet.size()]);
}
public static void print(String[] words) {
for (String word : words) {
System.out.println(word);
}
}
}
The output will be:
a
b
abvc
abccc
bbc
ccc
abc
I would go for hashset to remove duplicates, it will remove duplicates since hash function for the same string will give same value, and duplicates will be eliminated. Then you can convert it to a string.
I would recommend doing this with a different approach. If you can use an ArrayList, why not just create one of those, and add the non-duplicate values to it, like this:
ArrayList<String> uniqueArrayList = new ArrayList<String>();
for(int i = 0; i < words.length; i++){
if(!uniqueArrayList.contains(words[i])){ // If the value isn't in the list already
uniqueArrayList.add(words[i]);
}
}
Now, you have an array list of all of your values without the duplicates. If you need to, you can work on converting that back to a regular array.
EDIT
I really think you should use the above option if you can, as there is no clean or decently efficient way to do this only using arrays. However, if you must, you can do something like this:
You can use the code you have to mark values as null if they are duplicates, and also create a counter to see how many unique values you have, like this:
int uniqueCounter = 0;
for(int i = 0; i < isDuplicate.length; i++){
if(!isDuplicate[i]){
uniqueCounter++;
}
}
Then, you can create a new array of the size of unique items, and loop through the words and add non-duplicate values.
String[] uniqueArray = new String[uniqueCounter];
int uniqueIndex = 0;
int wordsIndex = 0;
while(index < uniqueArray.length){
// Check if words index is not a duplicate
if(!isDuplicate[wordsIndex]){
// Add to array
uniqueArray[uniqueIndex] = words[wordsIndex];
uniqueIndex++; // Need to move to next spot in unique.
}
// Need to move to next spot in words
wordsIndex++;
}
Again, I HIGHLY recommend against something like this. It is very poor, and pains me to write, but for the sake of example on how it could be done using an array, you can try it.
I don't have the time to write functioning code, but I would reccomend to first sort the array using Arrays.sort(stringArray) and then loop throug the array coparing one string to the previous. Strings that match the previous one are duplicates.
Note: This method is probably not the fastest one and though only should be used on small arrays or in tasks where performance does not matter.
What about this approach?
public static String[] removeDuplicate(String[] words){
// remember which word is a duplicate
boolean[] isDuplicate = new boolean[words.length];
// and count them
int countDuplicate = 0;
for (int i = 0; i < words.length ; i++){
// only check "forward" because "backwards checked" duplicates have been marked yet
for(int j = i + 1; j < words.length ; j++){
if (words[i].equals(words[j])) {
isDuplicate[j] = true;
countDuplicate++;
}
}
}
// collect non-duplicate strings
String[] tmp = new String[words.length - countDuplicate];
int j = 0;
for (int i = 0; i < isDuplicate.length; i++) {
if (isDuplicate[i] == false) {
tmp[j] = words[i];
j++;
}
}
// and return them
return tmp;
}

Finding Palindromes in an Array

For this assignemnt, I think that I got it right, but when I submit it online, it doesn't list it as correct even though I checked with Eclipse.
The prompt:
Write a method isPalindrome that accepts an array of Strings as its argument and returns true if that array is a palindrome (if it reads the same forwards as backwards) and /false if not. For example, the array {"alpha", "beta", "gamma", "delta", "gamma", "beta", "alpha"} is a palindrome, so passing that array to your method would return true. Arrays with zero or one element are considered to be palindromes.
My code:
public static void main(String[] args) {
String[] input = new String[6]; //{"aay", "bee", "cee", "cee", "bee", "aay"} Should return true
input[0] = "aay";
input[1] = "bee";
input[2] = "cee";
input[3] = "cee";
input[4] = "bee";
input[5] = "aay";
System.out.println(isPalindrome(input));
}
public static boolean isPalindrome(String[] input) {
for (int i=0; i<input.length; i++) { // Checks each element
if (input[i] != input[input.length-1-i]){
return false; // If a single instance of non-symmetry
}
}
return true; // If symmetrical, only one element, or zero elements
}
As an example, {"aay", "bee", "cee", "cee", "bee", "aay"} returns true in Eclipse, but Practice-It! says it returns false. What is going on?
You cant use operator == or != to compare string object. The operators will work on the object references and not values.
public static boolean isPalindrome(String[] input) {
for (int i=0; i<input.length; i++) { // Checks each element
if (!input[i].equals( input[input.length-1-i])){
return false; // If a single instance of non-symmetry
}
}
return true; // If symmetrical, only one element, or zero elements
}
This is not how you compare Strings in Java. Use the following:
if (!input[i].equals(input[input.length-1-i])){
return false; // If a single instance of non-symmetry
}
Read this.

Categories

Resources