Remove array duplicates - java

I'm trying to remove duplicates from the array, but it is not working.
Am I missing something ?
Code :-
class RemoveStringDuplicates {
public static char[] removeDups(char[] str) {
boolean bin_hash[] = new boolean[256];
int ip_ind = 0, res_ind = 0;
char temp;
while (ip_ind < str.length) {
temp = str[ip_ind];
if (bin_hash[temp] == false) {
bin_hash[temp] = true;
str[res_ind] = str[ip_ind];
res_ind++;
}
ip_ind++;
}
return str;
}
public static void main(String[] args) {
char str[] = "test string".toCharArray();
System.out.println(removeDups(str));
}
}
Output :-
tes ringing //ing should not have been repeated!

Instead of assigning the characters into the same array, you should use a new array. Because, after removing the duplicates, the trailing elements are not being removed, and thus are printed.
So, if you use a new array, the trailing elements would be null characters.
So, just create an new array:
char[] unique = new char[str.length];
And then change the assignment:
str[res_ind] = str[ip_ind];
to:
unique[res_ind] = str[ip_ind];
Also, you can consider using an ArrayList instead of an array. That way you won't have to maintain a boolean array for each character, which is quite too much. You are loosing some not-needed extra space. With an ArrayList, you can use the contains method to check for the characters already added.
Well, you can also avoid doing all those counting stuffs manually, by using a Set, which automatically removes duplicates for you. But most implementation does not maintain insertion order. For that you can use LinkedHashSet.

The specific problem has already found a solution, but if you are not restricited to using your own method and can use the java libraries, I would suggest something like this:
public class RemoveDuplicates {
// Note must wrap primitives for generics
// Generic array creation not supported by java, gotta return a list
public static <T> List<T> removeDuplicatesFromArray(T[] array) {
Set<T> set = new LinkedHashSet<>(Arrays.asList(array));
return new ArrayList<>(set);
}
public static void main(String[] args) {
String s = "Helloo I am a string with duplicates";
Character[] c = new Character[s.length()];
for (int i = 0; i < s.length(); i++) {
c[i] = s.charAt(i);
}
List<Character> noDuplicates = removeDuplicatesFromArray(c);
Character[] noDuplicatesArray = new Character[noDuplicates.size()];
noDuplicates.toArray(noDuplicatesArray);
System.out.println("List:");
System.out.println(noDuplicates);
System.out.println("\nArray:");
System.out.println(Arrays.toString(noDuplicatesArray));
}
}
Out:
List:
[H, e, l, o, , I, a, m, s, t, r, i, n, g, w, h, d, u, p, c]
Array:
[H, e, l, o, , I, a, m, s, t, r, i, n, g, w, h, d, u, p, c]
The linkedhashset retains ordering, which might be especially important for things like characterarrays.

Try This:
public static char[] removeDups(char[] str) {
boolean bin_hash[] = new boolean[256];
int ip_ind = 0, res_ind = 0;
char temp;
char a[] = new char[str.length];
while (ip_ind < str.length) {
temp = str[ip_ind];
if (bin_hash[temp] == false) {
bin_hash[temp] = true;
a[res_ind] = str[ip_ind];
res_ind++;
}
ip_ind++;
}
return a;
}
You basically are updating the str variable in the loop. Updating it and again looping on the updated array.

I believe the problem is caused by the fact that you are iterating over str while you are modifying it (by the line str[res_ind] = str[ip_ind]). If you copy the result to another array, it works:
class RemoveStringDuplicates {
public static char[] removeDups(char[] str) {
char result[] = new char[str.length];
boolean bin_hash[] = new boolean[256];
int ip_ind = 0, res_ind = 0;
char temp;
while (ip_ind < str.length) {
temp = str[ip_ind];
if (bin_hash[temp] == false) {
bin_hash[temp] = true;
result[res_ind] = str[ip_ind];
res_ind++;
}
ip_ind++;
}
return result;
}
public static void main(String[] args) {
char str[] = "test string".toCharArray();
System.out.println(removeDups(str));
}
}

