How to find anagram for 2 Strings - java

I have written a Java program to find Anagram for 2 strings.
For Reference:
Two strings are anagrams if they are written using the same exact letters, ignoring space, punctuation and capitalization. Each letter should have the same count in both strings. For example, Army and Mary are anagram of each other.
Program:
package practice;
import java.util.ArrayList;
import java.util.List;
public class Anagram_String {
public static void main(String[] args) {
String s1="mary";
String s2="army";
int k=0;
List<String> matchedChar= new ArrayList<String>();
String charmatch="";
char[] ch1= s1.toLowerCase().toCharArray();
char[] ch2= s2.toLowerCase().toCharArray();
if(s1.length()==s2.length())
{
for(int i=0;i<s1.length();i++)
{
for(int j=0;j<s2.length();j++)
{
if(ch1[i]==ch2[j])
{
k++;
charmatch=String.valueOf(ch1[i]);
System.out.println(charmatch);
matchedChar.add(charmatch);
System.out.println("Arraylist value is "+matchedChar.toString());
System.out.println(matchedChar.size());
}
}
k=0;
}
String arrayValue=matchedChar.toString();
System.out.println("Array value is "+arrayValue);
if(arrayValue.contains(s2)){
System.out.println("String 1 and String 2 are anagrams of each other");
}
else
{
System.out.println("String 1 and String 2 are not anagrams of each other");
}
}
}
}
Output:
m
Arraylist value is [m]
1
a
Arraylist value is [m, a]
2
r
Arraylist value is [m, a, r]
3
y
Arraylist value is [m, a, r, y]
4
Array value is [m, a, r, y]
String 1 and String 2 are not anagrams of each other
Here if you see all the characters are added to to the arraylist but when compared with the string, it is showing the output as they are not anagrams of each other.
Kindly help me to find solution for this.
Thank you,

What I think is that your solution will work only for words with unique characters, and time complexity will be O(n^2) (where n - is the length of String).
However, there is a better solution for such problem:
Take String.toCharArray() value for each string
Sort those arrays
If those arrays are equal, then your words are anagrams

You can count number of letters in both strings. If both strings have the same number of letters they are anagrams.
You can use an int[] to store number of letters.
public static boolean anagrams(String a, String b) {
int[] letters = new int[26];
// Convert to upper case because the test is case insensitive
a = a.toUpperCase();
b = b.toUpperCase();
for (int i = 0; i < a.length(); i++) {
char ch = a.charAt(i);
if (ch < 'A' || ch > 'Z') {
continue; // Skip non letters
}
letters[ch - 'A']++; // Increment number of the current letter
}
for (int i = 0; i < b.length(); i++) {
char ch = b.charAt(i);
if (ch < 'A' || ch > 'Z') {
continue; // Skip non letters
}
letters[ch - 'A']--; // Decrement number of the current letter
}
for (int i = 0; i < letters.length; i++) {
if (letters[i] != 0) {
// If there are more or less of this letter
// in the first string it is not an anagram
return false;
}
}
return true;
}
Note this algorithm is done in O(n) where n is the number of letters of each string. Sorting the strings needs at least O(n log(n))
Taking the idea from AxelH's comments it is possible to create an external method to loop as follow.
private void countLetters(int[] letters, String str, int incrementFactor) {
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch < 'A' || ch > 'Z') {
continue; // Skip non letters
}
letters[ch - 'A'] += incrementFactor;
}
}
public static boolean anagrams(String a, String b) {
int[] letters = new int[26];
countLetters(letters, a.toUpperCase(), 1); // Note the +1
countLetters(letters, b.toUpperCase(), -1); // Note the -1
for (int i = 0; i < letters.length; i++) {
if (letters[i] != 0) {
// If there are more or less of this letter
// in the first string it is not an anagram
return false;
}
}
return true;
}
This seems to me a more readable and elegant way. Thanks AxelH.
Note In the previous code there are expressions like letters[ch - 'A']++. This line of code use an interesting properties of type char of java that is a special primitive numeric type, so it is possible to use mathematical operations on it.
In particular:
'A' - 'A' --> 0
'B' - 'A' --> 1
'C' - 'A' --> 2
'D' - 'A' --> 3
...
'Z' - 'A' --> 25
So this expression can be used to give an index to a letter starting from 0 for A ending to 25 for Z.

