Java Beginner, comparing strings in nested for loop - java

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...");
}
}

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"));
}
}

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();
}
}

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.

Related

I am trying to check for Anagram

Why the code is showing me the error for missing return statement?
What I am trying to do is check the length of the string followed by its content and compare both of them.
import java.util.Scanner;
public class Solution {
static boolean isAnagram(String a, String b) {
char[] arr1 = a.toLowerCase().toCharArray();
char[] arr2 = b.toLowerCase().toCharArray();
java.util.Arrays.sort(arr1);
java.util.Arrays.sort(arr2);
if (arr1.length != arr2.length) {
if (!arr1.equals(arr2)) {
System.out.println("Not Anagrams");
}
return false;
} else if (arr1.equals(arr2)) {
System.out.println("Anagrams");
return true;
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String a = scan.next();
String b = scan.next();
scan.close();
boolean ret = isAnagram(a, b);
System.out.println((ret) ? "Anagrams" : "Not Anagrams");
}
}
PRIMARY QUESTION
You need to have a "return" outside if statements.
else if(arr1.equals(arr2))
{
System.out.println("Anagrams");
return true;
}
return false; //add this here. I tested, error goes after this.
}
Tested here - https://onlinegdb.com/S188-FdGL
EXTRA
Your Anagram logic is wrong.
The correct logic should be like this (follow comments to understand).
import java.util.Scanner;
import java.util.Arrays;
public class Solution {
static boolean isAnagram(String a, String b)
{
char[] arr1 = a.toLowerCase().toCharArray();
char[] arr2 = b.toLowerCase().toCharArray();
int n1 = arr1.length;
int n2 = arr2.length;
// If length is different, then they cannot be Anagram
if (n1 != n2) return false;
// Sort the Character Arrays
Arrays.sort(arr1);
Arrays.sort(arr2);
// Compare each characters of sorted Character Arrays,
// if any character mismatches, it is not an Anagram
for (int i = 0; i < n1; i++)
if (arr1[i] != arr2[i])
return false;
// If all characters of both character Arrays are same,
// only then, the String are Anagrams, so return true
return true;
// Also, remove the print statements from this method,
// as you are already printing in the main method,
// so it creates duplicate prints
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String a = scan.next();
String b = scan.next();
scan.close();
boolean ret = isAnagram(a, b);
System.out.println( (ret) ? "Anagrams" : "Not Anagrams" );
}
}
Tested here - https://onlinegdb.com/rJe-OEtuGL

Java Poem Palindrome Checker: Iterate through array matching elements in order

Currently trying to program a poem Palindrome checker. This is not for palindromes specifically, but that the array has words in the same order both ways. For example the following is a poem palindrome
Life-
imitates nature,
always moving, traveling continuously.
Continuously traveling, moving always,
nature imitates
life
My issue is iterating through the array to match the first and last elements, as currently it compares things in the wrong order.
My code is as follows:
import java.util.Scanner;
import java.io.*;
public class WordPalindromeTest {
public static void main(String[] args) {
System.out.println("This program determines if an entered sentence/word poem is a palindrome.");
Scanner input = new Scanner(System.in);
System.out.println("Please enter a string to determine if it is a palindrome: ");
while(input.hasNextLine()) {
String palin = input.nextLine();
if(palin.equals("quit")) {
break;
}
else {
boolean isPalin = isWordPalindrome(palin);
if(isPalin == true) {
System.out.println(palin + " is a palindrome!");
}
else
System.out.println(palin + " is NOT a palindrome!");
}
}
System.out.println("Goodbye!");
input.close();
}
public static boolean isWordPalindrome(String s) {
boolean isWordPal = false;
String lowerCase = s.toLowerCase();
String replaced = lowerCase.replaceAll("[^a-zA-Z0-9\\s]", "");
String words[] = replaced.split(" ");
for(int i = 0; i < words.length; i++) {
for(int j = 0; j < words.length; j++) {
if (words[i].equals(words[j]) && i != j) {
isWordPal = true;
}
else
isWordPal = false;
}
}
return isWordPal;
}
}
With the specific point in question being
public static boolean isWordPalindrome(String s) {
boolean isWordPal = false;
String lowerCase = s.toLowerCase();
String replaced = lowerCase.replaceAll("[^a-zA-Z0-9\\s]", "");
String words[] = replaced.split(" ");
for(int i = 0; i < words.length; i++) {
for(int j = 0; j < words.length; j++) {
if (words[i].equals(words[j]) && i != j) {
isWordPal = true;
}
else
isWordPal = false;
}
}
return isWordPal;
}
I am confused on how to properly set up the loop to compare the right elements. It should compare the first element to the last, the second to the second to last, etc. until the loop is finished. I realize I have it compare the first to the entire array before moving on.
This seems like a homework assignment so I won't give you a working solution. But this of it like this:
-You don't need two loops. You only need to compare the first to the last, the second to the second to last, etc. (Hint: if you subtract i-1 from the length of the Array you'll get the corresponding element to i that you need to compare to). Also you only need to iterate over half of the length of the Array
-If ever isWordPal becomes false, you need to return false. Otherwise it might get overwritten and at the end it will return true.