All the other answers seem to be correct. The "ing" that you see at the end of the result is actually untouched characters already in the array.
As an alternative solution (if you want to conserve memory), you can loop over the last part of the array to delete the characters at the end because you already know they are duplicate.
//C# code, I think you just need to change str.Length here to str.length
for (int delChars = res_ind; delChars < str.Length; delChars++)
{
str[delChars] = '\0';
}

You are totally abusing the Java language with your code. The data structure classes in the standard libraries are the main point of using Java. Use them.
The correct way to code something to do what you want is here:
class RemoveStringDuplicates {
public static String removeDups(CharSequence str) {
StringBuilder b = new StringBuilder(str);
HashSet<Character> s = new HashSet<Character>();
for(int idx = 0; idx < b.size(); idx++)
if(mySet.contains(b.charAt(idx)))
b.deleteCharAt(idx--);
else
s.add(ch);
return b.toString();
}
public static void main(String[] args) {
System.out.println(removeDups(str));
}
}
There are probably even better ways of doing it, too. Don't go avoiding Java's data structures.
If you are writing code that is performance-sensitive enough that you have to use primitive code like that in your question, you should be using a different language, like C.

Related

Parsing a string and returning an array

Heres my code that takes a string and returns an array of the ascii values for each character in the array in order. Compile error is 'array required, but java.lang.String found'
public class Q1E {
int[] stringToCodes(String characters){
int characterLength= length(characters);
int[] array=new int[characterLength];
for(int i=0;i<characterLength;i++) {
array[i] =(int) characters[i];
}
}
}
You can't use array syntax on a String, use character.charAt(i)instead. Also, you need to return the array at the end.
Java uses Unicode/UTF-16 for strings, not ASCII.
If want to restrict your method to processing characters in the ASCII range, it should throw an exception when it encounters one outside that range.
If you want a sequence of "character codes" (aka codepoints), you have to use the String.codePointAt() at method. Because String holds a counted sequences of UTF-16 code-units and there might be one or two code-units per codepoint, you only know that String.length() is an upper bound of the number of codepoints in advance.
public class Q1E {
int[] stringToCodes(String s) {
int[] codepoints = new int[s.length()]; // there might be fewer
int count = 0;
for(int cp, i = 0; i < s.length(); i += Character.charCount(cp)) {
cp = s.codePointAt(i);
// for debugging, output in Unicode stylized format
System.out.println(String.format(
cp < 0x10000 ? "U+%04X" : "U+%05X", cp));
codepoints[count++] = cp;
}
int[] array = java.util.Arrays.copyOf(codepoints, count);
return array;
}
}
Try it with this Wikipedia link on an English word:
stringToCodes("http://en.wikipedia.org/wiki/Résumé");
Your code appears to have a few bugs, it's String#length() and I would suggest you add a null check. Finally (since characters isn't an array), I think you want to use String#charAt(int)
int[] stringToCodes(String characters) {
int characterLength = 0;
if (characters != null) {
characterLength = characters.length();
}
int[] array = new int[characterLength];
for (int i = 0; i < characterLength; i++) {
array[i] = characters.charAt(i);
}
return array;
}
Of course, you could shorten it with a ternary
int characterLength = (characters != null) ? characters.length() : 0;
int[] array = new int[characterLength];
try this:
public class Test {
public static void main(String[] args) {
int []ascii=stringToCodes("abcdef");
for(int i=0;i<ascii.length;i++){
System.out.println(ascii[i]);
}
}
public static int [] stringToCodes(String characters){
int []ascii=new int[characters.length()];
for(int i=0;i<characters.length();i++){
ascii[i]=(int)characters.charAt(i);
}
return ascii;
}
}

Code isnt even executing. JAVA