My answer is quite similar to Marine's, but takes a little higher-level approach with Java 8 streams, making the code a little more concise and readable:
public class Application {
public boolean isAnagramsEqual(String str1, String str2) {
Map<Character, Long> count = countChars(str1);
Map<Character, Long> count2 = countChars(str2);
return count.equals(count2);
}
private Map<Character, Long> countChars(String str) {
return str.toLowerCase()
.chars().mapToObj(ch -> (char) ch) //convert into stream of Characters
.filter(Character::isLetterOrDigit) //filter out not-needed chars
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}}
Method countChars creates a map with each unique character mapped to it's count in the given string.
It may be a little less performant than Marine's, but it's still O(n).

Your outputs says it itself:
Array value is [m, a, r, y]
As mentioned above I would also just create array and sort them, but here is the solution you may be searching for:
String s1="mary";
String s2="army";
List<String> matchedChar= new ArrayList<String>();
String charmatch="";
char[] ch1= s1.toLowerCase().toCharArray();
char[] ch2= s2.toLowerCase().toCharArray();
if(s1.length()==s2.length())
{
for(int i=0;i<s1.length();i++)
{
for(int j=0;j<s2.length();j++)
{
if(ch1[i]==ch2[j])
{
charmatch=String.valueOf(ch1[i]);
System.out.println(charmatch);
matchedChar.add(charmatch);
System.out.println("Arraylist value is "+matchedChar.toString());
System.out.println(matchedChar.size());
}
}
}
String arrayValue="";
for (String s : matchedChar){
arrayValue = arrayValue + s;
}
System.out.println("Array value is "+arrayValue);
System.out.println("s1 value is "+s1);
if(arrayValue.equals(s1)){
System.out.println("String 1 and String 2 are anagrams of each other");
}
else
{
System.out.println("String 1 and String 2 are not anagrams of each other");
}
}

Use .split("(?!^)") on your String to make it an String Array. Next sort arrays and compare it. It's the best option for me too.

This is how you can do it by sorting the arrays:
public static void main(String[] args) {
System.out.println(isAnagram("mary", "army"));
}
public static boolean isAnagram(String s1, String s2){
char[] c1 = s1.toLowerCase().toCharArray();
char[] c2 = s2.toLowerCase().toCharArray();
Arrays.sort(c1);
Arrays.sort(c2);
boolean anagram = false;
if(Arrays.equals(c1, c2)){anagram = true;}
return anagram;
}

