Sunday, February 19, 2017

Java Xml Tabulator

Tried to google Java or XSLT solution to convert XML to tabular data format, butcould not find an easy to understand or to use one. So that I made one myself.

https://github.com/shijiema/JavaXmlTabulator

Java Xml Tabulator

Converting XML to tabular form of data in pure Java implementation. No third party library required.
For am Xml such as
<Relations>
 <Relationship p1="v1">some text
     <id>1</id>
  <Type>OneToMany</Type>other text
  <Weight>1.0</Weight>
  <Score>100.0</Score>
 </Relationship>
 <Relationship>
  <id>2</id>   noise 3
  <Type>ManytoOne</Type>
  <Weight>1.0</Weight>
  <Score>90.0</Score>
 </Relationship>
</Relations>
It will convert it to a flatten version of data that if iterating, looks like this:
[Relations_Relationship, Relations_Relationship_Score, Relations_Relationship_Type, Relations_Relationship_Weight, Relations_Relationship_id, Relations_Relationship_p1]
[some textother text, 100.0, OneToMany, 1.0, 1, v1]
[noise 3, 90.0, ManytoOne, 1.0, 2, null]
It has two ways to access transformed data.
First method is through its iterator() method, which will return each row as List. First row is header and subsequent rows are body content. Headers and body content have been aligned.
Second method is through its getHeaders() and getBody() if partial data access is what is wanted.

Algorithm

Observations:

  1. non-repeat elements in XML could be treated as parent node's attributes
  2. repeat element in XML usually means multiple rows after being flattened
  3. path from root to node makes the columns in tabular format
