-2

Here is the problem statement: Write a function that compares 2 strings to return true or false depending on if both strings contain the same letters. Order doesn't matter.

I do not know how to properly compare the character arrays in my nested for loop. I wish I could be more specific with what my issue is, but I'm a really new learner and can't see why this isn't working. I do believe it's not doing what I would like in the nested for loops. Thanks in advance!

import java.util.Scanner;

public class PracticeProblems { 

public static boolean stringCompare(String word1, String word2) {
    char[] word1b = new char[word1.length()];
    char[] word2b = new char[word2.length()];
    boolean compareBool = false;

    for(int i = 0; i < word1.length(); i++) {
        word1b[i] = word1.charAt(i);
        word2b[i] = word2.charAt(i);
    }   

    for(int i = 0; i < word1.length(); i++) {
        for(int j = 0; j < word2.length(); j++) {
            if(word1b[i] == word2b[j]) {
                compareBool = true;
                break;
            } else {
                compareBool = false;
                break;
            }
        }
    }   
    return compareBool;
}

public static void main(String []args) {
    Scanner scan = new Scanner(System.in);
    System.out.println("Word 1?");
    String word1 = scan.nextLine();
    System.out.println("Word 2?");
    String word2 = scan.nextLine();

    if(PracticeProblems.stringCompare(word1, word2) == true) {
        System.out.println("Same Letters!");
    } else {
        System.out.println("Different Letters...");
    }

}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
waffles
  • 208
  • 2
  • 11
  • 1
    You always `break` on the first time through the loop. Remove the `break` in the `if` and leave the one in the `else`. – resueman Feb 17 '17 at 19:27
  • Why not just `char[] word1b = word1.toCharArray();`? (Or, compare `word1.charAt(i)` and `word2.charAt(j)`, which avoids creating new arrays). – Andy Turner Feb 17 '17 at 19:27
  • Put the characters of each `String` into a `Set`. Then compare the sets. – Frank Puffer Feb 17 '17 at 19:28
  • @AndyTurner, this is not really a duplicate of the question I mentioned. It is a newbie level question, but not about `==` vs `equals()`. My mistake. – Grzegorz Górkiewicz Feb 17 '17 at 19:29
  • @GrzegorzGórkiewicz yeah, I realized it wasn't. – Andy Turner Feb 17 '17 at 19:29
  • Another fact is that you do not compare lengths of those words... which may result in an `IndexOutOfBoundsException` in the first for loop. – Grzegorz Górkiewicz Feb 17 '17 at 19:35
  • 1
    Also, note that you are checking whether all of the letters in `word1` are in `word2`; not also that all of the letters in `word2` are in `word1`. – Andy Turner Feb 17 '17 at 19:36
  • A couple of details: If the problem statement is to be taken literally, you should filter out chars that are not letters (like spaces and digits, for example). If `word2` is shorter than `word1`, I’m afraid you will hit a `StringIndexOutOfBoundsException`. – Ole V.V. Feb 17 '17 at 20:09

3 Answers3

2

The code below will do the job. This is essentially an expansion of Frank's comment above. We convert the two strings to two sets and then compare.

import java.util.*;

public class SameChars {

    // Logic to convert the string to a set
    public static Set<Character> stringToCharSet(String str) {
       Set<Character> charSet = new HashSet<Character>();
       char arrayChar[] = str.toCharArray();
       for (char aChar : arrayChar) {
          charSet.add(aChar);
       }

       return charSet;
    }

    // Compares the two sets
    public static boolean hasSameChars(String str1, String str2) {
       return stringToCharSet(str1).equals(stringToCharSet(str2));
    }

    public static void main(String args[]){
        // Should return true
        System.out.println(hasSameChars("hello", "olleh"));
        // Should returns false
        System.out.println(hasSameChars("hellox", "olleh"));
    }

}
Andre M
  • 6,649
  • 7
  • 52
  • 93
  • Can you think how to do it without using a set? :) – Andy Turner Feb 17 '17 at 20:00
  • 2
    First check if strings are same length, if they are then create two arrays from the strings, sort and then compare the indexes. The rest is homework :) – Andre M Feb 17 '17 at 20:19
  • Wouldn't that have made a better answer? – Andy Turner Feb 17 '17 at 20:21
  • Suggesting that the rest is homework? For the alternative approach: there are many ways to do things in programming. If it gets the job done and performance is acceptable, then time to deal with the rest of the backlog. You can optimise once the backlog is empty or if it is really critical. – Andre M Feb 17 '17 at 20:40
2

I sorted arrays before comparing.

    //import statement for Arrays class
    import java.util.Arrays;
    import java.util.Scanner;

    public class PracticeProblems { 

    public static boolean stringCompare(String word1, String word2) {
        char[] word1b = new char[word1.length()];
        char[] word2b = new char[word2.length()];

        boolean compareBool = true;

        for(int i = 0; i < word1.length(); i++) {
            word1b[i] = word1.charAt(i);
        }   
        //sort the new char array
        Arrays.sort(word1b);


        // added a second loop to for the second world
        for(int i = 0; i < word2.length(); i++) {
            word2b[i] = word2.charAt(i);
        } 

        Arrays.sort(word2b);

        for(int i = 0; i < word1.length(); i++) {

            //removed second for loop. 
    //        for(int j = 0; j < word2.length(); j++) {

            // if the two strings have different length, then they are different
            if((word1.length()!=word2.length())){
                compareBool = false;
                break;

            }
            //changed to not equal  
            if( (word1b[i] != word2b[i]) ) {
                compareBool = false;
                break;

            } 
            //removed else statment
    //      else {
    //                compareBool = false;
    //                break;
    //
    //        }
        }   
        return compareBool;
    }

    public static void main(String []args) {
        Scanner scan = new Scanner(System.in);
        System.out.println("Word 1?");
        String word1 = scan.nextLine();
        System.out.println("Word 2?");
        String word2 = scan.nextLine();

        if(PracticeProblems.stringCompare(word1, word2) == true) {
            System.out.println("Same Letters!");
        } else {
            System.out.println("Different Letters...");
        }
        //resource leak.  use close() method.
        scan.close();
    }
    }
Girum A
  • 63
  • 10
  • Nice explanation. I am a bit in doubt whether your version is correct if the user enters `ease` and `seas`. They contain the same letters, namely a, e and s, only not equally many of each. If it's a school assignment, it may be that either result is acceptable, if only it's specified what the program does. – Ole V.V. Feb 17 '17 at 22:37
1

Allow me to rename your boolean variable to letterFound (or maybe even letterFoundInWord2) because this is what you are checking in your double loop. Explanatory naming makes it easier to keep the thoughts clear.

Since you are checking one letter from word1 at a time, you can move the declaration of letterFound inside the outer for loop and initialize it to false here since each time you take a new letter from word1 you haven’t found it in word2 yet. In your if statement inside the for loops, it is correct to break in the case the letters are the same and you set letterFound to true. In the opposite case, don’t break, just go on to check the next letter. In fact you can delete the else part completely.

After the inner for loop, if letterFound is still not true, we know that the letter from word1 is not in word2. So stringCompare() should return false:

if (! letterFound) {
    return false;
}

With this change, after the outer for loop we know that all letters from word1 were found in word2, so you can type return true; here.

Except:

  • You seem to be assuming the strings have the same length. If they have not, you program will not work correctly.
  • As Andy Turner said, you should also check that all the letters in word2 are in word1; it doesn’t follow from the letters from word1 being in word2.
  • Should only letters be considered? Should you ignore spaces, digits, punctuation, …?

Hope you will be able to figure it out. Feel free to follow up in comments or ask a new question.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161