In this code i converted my string into char array using the code :String.toCharArray() inside a function named toSort() and sorted the words in the string. Then inside Isanagram() method I checked whether it is anagram or not. For that first I have to make sure whether the sorted strings are of same length or not after I compared each character in one string with other.
Here is the full code try to decompose each method and study.
import java.util.Scanner;
public class StANaEx1 {
String toSort(String s5){
int i,j;
char temp;
char ch1[] = s5.toCharArray();
int len = ch1.length;
for(i=0;i<len;i++){
for(j=i+1;j<len;j++){
if(ch1[i]>ch1[j]){
temp = ch1[i];
ch1[i] = ch1[j];
ch1[j] = temp;
}
}
}
String s6 = new String(ch1);
return s6;
}
void isAnagram(String s9,String s10){
int i,len1,len2,flag=0;
System.out.println("s9 : "+s9);
System.out.println("s10 : "+s10);
System.out.println("");
s9 = s9.trim(); //To remove white spaces again no need.I used because my compiler didn't recognize my replace() method in main() method.
s10 = s10.trim();
len1 = s9.length();
len2 = s10.length();
System.out.println("len1 : "+len1); //To check the length of the given strings without white spaces.
System.out.println("len2 : "+len2);
System.out.println("");
for(i=0;i<len1;i++){
System.out.println("s9["+i+"] : "+s9.charAt(i)); //Error checking.
}
System.out.println("");
for(i=0;i<len2;i++){
System.out.println("s10["+i+"] : "+s10.charAt(i));
}
System.out.println("");
if(len1!=len2){
System.out.println("Not Anagram string length different");
}
else{
for(i=0;i<len1;i++){ //Since string lengths are same len1 = len2.
if(s9.charAt(i)!=s10.charAt(i)){
flag=1;
break;
}
}
if(flag==0){
System.out.println("Anagram");
}
else{
System.out.println("Not Anagram");
}
}
}
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
StANaEx1 ob1 = new StANaEx1();
System.out.println("-----Anagram checking-----");
System.out.println("");
System.out.println("Enter the 1st String: ");
System.out.println("");
String s1 = sc.nextLine();
s1 = s1.replace("//s", ""); //This is to remove white spaces.
String s3 = s1.toLowerCase(); //Change the input string to lower case in order to make sorting easy.
System.out.println("");
System.out.println("Enter the next String: ");
String s2 = sc.nextLine();
s2 = s2.replace("//s", "");
String s4 = s2.toLowerCase();
System.out.println("");
String s7 = ob1.toSort(s3);
String s8 = ob1.toSort(s4);
ob1.isAnagram(s7,s8);
sc.close();
}
}
Output
-----Anagram checking-----
Enter the 1st String:
Mary
Enter the next String:
army
s9 : amry
s10 : amry
len1 : 4
len2 : 4
s9[0] : a
s9[1] : m
s9[2] : r
s9[3] : y
s10[0] : a
s10[1] : m
s10[2] : r
s10[3] : y
Anagram
Output 2
-----Anagram checking-----
Enter the 1st String:
Sniper
Enter the next String:
kill
s9 : einprs
s10 : ikll
len1 : 6
len2 : 4
s9[0] : e
s9[1] : i
s9[2] : n
s9[3] : p
s9[4] : r
s9[5] : s
s10[0] : i
s10[1] : k
s10[2] : l
s10[3] : l
Not Anagram string length different

import java.util.Arrays;
public class AnagramString {
public static void main(String[] args) {
String str1="Keep";
String str2="peek";
//convert the string into the array with lower casing its character
char arrstr1[]=str1.toLowerCase().toCharArray();
char arrstr2[]=str2.toLowerCase().toCharArray();
//sort the array of character by acending order
Arrays.sort(arrstr1);
Arrays.sort(arrstr2);
//set true boolean value to the status
boolean status=true;
//comparing the char array
status = Arrays.equals(arrstr1, arrstr2);//here we get true value if they are containing the same character
System.out.println(Arrays.toString(arrstr1));
System.out.println(Arrays.toString(arrstr2));
if(arrstr1.length==arrstr2.length && status) {
System.out.println("2 string are anagram");
}else {
System.out.println("2 string are not anagram");
}
}
}

Related

Determining the highest word alphabetically without arrays in java