check if two strings are permutation of each other?

I am solving this question as an assignment of the school. But the two of my test cases are coming out wrong when I submit the code? I don't know what went wrong. I have checked various other test cases and corner cases and it all coming out right.
Here is my code:
public static boolean isPermutation(String input1, String input2) {
if(input1.length() != input2.length())
{
return false;
}
int index1 =0;
int index2 =0;
int count=0;
while(index2<input2.length())
{
while(index1<input1.length())
{
if( input1.charAt(index1)==input2.charAt(index2) )
{
index1=0;
count++;
break;
}
index1++;
}
index2++;
}
if(count==input1.length())
{
return true;
}
return false;
}
SAMPLE INPUT
abcde
baedc
output
true
SAMPLE INPUT
abc
cbd
output
false
A simpler solution would be to sort the characters in both strings and compare those character arrays.
String.toCharArray() returns an array of characters from a String
Arrays.sort(char \[\]) to sort a character array
Arrays.equals(char \[\], char \[\]) to compare the arrays
Example
public static void main(String[] args) {
System.out.println(isPermutation("hello", "olleh"));
System.out.println(isPermutation("hell", "leh"));
System.out.println(isPermutation("world", "wdolr"));
}
private static boolean isPermutation(String a, String b) {
char [] aArray = a.toCharArray();
char [] bArray = b.toCharArray();
Arrays.sort(aArray);
Arrays.sort(bArray);
return Arrays.equals(aArray, bArray);
}
A more long-winded solution without sorting would to be check every character in A is also in B
private static boolean isPermutation(String a, String b) {
char[] aArray = a.toCharArray();
char[] bArray = b.toCharArray();
if (a.length() != b.length()) {
return false;
}
int found = 0;
for (int i = 0; i < aArray.length; i++) {
char eachA = aArray[i];
// check each character in A is found in B
for (int k = 0; k < bArray.length; k++) {
if (eachA == bArray[k]) {
found++;
bArray[k] = '\uFFFF'; // clear so we don't find again
break;
}
}
}
return found == a.length();
}
You have two ways to proceed
Sort both strings and then compare both strings
Count the characters in string and then match.
Follow the tutorial here
In case you String is ASCII you may use the next approach:
Create 256 elements int array
Increment element of corresponding character whenever it's found in string1
Decrement element of corresponding character whenever it's found in string2
If all elements are 0, then string2 is permutation of string1
Overall complexity of this approach is O(n). The only drawback is space allocation for charCount array:
public static boolean isPermutation(String s1, String s2) {
if (s1.length() != s2.length()) {
return false;
}
int[] charCount = new int[256];
for (int i = 0; i < s1.length(); i++) {
charCount[s1.charAt(i)]++;
charCount[s2.charAt(i)]--;
}
for (int i = 0; i < charCount.length; i++) {
if (charCount[i] != 0) {
return false;
}
}
return true;
}
If your strings can hold non-ASCII values, the same approach could be implemented using HashMap<String, Integer> as character count storage
I have a recursive method to solve the permutations problem. I think that this code will seem to be tough but if you will try to understand it you will see the beauty of this code. Recursion is always hard to understand but good to use! This method returns all the permutations of the entered String 's' and keeps storing them in the array 'arr[]'. The value of 't' initially is blank "" .
import java.io.*;
class permute_compare2str
{
static String[] arr= new String [1200];
static int p=0;
void permutation(String s,String t)
{
if (s.length()==0)
{
arr[p++]=t;
return;
}
for(int i=0;i<s.length();i++)
permutation(s.substring(0,i)+s.substring(i+1),t+s.charAt(i));
}
public static void main(String kr[])throws IOException
{
int flag = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the first String:");
String str1 = br.readLine();
System.out.println("Enter the second String:");
String str2 = br.readLine();
new permute_compare2str().permutation(str1,"");
for(int i = 0; i < p; ++i)
{
if(arr[i].equals(str2))
{
flag = 1;
break;
}
}
if(flag == 1)
System.out.println("True");
else
{
System.out.println("False");
return;
}
}
}
One limitation that I can see is that the length of the array is fixed and so will not be able to return values for a large String value 's'. Please alter the same as per the requirements. There are other solution to this problem as well.
I have shared this code because you can actually use this to get the permutations of a string printed directly without the array as well.
HERE:
void permutations(String s,String t)
{
if (s.length()==0)
{
System.out.print(t+" ");
return;
}
for(int i=0;i<s.length();i++)
permutations(s.substring(0,i)+s.substring(i+1),t+s.charAt(i));
}
Value of 's' is the string whose permutations is needed and value of 't' is again empty "".
it will take O(n log n) cuz i sort each string and i used more space to store each one
public static boolean checkPermutation(String a,String b){
return sortString(a).equals(sortString(b));
}
private static String sortString(String test) {
char[] tempChar = test.toCharArray();
Arrays.sort(tempChar);
return new String(tempChar);
}
String checkPermutation(String a,String b){
char[] aArr = a.toCharArray();
char[] bArr = b.toCharArray();
Arrays.sort(aArr);
Arrays.sort(bArr);
if(aArr.length != bArr.length){
return "NO";
}
int p = 0, q = 0;
while(p < aArr.length){
if(aArr[p] != bArr[q]){
return "NO";
}
p++;
q++;
}
return "YES";
}
public static boolean isStringArePermutate(String s1, String s2){
if(s1==null || s2==null) {
return false;
}
int len1 = s1.length();
int len2 =s2.length();
if(len1!=len2){
return false;
}
for(int i =0;i<len1;i++){
if(!s1.contains(String.valueOf(s2.charAt(i)))) {
return false;
}
s1=s1.replaceFirst(String.valueOf(s2.charAt(i)), "");
}
if(s1.equals("")) {
return true;
}
return false;
}

