Java Alphabetizer - java

I'm trying to make a program in which I ask the user to input words, and then the program puts them in Alphabetical Order. Here's what I've got so far:
import java.util.Scanner;
public class WordAlphabeticalizer {
/**
* #param args
*/
public static void main(String[] args) {
// Variables and Objects
String arraylength;
Scanner input = new Scanner (System.in);
// Code
System.out.println("Please input how many terms you would like to alphabetize"):
arraylength = input.nextLine();
String[] words = new String[Integer.parseInt(arraylength)];
for(int index = 0; index < words.length; index ++){
System.out.println("Please input word number " + (index + 1) + ":");
words[index] = input.nextLine();
}
}
}
I would like to know how to go about comparing the first letters of each word in the array, and what logic I would use to keep going to compare the word to the first two, three, or how many ever spaces it needs to go in order to get which word goes first, and then the word that goes after it. Any ideas?

java.lang.String implements the java.lang.Comparable interface so you can sort them by adding them to a sorted collection (Try java.util.TreeSet)
Set<String> stringsToSort = new TreeSet<String>();
stringsToSort.add("Fish");
stringsToSort.add("Dog");
stringsToSort.add("Cat");
System.out.println(stringsToSort);

Though it's a bit verbose, this is a method I've used to alphabetise Strings:
public static String[] alphabetise(final String[] array)
{
Arrays.sort(array, new Comparator<String>()
{
#Override
public int compare(final String o1, final String o2)
{
if(o1 == null && o2 == null)
{
return 0;
}
else if(o1 == null)
{
return -1;
}
else if(o2 == null)
{
return 1;
}
else if(o1.equals(o2))
{
return 0;
}
else if(o1.isEmpty())
{
return -1;
}
else if(o2.isEmpty())
{
return 1;
}
final Character[] c1 = toCharacterArray(o1.toLowerCase());
final Character[] c2 = toCharacterArray(o2.toLowerCase());
final int max = Math.max(c1.length, c2.length);
for(int i = 0; i < max; i++)
{
if(i < c1.length && i < c2.length)
{
final int comp = c1[i].compareTo(c2[i]);
if(comp != 0)
{
return comp;
}
}
else return new Integer(c1.length).compareTo(new Integer(c2.length));
}
return 0;
}
});
return array;
}
static Character[] toCharacterArray(final String str)
{
if(str == null || str.isEmpty()) return new Character[0];
final Character[] array = new Character[str.length()];
int counter = 0;
for(final char c : str.toCharArray())
{
array[counter++] = c;
}
return array;
}
This will conform to proper alphabetical order, ignoring capitals and favouring shorter words over longer (e.g. "House" before "Houses").

Related

Check to see if all words in an ArrayList are in a string array and in order?