I have been trying to write a program that does 2 things, finds the longest word in a user generated string and finding the highest word in alphabetical order. I have the longest word working fine, but I cant figure out the alphabetical problem to save my life. the problem I'm running into is how it is comparing the words running in the for loops. Any help would be appreciated!
/*
CSC 190
Hw7
Ryan Burchfield
10/19/17
Purpose: Take a string and return both the Longest and largest words in the String.
*/
package hw7;
import java.util.Scanner;
class MyString{
String s;
MyString( String s1 ){
s=s1;
}
void setString(String s1){
s=s1;
}
String getLongest(String s1){
s1 = s1 +" ";
int length = s1.length();
String temp="", longestw="";
char ltr;
int templ, longest=0;
for(int i=0; i<length;i++){
ltr = s1.charAt(i);
if(ltr!=' ' && ltr!=',' && ltr!='.'){
temp=temp+ltr;
}
else{
templ=temp.length();
if(templ>longest){
longest=templ;
longestw=temp;
}
temp="";
}
}
return longestw;
}
String getLargest(String s1){
s1= s1 + " ";
String temp="", curWord="",largestW="";
char ltr;
for(int i=0; i<s1.length(); i++){
ltr = s1.charAt(i);
if(ltr!=' ' && ltr!=',' && ltr!='.'){
temp= temp + ltr;
}else{
char ltr1;
for(int j=0; j<s1.length(); j++){
ltr1 = s1.charAt(j);
if(ltr1!=' ' && ltr1!=',' && ltr1!='.'){
curWord= curWord + ltr1;
}
else{
int largest = temp.compareToIgnoreCase(curWord);
System.out.println(temp+","+curWord+","+temp.compareToIgnoreCase(curWord));
System.out.println(largest);
if(largest > 0){
largestW=curWord;
}else{
largestW=temp;
}
curWord="";
temp="";
}
}
}
}
return largestW;
}
}
public class Hw7 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Please enter a series of words: ");
String s = in.nextLine();
MyString s1 = new MyString(s);
System.out.println("The longest word is: " + s1.getLongest(s));
System.out.println("The largest word is: " + s1.getLargest(s));
}
}
if(largest > 0){
largestW=curWord;
}else{
largestW=temp;
}
This is where the program goes wrong. You did not compare currWord / temp with largestW
A better way to write getLargest() is to use the same way as getLongest(), i.e. using one loop, and compare largestW with temp every time (if largestW is empty then just set largestW = temp)
I would solve this with a single method that takes a Comparator<String> and the input String; construct a Scanner using the Scanner(String) constructor and modify the delimiter using Scanner#useDelimiter(String) to consume white space, commas, and literal '.'. Then use the supplied Comparator to compare the tokens available through the Scanner. Like,
static String findWord(Comparator<String> comp, String s1) {
Scanner sc = new Scanner(s1);
sc.useDelimiter("[\\s,\\.]+");
String max = null;
while (sc.hasNext()) {
String token = sc.next();
if (max == null || comp.compare(max, token) < 0) {
max = token;
}
}
return max;
}
Then, assuming you're using Java 8+, main can be written using Comparators already available like -
Comparator<String> stringLengthComparator = Comparator.comparingInt(
String::length);
Comparator<String> stringAlphaComparator = Comparator.naturalOrder();
Scanner in = new Scanner(System.in);
System.out.println("Please enter a series of words: ");
String sentence = in.nextLine();
System.out.printf("Longest: %s%n", findWord(stringLengthComparator, sentence));
System.out.printf("Lexically: %s%n", findWord(stringAlphaComparator, sentence));
But, if you're using an earlier version - or you want to better understand what it does, the exact same code will work if you replace the two Comparators with equivalent code - like
Comparator<String> stringLengthComparator = new Comparator<String>() {
public int compare(String a, String b) {
return Integer.compare(a.length(), b.length());
}
};
Comparator<String> stringAlphaComparator = new Comparator<String>() {
public int compare(String a, String b) {
return a.compareTo(b);
}
};
There's a lot of code there, nearly all of which is unnecessary.
Try this:
String longest = Arrays.stream(s.split(" +")).sort(comparing(String::length).reversed()).findFirst().get();
String highest = Arrays.stream(s.split(" +")).sort().reduce((a,b) -> b).get();
Note: Read and understand the code well before you submit your assignment.
Disclaimer: Code may not compile or even work as it was thumbed in on my phone (but there's a reasonable chance it will work)
As your post you can get the longest word. I will show you how to get the highest letter in alphabetical order of the longest word.
There is a method call toCharArray() you can use this method to make letter array of given word.
Than you can use casting to get integer value of the given char value
Then you can compare that integer value to get the highest integer value
Once you have the highest integer value cast that int value to char to take the letter
Following links to more information
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#toCharArray()
http://javaseeeedu.blogspot.com/2015/12/casting-part-1.html
I have change your code try it
import java.util.Scanner;
class MyString{
String s;
MyString( String s1 ){
s=s1;
}
void setString(String s1){
s=s1;
}
String getLongest(String s1){
s1 = s1 +" ";
int length = s1.length();
String temp="", longestw="";
char ltr;
int templ, longest=0;
for(int i=0; i<length;i++){
ltr = s1.charAt(i);
if(ltr!=' ' && ltr!=',' && ltr!='.'){
temp=temp+ltr;
}
else{
templ=temp.length();
if(templ>longest){
longest=templ;
longestw=temp;
}
temp="";
}
}
return longestw;
}
char getLargest(String s1){
int max = 0;
char []arr = s1.toCharArray();
int temp[] = new int[arr.length];
for(int i=0;i<arr.length;i++){
temp[i] = (int)arr[i];
if(i!=0){
if(temp[i-1] < temp[i]){
max = temp[i];
}else{
max = temp[i-1];
}
}
}
return (char)max;
}
}
class Demo {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Please enter a series of words: ");
String s = in.nextLine();
MyString s1 = new MyString(s);
System.out.println("The longest word is: " + s1.getLongest(s));
System.out.println("The largest letter is: " + s1.getLargest(s1.getLongest(s)));
}
}

Print all Digrams and their frequencies in a string

I'm trying to write a program that reads a string of text and prints all digrams in this text and their frequencies. A digram is a sequence of two characters. The program prints digrams sorted based on frequencies (in descending
order).
Example of input: park car at the parking lot
Corresponding output: ar:3 pa:2 rk:2 at:1 ca:1 he:1 in:1 ki:1 lo:1 ng:1 ot:1 th:1
I have this implementation but it only works for every character in the string. How would I implement this for every digram?
import java.util.Scanner;
public class Digrams {
public static void main(String args[]) {
int ci, i, j, k, l=0;
String str, str1;
char c, ch;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a String : ");
str=scan.nextLine();
i=str.length();
for(c='A'; c<='z'; c++)
{
k=0;
for(j=0; j<i; j++)
{
ch = str.charAt(j);
if(ch == c)
{
k++;
}
}
if(k>0)
{
System.out.println("" +c +": " +k);
}
}
}
}
I know you've already got perfect answers and much much better than this, but I was wondering if I can sort the result in descending order without the help of Collections Class, it may be of help, or a new idea.
import java.util.ArrayList;
import java.util.Scanner;
public class Digrams{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Insert The Sentence");
String []sentence = in.nextLine().split(" "); // split the input according to the spaces and put them in array
//get all digrams
ArrayList<String> allDigrams = new ArrayList<String>(); // ArrayList to contain all possible digrams
for(int i=0; i<sentence.length; i++){ // do that for every word
for(int j=0; j<sentence[i].length(); j++){ // cycle through each char at each index in the sentence array
String oneDigram= "";
if(j<sentence[i].length()-1){
oneDigram += sentence[i].charAt(j); // append the char and the following char
oneDigram += sentence[i].charAt(j+1);
allDigrams.add(oneDigram); // add the one diagram to the ArrayList
}
}
}
// isolate digrams and get corresponding frequencies
ArrayList<Integer> frequency = new ArrayList<Integer>(); // for frequencies
ArrayList<String> digrams = new ArrayList<String>(); //for digrams
int freqIndex=0;
while(allDigrams.size()>0){
frequency.add(freqIndex,0);
for(int j=0; j<allDigrams.size(); j++){ // compare each UNIQUE digram with the rest of the digrams to find repetition
if(allDigrams.get(0).equalsIgnoreCase(allDigrams.get(j))){
frequency.set(freqIndex, frequency.get(freqIndex)+1); // increment frequency
}
}
String dig = allDigrams.get(0); // record the digram temporarily
while(allDigrams.contains(dig)){ // now remove all repetition from the allDigrams ArrayList
allDigrams.remove(dig);
}
digrams.add(dig); // add the UNIQUE digram
freqIndex++; // move to next index for the following digram
}
// sort result in descending order
// compare the frequency , if equal -> the first char of digram, if equal -> the second char of digram
// and move frequencies and digrams at every index in each ArrayList accordingly
for (int i = 0 ; i < frequency.size(); i++){
for (int j = 0 ; j < frequency.size() - i - 1; j++){
if (frequency.get(j) < frequency.get(j+1) ||
((frequency.get(j) == frequency.get(j+1)) && (digrams.get(j).charAt(0) > digrams.get(j+1).charAt(0))) ||
((digrams.get(j).charAt(0) == digrams.get(j+1).charAt(0)) && (digrams.get(j).charAt(1) > digrams.get(j+1).charAt(1)))){
int swap = frequency.get(j);
String swapS = digrams.get(j);
frequency.set(j, frequency.get(j+1));
frequency.set(j+1, swap);
digrams.set(j, digrams.get(j+1));
digrams.set(j+1, swapS);
}
}
}
//final result
String sortedResult="";
for(int i=0; i<frequency.size(); i++){
sortedResult+=digrams.get(i) + ":" + frequency.get(i) + " ";
}
System.out.println(sortedResult);
}
}
Input
park car at the parking lot
Output
ar:3 pa:2 rk:2 at:1 ca:1 he:1 in:1 ki:1 lo:1 ng:1 ot:1 th:1
The way to do it is to check for every 2 letter combination, and look for those instead. You can do this by using a double for-loop, like so:
public static void main(String args[]) {
int ci, i, j, k, l=0;
String str, str1, result, subString;
char c1, c2, ch;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a String : ");
str=scan.nextLine();
i=str.length();
for(c1='A'; c1<='z'; c1++)
{
for(c2='A'; c2<='z'; c2++) {
result = new String(new char[]{c1, c2});
k = 0;
for (j = 0; j < i-1; j++) {
subString = str.substring(j, j+2);
if (result.equals(subString)) {
k++;
}
}
if (k > 0) {
System.out.println("" + result + ": " + k);
}
}
}
}
This also means you have to compare Strings, rather than comparing chars. This of course means the .equals() function needs to be used, rather than the == operator, since String is an object in Java.
Result for me was:
ar: 3 at: 1 ca: 1 he: 1 in: 1 ki: 1 lo: 1 ng: 1 ot: 1 pa: 2 rk: 2 th: 1
Here's how you do it in one line:
Map<String, Long> digramFrequencies = Arrays
.stream(str
.replaceAll("(?<!^| ).(?! |$)", "$0$0") // double letters
.split(" |(?<=\\G..)")) // split into digrams
.filter(s -> s.length() > 1) // discard short terms
.collect(Collectors.groupingBy(s -> s, Collectors.counting()));
See live demo.
This works by:
doubling all letters not at start/end of words, eg "abc defg" becomes "abbc deeffg"
splitting into pairs, re-starting splits at start of word
discarding short terms (eg words like "I" and "a")
counting frequencies
This should help:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter a String : ");
String str = scan.nextLine();
ArrayList<String> repetition = new ArrayList<String>();
ArrayList<String> digrams = new ArrayList<String>();
String digram;
for(int i = 0; i < str.length() - 1; i++) {
digram = str.substring(i, i + 2);
if(repetition.contains(digram) || digram.contains(" ") || digram.length() < 2)
continue;
int occurances = (str.length() - str.replace(digram, "").length()) / 2;
occurances += (str.replaceFirst(".*?(" + digram.charAt(0) + "+).*", "$1").length() - 1) / 2;
digrams.add(digram + ":" + occurances);
repetition.add(digram);
}
Collections.sort(digrams, (s1, s2) -> s1.substring(3, 4).compareTo(s2.substring(3, 4)));
System.out.println(digrams);
}
If you don't want to use jdk8 then let me know.