For some reason my if statement is not even being executed at all. Cannot figure out what is wrong, I am trying to test a word called "fuor" and do some manipulations in the hash table I have.
if(table[getHashIndex(c.toString())].contains(c.toString()))
this is the line that is not executing
Tableclass
char[] c = word.toCharArray();
for(int i=0;i<word.length()-1;i++)
{
char tempChar= c[i];
c[i]=c[i+1];
c[i+1]=tempChar;
if(table[getHashIndex(c.toString())].contains(c.toString()))
{
list.add(c.toString());
System.out.println("GOT IT BABY");
}
c = word.toCharArray();
}
public int getHashIndex(String word){
int key = 7;
//Adding ASCII values of string
//To determine the index
for(int i = 0 ; i < word.length(); i++){
key = key*BASE+(int)word.charAt(i);
//Accounting for integer overflow
if(key<0)
{
key*=-1;
}
}
key %= sizeOfTable;
return key;
}
//Bucket class
public boolean contains(String word){
Node insert = start;
//Traversing the list to find a match
while(insert!=null){
if(word.equalsIgnoreCase(insert.item))
return true;
insert = insert.next;
}
//did not find a match
return false;
}
The toString on a Java Array returns the default Object toString() (because arrays are not a primitive type e.g. c.toString() looks like this),
char[] t = new char[] { 'a' };
System.out.println(t.toString());
Output (for example)
[C#25f45022
I think you really wanted something like
char[] t = new char[] { 'a' };
System.out.println(java.util.Arrays.toString(t));
Which outputs
[a]
Or, maybe you wanted something like this
char[] t = new char[] { 'a' };
System.out.println(new String(t));
Which outputs
a

Converting String to "Character" array in Java

I want to convert a String to an array of objects of Character class but I am unable to perform the conversion. I know that I can convert a String to an array of primitive datatype type "char" with the toCharArray() method but it doesn't help in converting a String to an array of objects of Character type.
How would I go about doing so?
Use this:
String str = "testString";
char[] charArray = str.toCharArray();
Character[] charObjectArray = ArrayUtils.toObject(charArray);
One liner with java-8:
String str = "testString";
//[t, e, s, t, S, t, r, i, n, g]
Character[] charObjectArray =
str.chars().mapToObj(c -> (char)c).toArray(Character[]::new);
What it does is:
get an IntStream of the characters (you may want to also look at codePoints())
map each 'character' value to Character (you need to cast to actually say that its really a char, and then Java will box it automatically to Character)
get the resulting array by calling toArray()
Why not write a little method yourself
public Character[] toCharacterArray( String s ) {
if ( s == null ) {
return null;
}
int len = s.length();
Character[] array = new Character[len];
for (int i = 0; i < len ; i++) {
/*
Character(char) is deprecated since Java SE 9 & JDK 9
Link: https://docs.oracle.com/javase/9/docs/api/java/lang/Character.html
array[i] = new Character(s.charAt(i));
*/
array[i] = s.charAt(i);
}
return array;
}
Converting String to Character Array and then Converting Character array back to String
//Givent String
String given = "asdcbsdcagfsdbgdfanfghbsfdab";
//Converting String to Character Array(It's an inbuild method of a String)
char[] characterArray = given.toCharArray();
//returns = [a, s, d, c, b, s, d, c, a, g, f, s, d, b, g, d, f, a, n, f, g, h, b, s, f, d, a, b]
//ONE WAY : Converting back Character array to String
int length = Arrays.toString(characterArray).replaceAll("[, ]","").length();
//First Way to get the string back
Arrays.toString(characterArray).replaceAll("[, ]","").substring(1,length-1)
//returns asdcbsdcagfsdbgdfanfghbsfdab
or
// Second way to get the string back
Arrays.toString(characterArray).replaceAll("[, ]","").replace("[","").replace("]",""))
//returns asdcbsdcagfsdbgdfanfghbsfdab
//Second WAY : Converting back Character array to String
String.valueOf(characterArray);
//Third WAY : Converting back Character array to String
Arrays.stream(characterArray)
.mapToObj(i -> (char)i)
.collect(Collectors.joining());
Converting string to Character Array
Character[] charObjectArray =
givenString.chars().
mapToObj(c -> (char)c).
toArray(Character[]::new);
Converting char array to Character Array
String givenString = "MyNameIsArpan";
char[] givenchararray = givenString.toCharArray();
String.valueOf(givenchararray).chars().mapToObj(c ->
(char)c).toArray(Character[]::new);
benefits of Converting char Array to Character Array you can use the Arrays.stream funtion to get the sub array
String subStringFromCharacterArray =
Arrays.stream(charObjectArray,2,6).
map(String::valueOf).
collect(Collectors.joining());
String#toCharArray returns an array of char, what you have is an array of Character. In most cases it doesn't matter if you use char or Character as there is autoboxing. The problem in your case is that arrays are not autoboxed, I suggest you use an array of char (char[]).
You have to write your own method in this case. Use a loop and get each character using charAt(i) and set it to your Character[] array using arrayname[i] = string.charAt[i].
I hope the code below will help you.
String s="Welcome to Java Programming";
char arr[]=s.toCharArray();
for(int i=0;i<arr.length;i++){
System.out.println("Data at ["+i+"]="+arr[i]);
}
It's working and the output is:
Data at [0]=W
Data at [1]=e
Data at [2]=l
Data at [3]=c
Data at [4]=o
Data at [5]=m
Data at [6]=e
Data at [7]=
Data at [8]=t
Data at [9]=o
Data at [10]=
Data at [11]=J
Data at [12]=a
Data at [13]=v
Data at [14]=a
Data at [15]=
Data at [16]=P
Data at [17]=r
Data at [18]=o
Data at [19]=g
Data at [20]=r
Data at [21]=a
Data at [22]=m
Data at [23]=m
Data at [24]=i
Data at [25]=n
Data at [26]=g
another way to do it.
String str="I am a good boy";
char[] chars=str.toCharArray();
Character[] characters=new Character[chars.length];
for (int i = 0; i < chars.length; i++) {
characters[i]=chars[i];
System.out.println(chars[i]);
}
This method take String as a argument and return the Character Array
/**
* #param sourceString
* :String as argument
* #return CharcterArray
*/
public static Character[] toCharacterArray(String sourceString) {
char[] charArrays = new char[sourceString.length()];
charArrays = sourceString.toCharArray();
Character[] characterArray = new Character[charArrays.length];
for (int i = 0; i < charArrays.length; i++) {
characterArray[i] = charArrays[i];
}
return characterArray;
}
if you are working with JTextField then it can be helpfull..
public JTextField display;
String number=e.getActionCommand();
display.setText(display.getText()+number);
ch=number.toCharArray();
for( int i=0; i<ch.length; i++)
System.out.println("in array a1= "+ch[i]);
chaining is always best :D
String str = "somethingPutHere";
Character[] c = ArrayUtils.toObject(str.toCharArray());
If you don't want to rely on third party API's, here is a working code for JDK7 or below. I am not instantiating temporary Character Objects as done by other solutions above. foreach loops are more readable, see yourself :)
public static Character[] convertStringToCharacterArray(String str) {
if (str == null || str.isEmpty()) {
return null;
}
char[] c = str.toCharArray();
final int len = c.length;
int counter = 0;
final Character[] result = new Character[len];
while (len > counter) {
for (char ch : c) {
result[counter++] = ch;
}
}
return result;
}
I used the StringReader class in java.io. One of it's functions read(char[] cbuf) reads a string's contents into an array.
String str = "hello";
char[] array = new char[str.length()];
StringReader read = new StringReader(str);
try {
read.read(array); //Reads string into the array. Throws IOException
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < str.length(); i++) {
System.out.println("array["+i+"] = "+array[i]);
}
Running this gives you the output:
array[0] = h
array[1] = e
array[2] = l
array[3] = l
array[4] = o
String[] arr = { "abc", "cba", "dac", "cda" };
Map<Character, Integer> map = new HashMap<>();
String string = new String();
for (String a : arr) {
string = string.concat(a);
}
System.out.println(string);
for (int i = 0; i < string.length(); i++) {
if (map.containsKey(string.charAt(i))) {
map.put(string.charAt(i), map.get(string.charAt(i)) + 1);
} else {
map.put(string.charAt(i), 1);
}
}
System.out.println(map);
//out put {a=4, b=2, c=4, d=2}