I'm trying to iterate through an ArrayList and make sure that each element of the ArrayList shows up in order in a String array.
This my code so far:
int x = 0;
int y = 0;
int keywordLocationInPhrase = -1;
int nextKeywordLocationInPhrase = -1;
do {
if (keywords.get(x).equals(phrase[y])) {
keywordLocationInPhrase = y;
} else {
y++;
continue;
}
x++;
} while (keywordLocationInPhrase == -1);
I get stuck here because I don't know how to get the nextKeyWordLocationInPhrase's position.
All help is appreciated!
EDIT:
Example:
If the keywords list is:
[dog, cat]
And the array of Strings to match is:
[cat, toy, rat, dog]
This would be incorrect as even though the keywords are in the array of Strings, they do not show up in order.
It would be valid in the following case:
If the keywords list is:
[dog, cat]
And the array of Strings to match is:
[dog, toy, rat, cat]
The following maybe an easier solution:
int keyWordIndex = 0; //moves only when needed
boolean allMatch = true;
for(String word : phrase){
if(keywords.contains(word)){
allMatch &= (word.equals(keyword.get(keyWordIndex++));
}
}
//if allMatch is true at this point the order is respected.
What you want to do is loop through all phrase and check for keyword;
int y = 0;
for(int i = 0; i < phrase.lenght; i++){
if((y < keyword.size()) && phrase[i].equals(keyword.get(y)){
y++;
}
}
return y==keyword.size();
This returns true in your valid cases and false in invalid cases.
Here is my crack at the solution. I use maps for better performance when scanning the words array. Let me know if you have any questions.
public static void main(String[] args) {
List<String> values = new ArrayList<>();
values.add("dog");
values.add("cat");
values.add("sam");
String[] words = new String[5];
words[0] = "dog";
words[1] = "toy";
words[2] = "rat";
words[3] = "cat";
words[4] = "sam";
System.out.println(wordsMatch(values, words));
}
public static boolean wordsMatch(List<String> keywords, String[] words) {
int[] foundIndexes = new int[words.length];
int foundIdx = 0;
//convert our words array to a map for a faster lookup and we have the index
Map<String, Integer> wrdMap = getIndexMapFromWords(words);
// we have more values then words we know all our values is not in the list of words
// so return false
if (keywords.size() > words.length) {
return false;
}
for (String kw : keywords) {
Integer idx = wrdMap.get(kw);
if (idx == null) { // we don't have the word, false
return false;
}
if (foundIdx == 0) {
foundIndexes[foundIdx++] = idx;
} else {
int prevIdx = foundIndexes[foundIdx - 1];
if (prevIdx > idx) { // not in order false
return false;
} else { // add new idx
foundIndexes[foundIdx++] = idx;
}
}
}
return true;
}
public static Map<String, Integer> getIndexMapFromWords(String[] convertWords) {
Map<String, Integer> indexMap = new HashMap<>();
int idx = 0;
for (String wrd : convertWords) {
indexMap.put(wrd, idx++);
}
return indexMap;
}
I tried to keep your coding style and thinking instead of you then I refactored your codes:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args){
int x = 0;
int y = 0;
List<String> keywords = new ArrayList<>();
keywords.add("cat");
keywords.add("dog");
String[] phrase = {"cat", "toy", "rat", "dog"};
do {
if(x == keywords.size()) {
System.out.println("success");
return;
}
if(y == phrase.length - 1 && (x < keywords.size() - 1 || !keywords.get(x).equals(phrase[y]))) {
System.out.println("failed");
return;
}
if (keywords.get(x).equals(phrase[y])) {
x++;
} else {
y++;
}
} while (true);
}
}

How can I set a list of strings that were generated from a loop, into an array?

public static String[] findWordsOfLength(String letters, int wordSize) {
letters = "fourgooddogsswam";
for(int i = 0; i < letters.length()-3;i++){
String fourLetter = letters.substring(i,i+4);
}
for(int i = 0; i < letters.length()-4;i++){
String fiveLetter = letters.substring(i,i+5);
}
return ?;
}
I was wondering if I could somehow set the list of strings generated from this loop, into a string array? Is there a way I could return that value if I used multiple loops for different strings?
Here´s an answer not involving a List.
Based on the input you can precalculate the output length of your array and initialize it with the given size. Than you´d just be looping over the array size and use mathematics again to substring from the input.
public static void main(String[] args){
String[] words = findWordsOfLength("fourgooddogsswam", 4);
print(words);
}
public static String[] findWordsOfLength(String letters, int wordSize) {
// your working and output array definition
String[] words;
// If not even dividable add one to the size
if (letters.length() % wordSize == 0) {
words = new String[letters.length() / wordSize];
} else {
words = new String[letters.length() / wordSize + 1];
}
for(int i = 0; i < words.length;i++){
// To not run into IndexOutOfBound check if we´d be going out of bound
if(i*wordSize + wordSize > letters.length()) {
words[i] = letters.substring(i*wordSize);
} else {
words[i] = letters.substring(i*wordSize, i*wordSize+wordSize);
}
}
return words;
}
// Just prints
public static void print(String[] input) {
for(String string : input) {
System.out.println(string);
}
}
O/P:
four
good
dogs
swam
As Scary Wombat suggested in the comments, in the beginning of the method, you can create an ArrayList. Then within in each loop iteration, you can just keep adding to it. At the end of the method, you can convert the list to an array using the toArray method.
import java.util.ArrayList;
import java.util.List;
class Example {
public static String[] findWordsOfLength(String letters, int wordSize) {
if(letters == null) {
return null;
}
int size = letters.length();
int wordMax = size - wordSize + 1;
if(size < wordMax || wordMax <= 0) {
return new String[0];
}
List<String> result = new ArrayList<>();
for (int i = 0; i < wordMax; i++) {
result.add(letters.substring(i, i + wordSize));
}
return result.toArray(new String[0]);
}
public static void main(String[] args) {
String[] word = findWordsOfLength("fourgooddogsswam", 4);
for(String word : words) {
System.out.println(word);
}
/**
* Output in console:
*
* four
* ourg
* urgo
* rgoo
* good
* oodd
* oddo
* ddog
* dogs
* ogss
* gssw
* sswa
* swam
*/
}
}
Note that the advantage of using a list is that you don't need to know its size in advance. An array, on other hand, is initialized with a set size.
If you must use an array, you could do:
public static String[] findWordsOfLength(String letters, int wordSize) {
if(letters == null) {
return null;
}
int size = letters.length();
int wordMax = size - wordSize + 1;
if(size < wordMax || wordMax <= 0) {
return new String[0];
}
int j = 0;
String[] result = new String[wordMax];
for (int i = 0; i < wordMax; i++) {
result[j ++] = letters.substring(i, i + wordSize);
}
return result;
}

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