How do I count the number of occurrences of a char in a Multiple String?

My question is so special ,
giving those Strings
123456
String1 ABCD
String2 BDD
String3 CDEF
As we can see
the number of A in column 1 is 1.
the number of B in column 2 is 2.
the number of C in column 3 is 2.
the number of D in column 3 is 1.
the number of D in column 4 is 3.
the number of E in column 5 is 1.
the number of F in column 6 is 1.
the purpose of those calculs is to get the char that appear the most in each Column.
what is the best DataStructure i can use to handle this issue? knowing that i know the lenght of each String only at the Execution time.
the information i know already is the n° of column where each String begin.
the idea i have and i think it's not the best is iterating over the column n° and couting how much each char appear and finally finding that most occurred char.
Do you have some better solution?
info: My string could contain only those char[A,B,C,D,E,F]
Thank you.
Go through this sample code which you can insert Strings as list so there won't be any restrictions on number of String in the code but correct output will be given. I have added inline comments where it's required.
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class StringOperation {
public static void main(String[] args) {
List<String> stringList=new ArrayList<String>();
stringList.add("ABCD");
stringList.add(" BDD");
stringList.add(" CDEF");
stringList.add("ABCD");
char[][] array=getTwoDimentionArray(stringList);
for (int i = 0; i < array.length; i++) {
char[] cs = array[i];
numberOfCharactorsinString(cs, i);
}
}
//This method will create two dimension array from String list same time it will convert columns in to rows
public static char[][] getTwoDimentionArray(List<String> list){
char[][] twoDimenArray=null;
int maxLength=0;
for (String strings : list) {
if(maxLength<strings.length()){
maxLength=strings.length();
}
}
twoDimenArray=new char[maxLength][list.size()];
for (int i = 0; i < list.size(); i++) {
char[] charArray=list.get(i).toCharArray();
for (int j = 0; j < charArray.length; j++) {
twoDimenArray[j][i] = charArray[j];
}
}
return twoDimenArray;
}
//This method will return the char occurrences in the given char array
public static void numberOfCharactorsinString(char[] charArray,int count){
//Here we use set to identify unique chars in the char array
Set<Character> uniqueSet=new HashSet<Character>();
int forcount=0;
for (Character charVar : charArray) {
int occurent=1;
//check whether the searching char is not empty and not a space and not in previously counted
if( charVar!=Character.MIN_VALUE && charVar!=' ' && !uniqueSet.contains(charVar) && forcount<charArray.length){
uniqueSet.add(charVar);
for (int x=forcount+1;x<charArray.length;x++ ) {
if(charArray[x]==charVar){
occurent++;
}
}
System.out.println("The number of "+charVar+" in column "+(count+1)+" is "+occurent+".");
}
forcount++;
}
}
}
If you provide input as (Note that I have added additional input in here in 4th line)
String1 ABCD
String2 BDD
String3 CDEF
String1 ABCD
The out put will be as bellow
The number of A in column 1 is 2.
The number of B in column 2 is 3.
The number of C in column 3 is 3.
The number of D in column 3 is 1.
The number of D in column 4 is 4.
The number of E in column 5 is 1.
The number of F in column 6 is 1.
public class Main {
public static void main(String[] args) {
String str1 = "ABCD ";
String str2 = " BDD ";
String str3 = " CDEF";
String[] reversed = getReversed(str1, str2, str3); // reverse rows with columns
for(int i=0; i< reversed.length; i++){
String trimedString = reversed[i].trim(); // removes spaces that around the string
System.out.println(findMaxOccurrenceCharValue(trimedString)); // counts the maximum occurrence char
}
}
private static String[] getReversed(String str1, String str2, String str3){
char[] s1 = str1.toCharArray();
char[] s2 = str2.toCharArray();
char[] s3 = str3.toCharArray();
String[] newStr = new String[6];
for(int i =0; i<6; i++){
newStr[i] = "" + s1[i] + s2[i] + s3[i];
}
return newStr;
}
private static String findMaxOccurrenceCharValue(String str) {
char[] array = str.toCharArray();
int[] count = new int[1000];
for(char c: array){
count[c]++;
}
// find the max occurrence character and number of occurrence
String maxCharacter = "";
int maxValue = -1;
for(int i=0;i< array.length;i++){
if(count[array[i]] > maxValue){
maxValue = count[array[i]];
maxCharacter = String.valueOf(array[i]);
}
}
return maxCharacter + "=" + maxValue;
}
}
Output:
A=1
B=2
C=2
D=3
E=1
F=1