java string permutations and combinations lookup

I'm writing an Android word app. My code includes a method that would find all combinations of the string and the substrings of a 7 letter string with a minimum of length 3. Then compare all available combination to every word in the dictionary to find all the valid words. I'm using a recursive method. Here's the code.
// Gets all the permutations of a string.
void permuteString(String beginningString, String endingString) {
if (endingString.length() <= 1){
if((Arrays.binarySearch(mDictionary, beginningString.toLowerCase() + endingString.toLowerCase())) >= 0){
mWordSet.add(beginningString + endingString);
}
}
else
for (int i = 0; i < endingString.length(); i++) {
String newString = endingString.substring(0, i) + endingString.substring(i + 1);
permuteString(beginningString + endingString.charAt(i), newString);
}
}
// Get the combinations of the sub-strings. Minimum 3 letter combinations
void subStrings(String s){
String newString = "";
if(s.length() > 3){
for(int x = 0; x < s.length(); x++){
newString = removeCharAt(x, s);
permuteString("", newString);
subStrings(newString);
}
}
}
The above code runs fine but when I installed it on my Nexus s I realized that it runs a bit too slow. It takes a few seconds to complete. About 3 or 4 seconds which is unacceptable.
Now I've played some word games on my phone and they compute all the combinations of a string instantly which makes me believe that my algorithm is not very efficient and it can be improved. Can anyone help?
public class TrieNode {
TrieNode a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
TrieNode[] children = {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z};
private ArrayList<String> words = new ArrayList<String>();
public void addWord(String word){
words.add(word);
}
public ArrayList<String> getWords(){
return words;
}
}
public class Trie {
static String myWord;
static String myLetters = "afinnrty";
static char[] myChars;
static Sort sort;
static TrieNode myNode = new TrieNode();
static TrieNode currentNode;
static int y = 0;
static ArrayList<String> availableWords = new ArrayList<String>();
public static void main(String[] args) {
readWords();
getPermutations();
}
public static void getPermutations(){
currentNode = myNode;
for(int x = 0; x < myLetters.length(); x++){
if(currentNode.children[myLetters.charAt(x) - 'a'] != null){
//availableWords.addAll(currentNode.getWords());
currentNode = currentNode.children[myLetters.charAt(x) - 'a'];
System.out.println(currentNode.getWords() + "" + myLetters.charAt(x));
}
}
//System.out.println(availableWords);
}
public static void readWords(){
try {
BufferedReader in = new BufferedReader(new FileReader("c://scrabbledictionary.txt"));
String str;
while ((str = in.readLine()) != null) {
myWord = str;
myChars = str.toCharArray();
sort = new Sort(myChars);
insert(myNode, myChars, 0);
}
in.close();
} catch (IOException e) {
}
}
public static void insert(TrieNode node, char[] myChars, int x){
if(x >= myChars.length){
node.addWord(myWord);
//System.out.println(node.getWords()+""+y);
y++;
return;
}
if(node.children[myChars[x]-'a'] == null){
insert(node.children[myChars[x]-'a'] = new TrieNode(), myChars, x=x+1);
}else{
insert(node.children[myChars[x]-'a'], myChars, x=x+1);
}
}
}
In your current approach, you're looking up every permutation of each substring. So for "abc", you need to look up "abc", "acb", "bac", "bca", "cab" and "cba". If you wanted to find all permutations of "permutations", your number of lookups is nearly 500,000,000, and that's before you've even looked at its substrings. But we can reduce this to one lookup, regardless of length, by preprocessing the dictionary.
The idea is to put each word in the dictionary into some data structure where each element contains a set of characters, and a list of all words containing (only) those characters. So for example, you could build a binary tree, which would have a node containing the (sorted) character set "abd" and the word list ["bad", "dab"]. Now, if we want to find all permutations of "dba", we sort it to give "abd" and look it up in the tree to retrieve the list.
As Baumann pointed out, tries are well suited to storing this kind of data. The beauty of the trie is that the lookup time depends only on the length of your search string - it is independent of the size of your dictionary. Since you'll be storing quite a lot of words, and most of your search strings will be tiny (the majority will be the 3-character substrings from the lowest level of your recursion), this structure is ideal.
In this case, the paths down your trie would reflect the character sets rather than the words themselves. So if your entire dictionary was ["bad", "dab", "cab", "cable"], your lookup structure would end up looking like this:
There's a bit of a time/space trade-off in the way you implement this. In the simplest (and fastest) approach, each Node contains just the list of words, and an array Node[26] of children. This allows you to locate the child you're after in constant time, just by looking at children[s.charAt(i)-'a'] (where s is your search string and i is your current depth in the trie).
The downside is that most of your children arrays will be mostly empty. If space is an issue, you can use a more compact representation like a linked list, dynamic array, hash table, etc. However, these come at the cost of potentially requiring several memory accesses and comparisons at each node, instead of the simple array access above. But I'd be surprised if the wasted space was more than a few megabytes over your whole dictionary, so the array-based approach is likely your best bet.
With the trie in place, your whole permutation function is replaced with one lookup, bringing the complexity down from O(N! log D) (where D is the size of your dictionary, N the size of your string) to O(N log N) (since you need to sort the characters; the lookup itself is O(N)).
EDIT: I've thrown together an (untested) implementation of this structure: http://pastebin.com/Qfu93E80
See here: How to find list of possible words from a letter matrix [Boggle Solver]
The idea behind the code in the answers is as follows:
Iterate over each word dictionary.
Iterate over each letter in the word, adding it to a string and adding the string each time to an array of prefixes.
When creating string combinations, test to see that they exist in the prefix array before branching any further.
static List<String> permutations(String a) {
List<String> result=new LinkedList<String>();
int len = a.length();
if (len<=1){
result.add(a);
}else{
for (int i=0;i<len; i++){
for (String it:permutations(a.substring(0, i)+a.substring(i+1))){
result.add(a.charAt(i)+it);
}
}
}
return result;
}
I don't think adding all permutations is necessary. You can simply encapsulate the string into a PermutationString:
public class PermutationString {
private final String innerString;
public PermutationString(String innerString) {
this.innerString = innerString;
}
#Override
public int hashCode() {
int hash = 0x00;
String s1 = this.innerString;
for(int i = 0; i < s1.length(); i++) {
hash += s1.charAt(i);
}
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PermutationString other = (PermutationString) obj;
int nChars = 26;
int[] chars = new int[nChars];
String s1 = this.innerString;
String s2 = other.innerString;
if(s1.length() != s2.length()) {
return false;
}
for(int i = 0; i < s1.length(); i++) {
chars[s1.charAt(i)-'a']++;
}
for(int i = 0; i < s2.length(); i++) {
chars[s2.charAt(i)-'a']--;
}
for(int i = 0; i < nChars; i++) {
if(chars[i] != 0x00) {
return false;
}
}
return true;
}
}
A PermutationString is a string, but where two PermutationStrings are equal if they have the same frequency of characters. Thus new PermutationString("bad").equals(new PermutationString("dab")). This also holds for the .hashCode(): if the strings are permutations of each other, they will generate the same .hashCode().
Now you can simply a HashMap<PermutationString,ArrayList<String>> as follows:
HashMap<PermutationString,ArrayList<String>> hm = new HashMap<PermutationString,ArrayList<String>>();
String[] dictionary = new String[] {"foo","bar","oof"};
ArrayList<String> items;
for(String s : dictionary) {
PermutationString ps = new PermutationString(s);
if(hm.containsKey(ps)) {
items = hm.get(ps);
items.add(s);
} else {
items = new ArrayList<String>();
items.add(s);
hm.put(ps,items);
}
}
So now we iterate over all possible words in the dictionary, construct a PermutationString as key, and if the key already exists (that means that there is already a word with the same character frequencies), we simply add our own word to it. Otherwise, we add a new ArrayList<String> with the single word.
Now that we have filled up the hm with all permutations (but not that much keys), you can query:
hm.get(new PermutationString("ofo"));
This will return an ArrayList<String> with "foo" and "oof".
Testcase:
HashMap<PermutationString, ArrayList<String>> hm = new HashMap<PermutationString, ArrayList<String>>();
String[] dictionary = new String[]{"foo", "bar", "oof"};
ArrayList<String> items;
for (String s : dictionary) {
PermutationString ps = new PermutationString(s);
if (hm.containsKey(ps)) {
items = hm.get(ps);
items.add(s);
} else {
items = new ArrayList<String>();
items.add(s);
hm.put(ps, items);
}
}
Assert.assertNull(hm.get(new PermutationString("baa")));
Assert.assertNull(hm.get(new PermutationString("brr")));
Assert.assertNotNull(hm.get(new PermutationString("bar")));
Assert.assertEquals(1,hm.get(new PermutationString("bar")).size());
Assert.assertNotNull(hm.get(new PermutationString("rab")));
Assert.assertEquals(1,hm.get(new PermutationString("rab")).size());
Assert.assertNotNull(hm.get(new PermutationString("foo")));
Assert.assertEquals(2,hm.get(new PermutationString("foo")).size());
Assert.assertNotNull(hm.get(new PermutationString("ofo")));
Assert.assertEquals(2,hm.get(new PermutationString("ofo")).size());
Assert.assertNotNull(hm.get(new PermutationString("oof")));
Assert.assertEquals(2,hm.get(new PermutationString("oof")).size());
Use a Trie
Instead of testing all N! possibilities, you only follow prefix trees that lead to a result. This will significanlty reduce the amount of strings that you're checking against.
Well, you can extend your dictionary entities with array letters[] where letters[i] stays for times that i-th letter of alphabet used in this word. It'll take some additional memory, not far much than it is used now.
Then, for each word which permutations you want to check, you'll need to count number of distinct letters too and then traverse through dictiory with easy comparison procedure. If for all letters for word from dictionary number of occurrences less or equal than for word we are checking - yes, this word can be represented as permutation of substring, otherwise - no.
Complexity: it'll took O(D * maxLen) for precalculation, and O(max(N, D)) for each query.