How can I sort a string array in ascending order, by number of vowels in each string?

import java.util.*;
class VowelAsc
{
public static void main(String args[])
{
int count=0;
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
String [] s=new String[n];
int [] b=new int[40];
for(int i=0;i<n;i++)
{
s[i]=sc.next();
}
for(int i=0;i<s.length;i++)
{
char[] a=s[i].toCharArray();
for(int c=0;c<a.length;c++)
{
if(a[c]=='a' || a[c]=='e' || a[c]=='i' || a[c]=='o' || a[c]=='u' ||a[c]=='A' ||a[c]=='E' || a[c]=='I' || a[c]=='O' || a[c]=='U')
{
count++;
//b[c]=count;
}
}
if(count>0)
{
if(i<s.length)
{
String t=s[i];
s[i]=s[i+1];
s[i+1]=t;
}
}
}
}
}
I am trying to count the vowels present in each string and i wanted to swap the strings based on count variable which i am unable to do.
After accepting the strings i am converting it into char array with toCharArray() function and comparing each character with lower and upper case vowels.
I am getting an error. Any help in writing the part of the code would be appreciated.
Input:
n=4
xyz
bad
aeiou
hello
Output:
aeiou
hello
bad
xyz
Well... this might be slightly over the top (List and RegEx), but if you don't have to execute this millions of times, then sorting them in a list via a custom Comparator will do the job:
String[] s = new String[]{"xyz", "bad", "aeiou", "hello"};
Arrays.sort(s, new Comparator<String>(){
#Override
public int compare(String o1, String o2) {
return o2.replaceAll("[^aeiouAEIOU]", "").length()
- o1.replaceAll("[^aeiouAEIOU]", "").length();
}
});
EDIT: Optimized by removing the List, thanks #Holger
Similar to mumpitz code, but optimized for performance:
class Comp implements Comparator<String> {
private static boolean[] isVowel = new boolean[127];
static {
isVowel['a'] = true;
isVowel['e'] = true;
isVowel['i'] = true;
isVowel['o'] = true;
isVowel['u'] = true;
}
#Override
public int compare(String o1, String o2) {
return count(o1) - count(o2);
}
private int count(String s) {
int cnt = 0;
for (int i=0; i<s.length(); i++) {
char c = s.charAt(i);
if (c < 128 && isVowel(c))
cnt++;
}
}
return cnt;
}
}
String[] s = new String[]{"xyz", "bad", "aeiou", "hello"};
List<String> sList = Arrays.asList(s);
Collections.sort(sList, new Comp());
s = sList.toArray(s);

Checking if two strings are permutations of each other

How to determine if two strings are permutations of each other
Sort the two strings's characters.
Compare the results to see if they're identical.
Edit:
The above method is reasonably efficient - O(n*log(n)) and, as others have shown, very easy to implement using the standard Java API. Even more efficient (but also more work) would be counting and comparing the occurrence of each character, using the char value as index into an array of counts.
I do not thing there is an efficient way to do it recursively. An inefficient way (O(n^2), worse if implemented straightforwardly) is this:
If both strings consist of one identical character, return true
Otherwise:
remove one character from the first string
Look through second string for occurrence of this character
If not present, return false
Otherwise, remove said character and apply algorithm recursively to the remainders of both strings.
To put #Michael Borgwardt's words in to code:
public boolean checkAnagram(String str1, String str2) {
if (str1.length() != str2.length())
return false;
char[] a = str1.toCharArray();
char[] b = str2.toCharArray();
Arrays.sort(a);
Arrays.sort(b);
return Arrays.equals(a, b);
}
Create a Hashmap with the characters of the first string as keys and the number of occurances as value; then go through the second string and for each character, look up the hash table and decrement the number if it is greater than zero. If you don't find an entry or if it is already 0, the strings are not a permutation of each other. Obviously, the string must have the same length.
Linear Time solution in HashMap. Traverse and put first String in HashMap, keep the count of each character. Traverse second String and if it is already in the hashmap decrease the count by 1. At the end if all character were in the string the value in hashmap will be 0 for each character.
public class StringPermutationofEachOther {
public static void main(String[] args)
{
String s1= "abc";
String s2 ="bbb";
System.out.println(perm(s1,s2));
}
public static boolean perm(String s1, String s2)
{ HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int count =1;
if(s1.length()!=s2.length())
{
return false;
}
for(Character c: s1.toCharArray())
{
if(!map.containsKey(c))
map.put(c, count);
else
map.put(c, count+1);
}
for(Character c: s2.toCharArray())
{
if(!map.containsKey(c))
return false;
else
map.put(c, count-1);
}
for(Character c: map.keySet())
{
if(map.get(c)!=0)
return false;
}
return true;
}
}
You can try to use XOR, if one string is a permeation of the other, they should have essentially identical chars. The only difference is just the order of chars. Therefore using XOR trick can help you get rid of the order and focus only on the chars.
public static boolean isPermutation(String s1, String s2){
if (s1.length() != s2.length()) return false;
int checker = 0;
for(int i = 0; i < s1.length();i++ ){
checker ^= s1.charAt(i) ^ s2.charAt(i);
}
return checker == 0;
}
Sort the 2 strings by characters and compare if they're the same (O(n log n) time, O(n) space), or
Tally the character frequency of the 2 strings and compare if they're the same (O(n) time, O(n) space).
You might take a look at String.toCharArray and Arrays.sort
First you check the lengths (n), if they are not same, they cannot be permutations of each other. Now create two HashMap<Character, Integer>. Iterate over each string and put the number of times each character occur in the string. E.g. if the string is aaaaa, the map will have just one element with key a and value 5. Now check if the two maps are identical. This is an O(n) algorithm.
EDIT with code snippet :
boolean checkPermutation(String str1, String str2) {
char[] chars1 = str1.toCharArray();
char[] chars2 = str2.toCharArray();
Map<Character, Integer> map1 = new HashMap<Character, Integer>();
Map<Character, Integer> map2 = new HashMap<Character, Integer>();
for (char c : chars1) {
int occ = 1;
if (map1.containsKey(c) {
occ = map1.get(c);
occ++;
}
map1.put(c, occ);
}
// now do the same for chars2 and map2
if (map1.size() != map2.size()) {
return false;
}
for (char c : map1.keySet()) {
if (!map2.containsKey(c) || map1.get(c) != map2.get(c)) {
return false;
}
}
return true;
}
I'm working on a Java library that should simplify your task. You can re-implement this algorithm using only two method calls:
boolean arePermutationsOfSameString(String s1, String s2) {
s1 = $(s1).sort().join();
s2 = $(s2).sort().join();
return s1.equals(s2);
}
testcase
#Test
public void stringPermutationCheck() {
// true cases
assertThat(arePermutationsOfSameString("abc", "acb"), is(true));
assertThat(arePermutationsOfSameString("bac", "bca"), is(true));
assertThat(arePermutationsOfSameString("cab", "cba"), is(true));
// false cases
assertThat(arePermutationsOfSameString("cab", "acba"), is(false));
assertThat(arePermutationsOfSameString("cab", "acbb"), is(false));
// corner cases
assertThat(arePermutationsOfSameString("", ""), is(true));
assertThat(arePermutationsOfSameString("", null), is(true));
assertThat(arePermutationsOfSameString(null, ""), is(true));
assertThat(arePermutationsOfSameString(null, null), is(true));
}
PS
In the case you can clone the souces at bitbucket.
I did this, and it works well and quickly:
public static boolean isPermutation(String str1, String str2)
{
char[] x = str1.toCharArray();
char[] y = str2.toCharArray();
Arrays.sort(x);
Arrays.sort(y);
if(Arrays.equals(x, y))
return true;
return false;
}
public boolean isPermutationOfOther(String str, String other){
if(str == null || other == null)
return false;
if(str.length() != other.length())
return false;
Map<Character, Integer> characterCount = new HashMap<Character, Integer>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
int count = 1;
if(characterCount.containsKey(c)){
int k = characterCount.get(c);
count = count+k;
}
characterCount.put(c, count);
}
for (int i = 0; i < other.length(); i++) {
char c = other.charAt(i);
if(!characterCount.containsKey(c)){
return false;
}
int count = characterCount.get(c);
if(count == 1){
characterCount.remove(c);
}else{
characterCount.put(c, --count);
}
}
return characterCount.isEmpty();
}
Variation on other approaches but this one uses 2 int arrays to track the chars, no sorting, and you only need to do 1 for loop over the strings. The for loop I do over the int arrays to test the permutation is a constant, hence not part of N.
Memory is constant.
O(N) run time.
// run time N, no sorting, assume 256 ASCII char set
public static boolean isPermutation(String v1, String v2) {
int length1 = v1.length();
int length2 = v2.length();
if (length1 != length2)
return false;
int s1[] = new int[256];
int s2[] = new int[256];
for (int i = 0; i < length1; ++i) {
int charValue1 = v1.charAt(i);
int charValue2 = v2.charAt(i);
++s1[charValue1];
++s2[charValue2];
}
for (int i = 0; i < s1.length; ++i) {
if (s1[i] != s2[i])
return false;
}
return true;
}
}
Unit Tests
#Test
public void testIsPermutation_Not() {
assertFalse(Question3.isPermutation("abc", "bbb"));
}
#Test
public void testIsPermutation_Yes() {
assertTrue(Question3.isPermutation("abc", "cba"));
assertTrue(Question3.isPermutation("abcabcabcabc", "cbacbacbacba"));
}
If we do the initial length check, to determine if the two strings are of the same length or not,
public boolean checkIfPermutation(String str1, String str2) {
if(str1.length()!=str2.length()){
return false;
}
int str1_sum = getSumOfChars(str1);
int str2_sum = getSumOfChars(str2);
if (str1_sum == str2_sum) {
return true;
}
return false;
}
public int getSumOfChars(String str){
int sum = 0;
for (int i = 0; i < str.length(); i++) {
sum += str.charAt(i);
}
return sum;
}
The obligatory Guava one-liner:
boolean isAnagram(String s1, String s2) {
return ImmutableMultiset.copyOf(Chars.asList(s1.toCharArray())).equals(ImmutableMultiset.copyOf(Chars.asList(s2.toCharArray())));
}
(Just for fun. I don't recommend submitting this for your assignment.)
As you requested, here's a complete solution using recursion.
Now all you have to do is:
Figure out what language this is
Translate it to Java.
Good luck :-)
proc isAnagram(s1, s2);
return {s1, s2} = {''} or
(s2 /= '' and
(exists c = s1(i) |
s2(1) = c and
isAnagram(s1(1..i-1) + s1(i+1..), s2(2..))));
end isAnagram;
I did it using C#
bool Arepermutations(string string1, string string2)
{
char[] str1 = string1.ToCharArray();
char[] str2 = string2.ToCharArray();
if (str1.Length !=str2.Length)
return false;
Array.Sort(str1);
Array.Sort(str2);
if (str1.Where((t, i) => t!= str2[i]).Any())
{
return false;
}
return true;
}
public boolean permitation(String s,String t){
if(s.length() != t.length()){
return false;
}
int[] letters = new int[256];//Assumes that the character set is ASCII
char[] s_array = s.toCharArray();
for(char c:s_array){ /////count number of each char in s
letters[c]++;
}
for(int i=0;i<t.length();i++){
int c = (int)t.charAt(i);
if(--letters[c]<0){
return false;
}
}
return true;
}
import java.io.*;
public class permute
{
public static String sort(String s)
{
char[] str = s.toCharArray();
java.util.Arrays.sort(str);
return new String(str);
}
public static boolean permutation(String s,String t)
{
if(s.length()!=t.length())
{
return false;
}
return sort(s).equals(sort(t));
}
public static void main(String[] args) throws IOException
{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String string = null;
boolean x=true;
System.out.println("Input String:");
string = bf.readLine();
System.out.println("Input another String:");
String result = bf.readLine();
String resultant = sort(string);
if(x==permutation(result,resultant))
{
System.out.println("String"+" "+"("+result+")"+"is a permutation of String"+" "+"("+string+")");
}
else
{
System.out.println("Sorry No anagram found");
}
}
}
public class TwoStrgPermutation {
public int checkForUnique(String s1, String s2)
{
int[] array1 = new int[256];
int[] array2 = new int[256];
array1 = arrayStringCounter(array1,s1);
array2 = arrayStringCounter(array2,s2);
if(Arrays.equals(array1, array2))
return 0;
else
return 1;
}
public int[] arrayStringCounter(int[] array,String s)
{
int val;
for(int i=0;i<s.length();i++)
{
val = (int)s.charAt(i);
array[val]++;
}
return array;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
InputStreamReader in = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(in);
TwoStrgPermutation obj = new TwoStrgPermutation();
try {
String string1 = br.readLine();
String string2 = br.readLine();
int len1 = string1.length();
int len2 = string2.length();
if(len1==len2)
{
int result = obj.checkForUnique(string1,string2);
if (result == 0){
System.out.println("yes it is a permutation");
}
else if (result >0)
{
System.out.println("no it is not");
}
}
else
{
System.out.println("no it is not");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
>>>def isPermutation = lambda x, y: set([i for i in x]) == set([j for j in x])
>>>isPermutation("rasp", "spar")
>>>True
This is an O(N) solution, in which N is the length of the shorter string.
It has a disadvantage, which is that only ASCII characters are acceptable.
If we want better applicability, we may substitute a hash table for the int charNums[].
But it also means C wouldn't be a good choice, coz' there is no standard hash table implementation for C.
int is_permutation(char *s1, char *s2)
{
if ((NULL == s1) ||
(NULL == s2)) {
return false;
}
int static const
_capacity = 256; // Assumption
int
charNums[_capacity] = {0};
char
*cRef1 = s1,
*cRef2 = s2;
while ('\0' != *cRef1 && '\0' != *cRef2) {
charNums[*cRef1] += 1;
charNums[*cRef2] -= 1;
cRef1++;
cRef2++;
}
if ('\0' != *cRef1 || '\0' != *cRef2) {
return false;
}
for (int i = 0; i < _capacity; i++) {
if (0 != charNums[i]) {
return false;
}
}
return true;
}
Create two methods:
1. First method takes a string and returns a sorted string:
public String sort(String str) {
char char_set[] = str.toCharArray();
Arrays.sort(char_set);
return new String(char_set);
}
2. Second method takes two strings and return a boolean:
`public boolean sort(String x, String y) {
if (x.length() != y.length()) {
System.out.println("false");
return false;
}
System.out.println(sort(x).equals(sort(y)));
return sort(x).equals(sort(y));
}`
It can be done by using a Dictionary in C#. A basic implementation is like :
private static bool IsPermutation(string str1, string str2)
{
if (str1.Length != str2.Length)
return false;
var dictionary = new Dictionary<char, int>();
foreach(var x in str1)
{
if (dictionary.ContainsKey(x))
dictionary[x] += 1;
else
dictionary.Add(x, 1);
}
foreach (var y in str2)
{
if (dictionary.ContainsKey(y))
{
if (dictionary[y] > 0)
dictionary[y] -= 1;
else
return false;
}
else
return false;
}
foreach(var el in dictionary)
{
if (el.Value != 0)
return false;
}
return true;
}
Time Complexity is O(n), linear solution.
public static boolean isPermutation(String s1, String s2) {
if (s1.length() != s2.length()) {
return false;
}else if(s1.length()==0 ){
return true;
}
else if(s1.length()==1){
return s1.equals(s2);
}
char[] s = s1.toCharArray();
char[] t = s2.toCharArray();
for (int i = 0; i < s.length; i++) {
for (int j = 0; j < t.length; j++) {
if (s.length == s1.length() && (i == 0 && j == t.length - 1) && s[i] != t[j]) {
return false;
}
if (s[i] == t[j]) {
String ss = new String(s);
String tt = new String(t);
s = (ss.substring(0, i) + ss.substring(i + 1, s.length)).toCharArray();
t = (tt.substring(0, j) + tt.substring(j + 1, t.length)).toCharArray();
System.out.println(new String(s));
System.out.println(new String(t));
i = 0;
j = 0;
}
}
}
return s[0]==t[0] ;
}
This solution works for any charset. With an O(n) complexity.
The output for: isPermutation("The Big Bang Theory", "B B T Tehgiangyroeh")
he Big Bang Theory
B B Tehgiangyroeh
e Big Bang Theory
B B Tegiangyroeh
Big Bang Theory
B B Tgiangyroeh
Big Bang Theory
BB Tgiangyroeh
ig Bang Theory
B Tgiangyroeh
g Bang Theory
B Tgangyroeh
Bang Theory
B Tangyroeh
Bang Theory
B Tangyroeh
Bng Theory
B Tngyroeh
Bg Theory
B Tgyroeh
B Theory
B Tyroeh
BTheory
BTyroeh
Bheory
Byroeh
Beory
Byroe
Bory
Byro
Bry
Byr
By
By
B
B
true
Best Way to do this is by sorting the two strings first and then compare them. It's not the most efficient way but it's clean and is bound to the runtime of the sorting routine been used.
boolean arePermutation(String s1, String s2) {
if(s1.lenght() != s2.lenght()) {
return false;
}
return mySort(s1).equals(mySort(s2));
}
String mySort(String s) {
Char letters[] = s.toCharArray();
Arrays.sort(letters);
return new String(letters);
}
String str= "abcd";
String str1 ="dcazb";
int count=0;
char s[]= str.toCharArray();
char s1[]= str1.toCharArray();
for(char c:s)
{
count = count+(int)c ;
}
for(char c1:s1)
{
count=count-(int)c1;
}
if(count==0)
System.out.println("String are Anagram");
else
System.out.println("String are not Anagram");
}
Here is a simple program I wrote that gives the answer in O(n) for time complexity and O(1) for space complexity. It works by mapping every character to a prime number and then multiplying together all of the characters in the string's prime mappings together. If the two strings are permutations then they should have the same unique characters each with the same number of occurrences.
Here is some sample code that accomplishes this:
// maps keys to a corresponding unique prime
static Map<Integer, Integer> primes = generatePrimes(255); // use 255 for
// ASCII or the
// number of
// possible
// characters
public static boolean permutations(String s1, String s2) {
// both strings must be same length
if (s1.length() != s2.length())
return false;
// the corresponding primes for every char in both strings are multiplied together
int s1Product = 1;
int s2Product = 1;
for (char c : s1.toCharArray())
s1Product *= primes.get((int) c);
for (char c : s2.toCharArray())
s2Product *= primes.get((int) c);
return s1Product == s2Product;
}
private static Map<Integer, Integer> generatePrimes(int n) {
Map<Integer, Integer> primes = new HashMap<Integer, Integer>();
primes.put(0, 2);
for (int i = 2; primes.size() < n; i++) {
boolean divisible = false;
for (int v : primes.values()) {
if (i % v == 0) {
divisible = true;
break;
}
}
if (!divisible) {
primes.put(primes.size(), i);
System.out.println(i + " ");
}
}
return primes;
}
Based on the comment on this solution, https://stackoverflow.com/a/31709645/697935 here's that approach, revised.
private static boolean is_permutation(String s1, String s2) {
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int count = 1;
if(s1.length()!=s2.length()) {
return false;
}
for(Character c: s1.toCharArray()) {
if(!map.containsKey(c)) {
map.put(c, 1);
}
else {
map.put(c, map.get(c) + 1);
}
}
for(Character c: s2.toCharArray()) {
if(!map.containsKey(c)) {
return false;
}
else {
map.put(c, map.get(c) - 1);
}
}
for(Character c: map.keySet()) {
if(map.get(c) != 0) { return false; }
}
return true;
}
bool is_permutation1(string str1, string str2) {
sort(str1.begin(), str1.end());
sort(str2.begin(), str2.end());
for (int i = 0; i < str1.length(); i++) {
if (str1[i] != str2[i]) {
return false;
}
}
return true;
}
I wanted to give a recursive solution for this problem as I did not find any answer which was recursive. I think that this code seems to be tough but if you'll try to understand it you'll see the beauty of this code. Recursion is sometimes 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 solutions 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 "".
Reference: Introduction to Programming in Java

Categories

Resources