Java Given 2 Strings write a method to decide if one is a permutation of the other

That is a question from Cracking the coding interview.Below is my code:
class PalinDrome {
public static Scanner userinput = new Scanner(System.in);
public static void main(String [] args){
//1st input from user
System.out.println("Enter 1st string: ");
String s1= userinput.next().toLowerCase();
// convert 1st string to char Array
char [] charS1= s1.toCharArray();
System.out.println(charS1);
//2nd input from user
System.out.println("Enter 2nd string: ");
String s2= userinput.next().toLowerCase();
// convert 2nd string to char Array
char [] charS2= s2.toCharArray();
System.out.println(charS2);
if(s1.length()==s2.length() && s1.toCharArray()==s2.toCharArray()){
System.out.println(" Word 2 is Perm of 1st word");
}
else{
System.out.println(" Word 2 is not Perm of 1st word");
}
}
}
Question: When I use Tom(1st) and 2nd Mot/moT (tried different variations), I always get Not perm of 1st word. There are answers in the book, I want to know whats wrong with this logic. Thank in advance.
As mentioned in the comment s1.toCharArray()==s2.toCharArray() is wrong because you are not really comparing values in the array just the references of those 2 newly created arrays.
You should sort those arrays Arrays.sort
And then use Arrays.equals to compare those arrays.
Here is a solution using wether collections nor sorting. ^^
Idea is to mark entries in both Strings/char arrays that are the same character until everything is marked. (after checking the strings for same length)
package PermuteString;
public class Permutation {
public static void main(String[] args) {
String a = "yalla";
String b = "allay";
String c = "allas";
Permutation permutation = new Permutation();
if (permutation.isPermutationWithoutCollection(a, b))
System.out.println(a + " is permutation of " + b);
if (!permutation.isPermutationWithoutCollection(a, c))
System.out.println(a + " is not a permutation of " + c);
}
public boolean isPermutationWithoutCollection(String string1, String string2) {
if (string1.length() != string2.length()) {
return false;
}
char[] a = string1.toLowerCase().toCharArray();
char[] b = string2.toLowerCase().toCharArray();
for (int i = 0; i < a.length; i++) {
boolean unChanged = true;
for (int k = 0; k < b.length; k++) {
if (a[i] == b[k]) {
a[i] = 'A';
b[k] = 'B';
unChanged = false;
break;
}
}
if (unChanged) {
//System.out.println("wawawa");
return false;
}
}
return true;
}
}
Yields:
yalla is permutation of allay
yalla is not a permutation of allas
Really depends on what topic the interview is based (based on using java / based on algorithm).