splitting string into an array of ints

I have a string s="1,2,3,4,5" . I am using the split() method to split the string then i want to store it into an array of ints.
I tried doing the following but it doesn't work.
int i[]=Integer.parseInt(s.split(","));
I want to know if it is possible to do this without using a loop.
There is something like Array.convertAll in C# but I don't know of a similar thing in java.
In java there is no such way (method) by which you can directly get a int array by passing String array
So u must write some method to do this...
and if there is condition that you must not have to use loop then ...i write a code by adding some more code in Adel Boutros may u get help from this but its better to you loop.. :)
public class Test {
public static void main(String[] args) {
String s = "1,2,3,4,5";
int size = 0;
int[] arr = new int[s.split(",").length];
findInt(s, arr, size);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
static void findInt(String s, int[] arr, int index) {
String aa = null;
if (s == null) {
return;
}
if (s.length() != 1) {
String text = s.substring(0, s.indexOf(","));
arr[index] = Integer.parseInt(text);
} else {
arr[index] = Integer.parseInt(s);
}
if (s.length() != 1) {
aa = s.substring(s.indexOf(",") + 1, s.length());
}
findInt(aa, arr, ++index);
}
}
If you don't want to use a loop, you can call a method which does the loop for you.
e.g. (You will need to write the convertToInts method)
int[] ints = convertToInts(s);
In pure Java, there is no way of doing this.
In Apache Commons (especially Commons Lang), there are transform utilities that only take a function with array and do what you want, you don't have to code the loop by yourself.
public static void main (String []args) {
String s="1,2,3,4,5";
int size = 0;
int [] arr = new int [s.length];
findInt(s, arr, size);
}
void findInt(String s, int [] arr, int index) {
if (s.isEmpty()) {
return;
}
String text = s.substring(0,s.indexOf(","));
arr[index] = Integer.parseInt(text);
findInt(text.substring(1), arr, ++index);
}
PS: My method uses the recursive approach. The variable size will be the actual size of the int array.
This one will probably fail your contest, but it indeed avoids the loop :)
public static void main(String[] args) throws Exception {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
String s = "1,2,3,4,5";
String s1 = s.replaceAll("(\\d+),?", "arr[i++]=$1;");
int[] arr = new int[s.split(",").length];
jsEngine.put("arr", arr);
jsEngine.eval("var i=0;" + s1);
}
The result is an int[] filled with numbers from your String.

Categories