tablify(){
    with XML tree,
    1. merge non-repeat elements to their parents
        1.1 from leaf to root, merge non-repeat children element to its parent as its parent's attributes. this includes both text and its attributes
            attribute name for child node is child node element name; attribute value for child node element is child node's text value
            attribute name for child node attributes are child node element name + child node attribute name; value is child element attribute value
        1.2 remove these children from their parents
        1.3 repeat 1.1 and 1.2 until no more such children exists
    2. make node production from leaf to root
        2.1 for a node, make its equivalent node production
                2.1.1 leaf node's children node is null
                2.1.2 rows of repeat children element 1 * rows repeat children element 2 * rows repeat children element n
                2.1.3 insert this parent node to head of each produced row from 2.1.1

        2.2 do 2.1 for all parent nodes(null node's parent is the leaf node), but stop at root element
        2.3 do 2.1 for root element(this is because different path has different depth, they have to wait to do final production)
    3. in each row in final node production, convert node to columns
        3.1 node column name = path to node; node value = text content in node
        3.2 node attribute column name = path to node + attribute name; node attribute column value = attribute value
        (this works well for non-repeat node wrapped as parent node's attribute)
    4.return key-value paired node production
}

  • Shi Jie Ma - Initial work

Monday, November 21, 2016

Note: Statistics, Data mining, Maching learning and Artifical integgligence

Reading from http://stats.stackexchange.com/questions/5026/what-is-the-difference-between-data-mining-statistics-machine-learning-and-ai

 'unsupervised' (we don't know the answer--discovery) or 'supervised' (we know the answer--prediction

  • Statistics quantifies numbers
  • Data Mining explains patterns
  • Machine Learning predicts with models
  • Artificial Intelligence behaves and reasons

Thursday, October 20, 2016

Recursion: Davis' Staircase

Recursion, if computation is repeated, memorization can be used to make it linear. Some of them, if asking summary of something, DP can usually be used to solve it.

In this post, I am providing DP solution instead of recursion, which should be easily be written with memorization as an optimization.

Davis has staircases in his house and he likes to climb each staircase , , or steps at a time. Being a very precocious child, he wonders how many ways there are to reach the top of the staircase.
Given the respective heights for each of the staircases in his house, find and print the number of ways he can climb each staircase on a new line.
Input Format
The first line contains a single integer, , denoting the number of staircases in his house.
Each line of the subsequent lines contains a single integer, , denoting the height of staircase .
Constraints


Subtasks
  • for of the maximum score.
Output Format
For each staircase, print the number of ways Davis can climb it in a new line.
Sample Input
3
1
3
7
Sample Output
1
4
44
Explanation
Let's calculate the number of ways of climbing the first two of the Davis' staircases:
  1. The first staircase only has step, so there is only one way for him to climb it (i.e., by jumping step). Thus, we print on a new line.
  2. The second staircase has steps and he can climb it in any of the four following ways:




Thus, we print on a new line.


 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
public class Solution {
    static void numWays(int n){
        //let dp[i] is num ways to reach stair i. 
        //each dp[i] is an accumulation of ways to reach to there
        int dp[] = new int[n+1];
        //assuming you are at nth stair, to reach there
        //you can step 1 from n-1th stair
        //or step 2 from n-2th stair or
        //step 3 from n-3th stair
        //so you have that many ways to reach to nth stair. 
        //adding them up is the ways to reach to nth stair
        //dp[3]=dp[2]+dp[1]+dp[0];
        
        /*
        to reach to stair 1, you have one way:dp[1]=1=dp[0]
        to reach to stair 2, you have: 1 from dp[0], that is 1 way,2. from dp[1], that's 1 way.
        to reach to stair 3, you can : 1. dp[0]->dp[3],2.dp[2]->dp[3],3. dp[1]->dp[3]
        whatever you use to reach dp[2] now contributes to dp[3]
        */
        if(n==1){
            System.out.println(1);
        }else if(n==2){
            System.out.println(2);
        }else{
            dp[0]=1;//0 is base 
            dp[1]=1;dp[2]=dp[1]+dp[0];

            for(int i=3;i<=n;i++){
                dp[i]=dp[i-1]+dp[i-2]+dp[i-3];
            }
            System.out.println(dp[n]);
        }
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int s = in.nextInt();
        for(int a0 = 0; a0 < s; a0++){
            int n = in.nextInt();
            numWays(n);
        }
        
    }
}

Coin Change-- number of ways

Given a number of dollars, , and a list of dollar values for  distinct coins, , find and print the number of different ways you can make change for  dollars if each coin is available in an infinite quantity.
Hints:
  • You can solve this problem recursively, but you must optimize your solution to eliminate overlapping subproblems using Dynamic Programming if you wish to pass all test cases. More specifically, think of ways to store the checked solutions and use the stored values to avoid repeatedly calculating the same values.
  • Think about the degenerate cases: 
    • How many ways can you make change for  dollars?
    • How many ways can you make change for less than  dollars if you have no coins?
  • If you are having trouble defining the storage for your precomputed values, then think about it in terms of the base case .
Input Format
The first line contain two space-separated integers describing the respective values of  and .
The second line contains  space-separated integers describing the respective values of , where each integer denotes the dollar value of a distinct coin available in an infinite quantity.
Constraints
  • The list of coins contains  distinct integers where each integer denotes the dollar value of a coin available in an infinite quantity.
Output Format
Print a single integer denoting the number of ways we can make change for  dollars using an infinite supply of our  types of coins.
Sample Input 0
4 3
1 2 3 
Sample Output 0
4
Explanation 0
For  and  there are four solutions:
Thus, we print  on a new line.
Sample Input 1
10 4
2 5 3 6
Sample Output 1
5
Explanation 1
For  and  there are five solutions:
Thus, we print  on a new line.

 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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package dp;

import java.util.Scanner;

/**
 * first successful story by analyzing it and coming up an algorithm by myself
 * --even though I saw this question before, I basically forgot.
 * Them came up a acceptable solution within 15 minutes.
 * 
 * Cheers to myself.
 * @author Andrew Ma
 *
 */
public class CoinChangeNumOfWays {
 
    public static long makeChange(int[] coins, int money) {
     //I assumes 0 denom having 0 solutions to any amount of money
     //also assumes any denom having 0 solution to 0 amount of money
     //it turns out to be right! to be brave to make assumptions!
     //making room for 0 denom and 0 amount of money
        long dp[][] = new long[coins.length+1][money+1];
        //initialization the known solutions
        //0 denom
        for(int i=0;i<money+1;i++){
            dp[0][i]=0;//no solution for each money value
        }
        //0 money value
        for(int i=0;i<coins.length+1;i++){
            dp[i][0]=0;//no coin can do 0 change
        }
        //then build up values towards to final solution
        //c and m here are for dp array's dimensions
        /*
         * define dp[c][m] as accumulated solutions at c and m 
         * dp[c][m]=
         *    1. dp[c-1][m]. when money value is less than denom, then get solution from last denom
         *        --here it needs to have a 0 denom
         *    2. dp[c-1][m]+1. when money value equals denom value, we get one more solution
         *    3. dp[c-1][m] + dp[c][m-coins[c-1]]. when money valus is greater than denom value,
         *        it adds up accumulation from previous denom and same denom for meney value
         *        not including this denom.
         * damn, when did I become so able to analyze? I guess drawing it out and practice on paper or white board
         * really helped to see one's thoughts and then you just need to write the code to reflect the thoughts. 
         * and you are confident that you are able to write code to reflect your thoughts.
         */
        for(int c=1;c<coins.length+1;c++){
            for(int m=1;m<money+1;m++){
             //when it comes to refer values in coins, c need to be converted back to 0 based
                if(m<coins[c-1]){
                    //no change at this, copy the last denom's accumulated solutions
                    dp[c][m] = dp[c-1][m];
                }
                else if(m==coins[c-1]){
                    //we get one more solution
                    dp[c][m] = dp[c-1][m] +1;
                }
                else //if (m>coins[c-1])
                    {
                    //then it is last denom's accumulated solution + lesser value's accumulated solution
                    dp[c][m] = dp[c-1][m] + dp[c][m-coins[c-1]];
                }
            }
        }
        return dp[coins.length][money];
    }
    
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int coins[] = new int[m];
        for(int coins_i=0; coins_i < m; coins_i++){
            coins[coins_i] = in.nextInt();
        }
        System.out.println(makeChange(coins, n));
    }
}