Yes smloh you are right. Hash map does not return objects in order they
inserted. Thats why I have used Array List inside hash map. I have made
<Character, ArrayList> pair inside hash map. The Character key will hold all
distinct characters from "welcome to google code jam" string. The
corresponding value for the each Characters is a ArrayList (which is also a
Collection) in which I am adding that Character locations one by one in the
descending order (as I am processing test string from right to left then the
second 'o' should get processed before first 'o'). So while processing each
characters from test string, I m just retrieving Array List for the
character using hash map and traversing it for further process. I have used
Array List because it is definitely going to return positions in order I
have inserted ie. desceding order.

This is my code snippet:

        final int MOD = 10000;
        int N = Integer.parseInt(reader.readLine());
        String welcome = "welcome to code jam";

        HashMap<Character,ArrayList<Integer>> map = new
HashMap<Character,ArrayList<Integer>>();

        for(int i = welcome.length() - 1; i >= 0; i--){
            char ch = welcome.charAt(i);
            if(map.containsKey(ch)){
                ArrayList<Integer> get = map.get(ch);
                get.add(i);
            }else{
                ArrayList<Integer> te = new ArrayList<Integer>();
                te.add(i);
                map.put(ch, te);
            }
        }

        long [] mul = new long[welcome.length()];

        for(int i = 1; i <= N; i++){
            String line = reader.readLine();
            Arrays.fill(mul, 0);

            for(int j = line.length() - 1; j >= 0; j--){
                char ch = line.charAt(j);
                if(map.containsKey(ch)){
                    ArrayList<Integer> get = map.get(ch);
                    for(Iterator iter = get.iterator(); iter.hasNext();){
                        int col = (Integer)iter.next();
                        if(col < welcome.length()-1){
                                mul[col] = (mul[col] + mul[col+1]) % MOD;
                        }else if(col == welcome.length()-1){
                            mul[col]++;
                        }
                    }
                }
            }
            out.printf("Case #%d: %04d\n",i,mul[0]);
        }


On Mon, Sep 7, 2009 at 9:37 PM, smloh <shanming....@gmail.com> wrote:

>
> Love that optimization, Sameer.  Great example of replacing what is
> basically an inefficient linear-time search in the inner loop with the
> magic of hash tables for a usually constant-time performance.
> Although would need to make sure to be a little careful when using
> this technique for other similar problems, as I don't think the hash
> map guarantees you'll get the characters back in the same order
> they're put in.  If the target string had two adjacent repeated
> characters (like if it said "welcome to google code jam"), then would
> need to ensure the first 'o' is processed before the second one.
>
>
> On Sep 6, 3:03 am, sameer mhatre <sam77...@gmail.com> wrote:
> > Your solution is same as mine. Only difference is that I am traversing
> test
> > string backward and using hash map to improve running time.
> >
> > You can improve the running time of your code by avoiding inner loop
> which
> > traverse 0 to 18. We can keep each distinct characters of target string
> > "welcome to code jam" in the hash map as a key and value for the key will
> be
> > the array holding respective positions in the target string.
> >
> > So while traversing outer loop for test string you just need to check
> > whether the character is available in the hash map. If it is not then no
> > need to traverse inner loop. But if the character exist then just need to
> > traverse it's respective positions (retrieve array values corresponding
> to
> > that key) only.
> >
> > You can check my solution user "sam6230i". My solution is in JAVA.
> >
> > On Fri, Sep 4, 2009 at 1:44 PM, smloh <shanming....@gmail.com> wrote:
> >
> > > I'm going to try to provide an intuitive explanation of the logic I
> > > used for Problem C, in the hope it may help some fellow programmers.
> >
> > > First the code, in old-fashioned C:
> > > #include <stdio.h>
> > > #include <stdlib.h>
> > > #include <string.h>
> > > int main(int argc,char *argv[])
> > > {
> > >   char *wstr="welcome to code jam";
> > >   FILE * pFile, *pOut;
> > >   char buffer [600];
> > >   int mults[19];
> > >   int numCases;
> > >   pFile = fopen ("c-large.in" , "r");
> > >   pOut= fopen("c-large.out","w");
> > >   if (pFile == NULL) perror ("Error opening file");
> > >   else
> > >   {
> > >     fscanf(pFile, "%d\n", &numCases);
> > >     for (int num=0;num<numCases;num++)
> > >     {
> > >        fgets(buffer, 600, pFile);
> > >        for (int i=0;i<19;i++) mults[i]=0;
> > >        fprintf(pOut,"Case #%d: ",num+1);
> > >        int len=strlen(buffer);
> > >        for (int i=0;i<len;i++){
> > >                for (int j=0;j<19;j++){
> > >                        if (j==0) {
> > >                                if (buffer[i]==wstr[j]) mults[j]++;
> > >                        }else if (mults[j-1]>0){
> > >                                if (buffer[i]==wstr[j])
> > > mults[j]=(mults[j]+mults[j-1])%10000;
> > >                        }
> > >                }
> > >        }
> > >        if (mults[18]<1000) fprintf(pOut,"0");
> > >        if (mults[18]<100) fprintf(pOut,"0");
> > >        if (mults[18]<10) fprintf(pOut,"0");
> > >        fprintf(pOut,"%d\n",mults[18]);
> > >     }
> > >     fclose (pFile);
> > >   }
> > >   return 0;
> > > }
> >
> > > Explanation:
> > > Let's call the string we are testing the "test string", and "welcome
> > > to code jam" the "target string".
> >
> > > For each test case, the outer loop of this algorithm iterates over the
> > > test string, which is stored in buffer[].  The inner loop iterates
> > > over the target string, which is stored in wstr[].
> >
> > > As we go over the test string, we keep track of a number mults[j] for
> > > each character in the target string.
> > > This is defined as:
> >
> > > mults[j] = the number of ways to build the target string up to the jth
> > > character, using the characters in the test string we have evaluated
> > > so far
> > > * to correlate to the code, "jth character" counts from 0
> >
> > > Intuitively, we can describe mults[j] as the number of ways to "get
> > > to" the jth character in "welcome to code jam" that we have found so
> > > far.
> >
> > > When j==0, each time we encounter a character match ("buffer[i]==wstr
> > > [j]"), we increment mults[0] by 1, since we have 1 more potential
> > > first character for our target string.
> >
> > > When j>0, each time we encounter a match, we increment mults[j] by
> > > mults[j-1].
> >
> > > This is because there are mults[j-1] ways so far to form the target
> > > string up (j-1)th character.  Each of these ways, when combined with
> > > the character in we are currently evaluating, gives us a new way to
> > > form the target string up to the jth character.
> >
> > > We also mod(%) the calculations by 10000, since only the values less
> > > than 10000 at each step affect the last 4 digits of our final result.
> >
> > > When we are done iterating over the entire test string, mults[18]
> > > will, by definition, be the number of ways to build the entire target
> > > string, using the characters in the entire test string.
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"google-codejam" group.
To post to this group, send email to google-code@googlegroups.com
To unsubscribe from this group, send email to 
google-code+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-code?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to