Count Duplicate letters

I want to get a string count any letter in the string how many time it's appeared in the string,and print the letter and the number So that what i did:
import java.util.Scanner;
public class test1 {
public static void main(String[] args) {
String str;
Scanner in = new Scanner(System.in);
System.out.println("enter name");
str = in.nextLine();
char[] c1 = str.toCharArray();
int[] f = new int[str.length()];
for(int i=0;i<str.length();i++) {
for(int j=0;j<str.length();j++) {
if(c1[i]==c1[j]) {
f[i]++;
}
}
}
for(int k=0;k<c1.length;k++) {
for(int l=0;l<c1.length;l++) {
if(c1[k]==c1[l]) {
if(l!=k) {c1[k]=0;f[k]=0;}
}
}
System.out.println(c1[k]+"="+f[k]);
}
}
}
There are two problems:
1. when i print it's printing the duplicated letter twice(or thrice or more depends how many times the letter is in the string).
so i added the another 2 loops(k and l) that deletes the duplicated letters,but now instead of the duplicated letter it's print me: an square and a zero,how i can just get delete the letter and the number from the char and int array's?(for example when i insters the name "elichai" i get:
e=1
l=1
(an square)=0
c=1
h=1
a=1
i=2
2.The letter it deletes is the second letter not the first
(in "elichai" example it's deleted the first 'i' instead of the second 'i')
Thanks!
Different approach to solve your problem, but this is how I would probably do it:
String input = "Whatever";
Map<Character, Integer> charCounter = new LinkedHashMap<>(); // respects insertion order
for (char c : input.replaceAll("\\s+", "").toCharArray()) { // ignore spaces
Integer count = charCounter.get(c);
count = count == null ? 0 : count;
charCounter.put(c, count + 1);
}
System.out.println(charCounter);
class Twice_Occuring
{
void main(String s)
{
int count=0;
for(int i=0;i<s.length();i++)
{
char c=s.charAt(i);
int ind1=s.indexOf(c,i);
int ind2=s.indexOf(c,i+1);
if(ind2-ind1==1)
{System.out.print(c+" ");count++;}
}
System.out.println("\n Number of counts = "+count);
}
}

Categories

Resources