String Output Alignment in Java

practice question part 1
practice question part 2
This is a practice question which is rather hard for me. Below is my code for the static method(the main method is fixed -unchangeable, and signature of static method is given), and my intention is to get the matches between the characters and print them out.
But there are some concerns:
1) How do i ensure it doesn't print when all the strings are aligned but there are extra characters which makes the boolean false and the result to be not aligned instead? (e.g amgk as second string & first string is Java Programming Course)
2) How do i make it print right? currently the spaces are off and the letters aren't what is wanted.
3) If there is more than one character a in str1, which do i choose to put, and how do i omit the rest when there is already a match?
Would really appreciate a pseudocode to help guide a beginner like me in solving this problem.
public class Q3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter the first string:");
String input1 = sc.nextLine();
System.out.print("Enter the second string:");
String input2 = sc.nextLine();
System.out.println();
if (matchStrings(input1, input2)) {
System.out.println();
System.out.println("There is an alignment as shown above.");
} else {
System.out.println("No alignment can be found.");
}
}
public static boolean matchStrings(String str1, String str2) {
// Modify the code below to return the correct value.
boolean isMatch = false;
//int firstChar = str2.charAt(0);
//int lastChar = str2.charAt(str2.length()-1);
int prevIndex = 0;
System.out.println(str1);
for (int j = 0; j< str2.length(); j++) {
for (int i = 0; i<str1.length();i++) {
char charToSearch = str1.charAt(i);
int newIndex = i;
if (str2.charAt(j)== charToSearch) {
for (int k = prevIndex; k < newIndex-1; k++) {
System.out.print(" ");
}
System.out.print(charToSearch);
//prevIndex=newIndex+1;
isMatch = true;
}
}
}
return isMatch;
}
}
I think two of the first few structures you learn in a Data Structures course is the stack and queue. Thus, I will provide an implementation using a Stack. You can use a Stack to store the test String and pop each char element off the stack when it is matched up with a character in the first string. Otherwise you would output an empty space " " in the matched String object:
Stack s2 = new Stack();
String str1 = "Java Programming";
String str2 = "amg";
for(int i = str2.length()-1; i >= 0; i--){ //Need to populate the stack backwards...LIFO
s2.push(str2.charAt(i));
}
String match = ""; //Used to store the matching line
for(int i = 0; i < str1.length(); i++){
if(str1.charAt(i) == (char)s2.peek()){
match += s2.pop().toString();
}
else
{
match += " ";
}
}
System.out.println(str1);
System.out.println(match);
You can also use a Queue for this, but I will leave that for you to learn on your own. Also practice on creating your own Stack object using arrays and integer pointers to handle overflow/underflow.
The above code would print out:

Palindrome detector returns true even when it's not a palindrome

I need to make sure that on every assignment that I do, I have to write my own original code and not copy someone else's. It seems harder than you would expect. I'm trying to write a palindrome detector as part of an assignment. The code is good, except for one problem. The output says it's true, even when it's not a palindrome and it begins and ends with the same character. May you please help me. Here is my code:
public static boolean isPalindrome_nr(String word){
int beginning = 0;
int end = word.length() - 1;
boolean pd = true;
for (int i = end; i>0; i--){
if(word.charAt(0) == word.charAt(word.length()-1)){
pd = true;
}
else if (word.charAt(0) != word.charAt(word.length()-i)){
pd = false;
}
}
return pd;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
System.out.println("Is the string a palindrome or not? ");
String test = scan.nextLine();
System.out.println("Answer: " + isPalindrome_nr(test));
}
The goal is to get the word test, which is not a palindrome, registered as false, abba, which is a palindrome, registered as true, and application, which is not a palindrome, registered as false.
You are only comparing the first and last characters. That's not nearly enough to determine if a String is a palindrome.
You need something like this :
pd = true;
for (int i = end; i>=0; i--){
if(word.charAt(i) != word.charAt(end-i)){
pd = false;
break;
}
}
This can be further improved, since this loop would test all the pairs twice, so it's probably enough that i ends at end/2 or (end/2)+1.
You're only checking the first and last characters. The method should look like this so that your for-loop actually does what it's supposed to:
public static boolean isPalindrome_nr(String word) {
int beginning = 0;
int end = word.length() - 1;
boolean pd = true;
for (int i = end; i > 0; i--) {
// notice the use of i in here so that it will check all opposite chars
if(word.charAt(i) == word.charAt(word.length() - 1 - i)) {
pd = true;
}
else { // don't need the else-if
pd = false;
}
}
return pd;
}
Just as an extra note, there is another way to test if a string is a palindrome or not: reverse it and test if the reversed string is equal to the original string. Like this (it's a one-liner):
public static boolean isPalindrome(String s) {
return new StringBuilder(s).reverse().toString().equals(s);
}
Or the longer way (reversing the string with a for-loop instead of using the StringBuilder#reverse() method
public static boolean isPalindrome(String s) {
StringBuilder reverseString = new StringBuilder();
// reverse the string
for (int i = s.length() - 1; i > -1; i--) {
reverseString.append(s.charAt(i));
}
// return whether or not the reversed string is equal to the original string
return reverseString.toString().equals(s);
}

Categories

Resources