String Permutaton Problems

March 2nd, 2010 NamPham 2 comments

Hi,

Today I am trying to solve two interesting problems in String Permutations:

1. Generate all permutation of a string with assumption that all characters are unique.

The idea is recursively choose ‘available” character to build a new string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        private boolean[] mask = null;
	private char[] charSeq = null;
 
	//print all permutation with non repetition
	public void permute(String str){
		charSeq = new char[str.length()];
		mask = new boolean[str.length()];
		permutate(str,0);
	}
	private void permutate(String str,int index){
		for (int i = 0; i < str.length();i++){
			if (!mask[i]){
				charSeq[index] = str.charAt(i);
				mask[i] = true;
				if (index == str.length() - 1) System.out.println(new String(charSeq));
				else
					permutate(str,index+1);
				mask[i] = false;
			}
		}
	}

2. Generate all permutation of a string without a “uniqueness” assumption like above.

The idea is to convert this problem into the 1st one by looking more closely on the “availability’ of  characters. We can understand that in the problem one each character is unique and it has frequency is 1.  In the problem, we still have a set of “unique” character. The only difference is the frequency of each character:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
        private Hashtable charSet = new Hashtable();
        static int count = 0;
	private char[] charSeq = null;
 
	public void permute22(String str){
		count = 0;
		aSet.clear();
		charSeq = new char[str.length()];
		for (int i = 0;i < str.length(); i++){
			char chr = str.charAt(i);
			if (!charSet.keySet().contains(chr))
				charSet.put(chr,1);
			else
				charSet.put(chr,charSet.get(chr) +1);
		}
		permute22(str,0);
	}
 
	private void permute22(String str, int index){
		if (index == str.length()){
			System.out.println(++count+":"+new String(charSeq));
			aSet.add(new String(charSeq));
		}
		else{
			for (char ch:charSet.keySet()){
				if (charSet.get(ch) > 0){
					charSeq[index] = ch;
					charSet.put(ch,charSet.get(ch)-1);
					permute22(str, index+1);
					charSet.put(ch,charSet.get(ch)+1);
				}
			}
		}
	}

In future, I will collect and post more string generation/combination/generation problems.

PS: I found very interesting article about String Permutation here. Personally, I think the swapping idea is fantastic for the 1st problem. I do not think it works for the second problem with the assumption – two identical generation will happen sequentially because of sorting order. It is correct at the beginning. It is not correct during the swapping phase, however. At the middle of string generation by swapping, the order of its characters are not ordered anymore. I tested with my own source code and found the duplication in generation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
        static int count = 0;
	static HashSet aSet = new HashSet();
	private void QuickSort(char[] arr, int lower, int upper){
		if (lower >= upper) return;
		swap(arr,lower, (lower+upper)/2);
		int pivot = lower;
		int pivotValue = arr[pivot];
		for (int i = lower+1; i <= upper;i++){
			//if ith element in wrong position
			if (arr[i] < pivotValue){
				pivot++;
				swap(arr,pivot,i);
			}
		}
		//put the pivot into the correct position: <= pivotValue  = pivotValue  >= pivotValue
		swap(arr,lower,pivot);
		QuickSort(arr,lower,pivot-1);
		QuickSort(arr,pivot+1,upper);
	}
	public void permute2(String str){
		count = 0;
		aSet.clear();
		charSeq = str.toCharArray();
		QuickSort(charSeq,0,charSeq.length-1);
		System.out.println("SORTED:"+new String(charSeq));
 
		permute2(charSeq, 0);
	}
	private void swap(char[] arr,int i, int j){
		if (i == j) return;
		char temp = arr[i];arr[i] = arr[j]; arr[j] = temp;
	}
	private void permute2(char[] charSeq, int index) {
		int lastSwap = -1;
		if (index == charSeq.length - 1) {
			String aString = new String(charSeq);
			System.out.println(++count+":"+ aString);
			if (aSet.contains(aString))
				System.out.println("Collide:" + aString);
			else
			aSet.add(aString);
		}
		 else {
			for (int i = index; i < charSeq.length; i++) {
				if (charSeq[i] != lastSwap) {
					lastSwap = charSeq[i];
					swap(charSeq, i, index);
					permute2(charSeq, index + 1);
					swap(charSeq, i, index);
				}
			}
		}
	}

Hashing in Java

February 28th, 2010 NamPham No comments

This is my summary after reading a wonderful article from ibm (Java theory and practice: Hashing it out.

In my understanding, every object in Java has two implemented methods hashCode() and equals() to identify each object to others. A general rule is that two objects are equal to each other, they have the same hashcode (but the reverse is may not be true – and it is called collision).

Generally, we want to override both of them because of their relationship as mentioned above.

There are some requirements when you override two methods:

For equals(), it should:

Symmetry: a.equals(b) == b.equals(a)

Transitivity: a.equals(a) = true;

Reflexivity:  a.equals(b) == true, b.equals(c) == true -> c.equals(a) == true;

For hashCode():

Consistency: if a.equals(b) == true then a.hashCode() == b.hashCode()

Normally, when you implement the hashCode() method, we should not change the object’s hashCode() on the fly. Especially when we use a collection of objects, theirs hashCode should stay the same to avoid some unpredictable result. And we can refer these such objects as immutable objects – which their states do not change after it is constructed.
Finally, here are the interface for both two methods:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public boolean equals(Object object){
 
if (this == object) return true;
 
if (!this.getClass().equals(object.getClass())  return false;
 
return sth;
 
}
 
public int hashCode(){
 
return sth;
 
}

Java theory and practice: Hashing it out

Categories: Java Tags:

Add “Create a new txt document” in New menu (Windows 7)

February 13th, 2010 NamPham No comments

I have been using Windows 7 for a while and have nice experience with it except two problems with Windows Explorer:

1. It does not automatically update the content folder when I created/deleted files.

2. It does not have “Create a new text document” in New menu when you right click in the folder space.

I followed the guide in How to Add / Remove Items from New Menu in Windows? :

1. Open regedit and expand “HKEY_CLASSES_ROOT” key.

2. Now look for the file type which you want to add in “New” menu, e.g. for adding MP3 file type look for .MP3 key.

3. Right-click on it and select “New -> Key” and give it name “ShellNew“.

4. In right-side pane, right-click and select “New -> String Value“. Give it name “NullFile” and press Enter.

5. Thats it. You’ll immediately get the file type entry in “New” menu.

But it does not work with my windows 7. I checked my registry it already has this kind of information.

I am looking further and found out that my favorite text editor (Notepad++) has some compatibility issue with Windows 7 :( .

Fortunately, I found the solution in Windows 7 forum. It still change the content of registry but with PersistentHandler handler of text file I believe.

Here is the reg file that fixes the problem:

?Download txt.reg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Windows Registry Editor Version 5.00
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.txt]
"PerceivedType"="text"
@="txtfile"
"Content Type"="text/plain"
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.txt\PersistentHandler]
@="{5e941d80-bf96-11cd-b579-08002b30bfeb}"
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.txt\ShellNew]
"ItemName"=hex(2):40,00,25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,\
  6f,00,74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,\
  00,6e,00,6f,00,74,00,65,00,70,00,61,00,64,00,2e,00,65,00,78,00,65,00,2c,00,\
  2d,00,34,00,37,00,30,00,00,00
"NullFile"=""
Categories: Daily Life Tags: