Advertisement
Guest User

Untitled

a guest
Nov 3rd, 2012
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.04 KB | None | 0 0
  1. #include "EXTERN.h"
  2. #include "perl.h"
  3. #include "XSUB.h"
  4.  
  5. #define MIN(a,b) (((a)<(b))?(a):(b))
  6. #define NULL (void *)0
  7.  
  8. struct dictionary{
  9.   int value;
  10.   int count;
  11.   struct dictionary* next;
  12. };
  13. typedef struct dictionary item;
  14.  
  15. static item* push(int v,int c,item* curr){
  16.   item* head = malloc(sizeof(item));
  17.   head->value = v;
  18.   head->count = c;
  19.   head->next = curr;
  20.   return head;
  21. }
  22.  
  23. static item* hash(item* head,int index){
  24.   item* iterator = head;
  25.   while(iterator){
  26.     if(iterator->value == index){
  27.       return iterator;
  28.     }
  29.     iterator = iterator->next;
  30.   }
  31.  
  32.   return NULL;
  33. }
  34.  
  35.  
  36.  
  37. static int scores(int src[],int tgt[],int ax,int ay){
  38.   int i,j;
  39.   int scores[ax+2][ay+2];
  40.   item *head = NULL;
  41.   int INF = ax + ay;
  42.   scores[0][0] = INF;
  43.  
  44.   /* handle blank strings */
  45.   if(ax == 0){
  46.     return ay;
  47.   }else if(ay == 0){
  48.    return ax;
  49.   }
  50.  
  51.  
  52.   /* setup scoring matrix */
  53.   for(i=0;i<=ax;i++){
  54.     scores[i+1][1] = i;
  55.     scores[i+1][0] = INF;
  56.  
  57.     if(hash(head,src[i]) == NULL){
  58.       head = push(src[i],0,head);
  59.     }
  60.   }
  61.   for(j=0;j<=ay;j++){
  62.     scores[1][j+1] = j;
  63.     scores[0][j+1] = INF;
  64.  
  65.     if(hash(head,tgt[j]) == NULL){
  66.       head = push(tgt[j],0,head);
  67.     }
  68.   }
  69.  
  70.  
  71.   /* work loop */
  72.   int db,i1,j1;
  73.   for(i=1;i<=ax;i++){
  74.     db = 0;
  75.     for(j=1;j<=ay;j++){
  76.       i1 = hash(head,tgt[j-1])->count;
  77.       j1 = db;
  78.  
  79.       if(src[i-1] == tgt[j-1]){
  80.         scores[i+1][j+1] = scores[i][j];
  81.         db = j;
  82.       }else{
  83.         scores[i+1][j+1] = MIN(scores[i][j], MIN(scores[i+1][j], scores[i][j+1])) + 1;
  84.       }
  85.  
  86.       scores[i+1][j+1] = MIN(scores[i+1][j+1], scores[i1][j1] + i - i1 - 1 + j - j1);
  87.     }
  88.  
  89.     hash(head,src[i-1])->count = i;
  90.   }
  91.  
  92.   return scores[ax+1][ay+1];
  93. }
  94.  
  95. int cxs_edistance (AV* arraySource, AV* arrayTarget) {
  96.  
  97.     /* Skip down to next comment chunk, not using this yet */
  98.     /* This is left to clarify what we're solving          */
  99.  
  100.     int i,j;
  101.     int lenSource = av_len(arraySource)+1;
  102.     int lenTarget = av_len(arrayTarget)+1;
  103.     int arrSource [ lenSource ];
  104.     int arrTarget [ lenTarget ];
  105.     int lenSource2 = 0;
  106.     int lenTarget2 = 0;
  107.  
  108.     for (i=0; i < lenSource; i++) {
  109.         SV** elem = av_fetch(arraySource, i, 0);
  110.         int retval = SvNV(*elem);
  111.  
  112.         if (elem != NULL) {
  113.             arrSource[ i ] = retval;
  114.              lenSource2++;
  115.         }
  116.     }
  117.     for (j=0; j < lenTarget; j++) {
  118.         SV** elem = av_fetch(arrayTarget, j, 0);
  119.         int retval = SvNV(*elem);
  120.  
  121.         if (elem != NULL) {
  122.             arrTarget[ j ] = retval;
  123.              lenTarget2++;
  124.         }
  125.     }
  126.     //return scores(arrSource,arrTarget,lenSource2,lenTarget2);
  127.  
  128.  
  129.     /* For testing purposes, we use known values                    */
  130.     /* Ok, perl, here are values that compile with cc and return 1 */
  131.  
  132.     int arrSourcex[4];
  133.     int arrTargetx[4];
  134.  
  135.     arrSourcex[0] = 1;
  136.     arrSourcex[1] = 2;
  137.     arrSourcex[2] = 3;
  138.     arrSourcex[3] = 4;
  139.  
  140.     arrTargetx[0] = 1;
  141.     arrTargetx[1] = 3;
  142.     arrTargetx[2] = 2;
  143.     arrTargetx[3] = 4;
  144.  
  145.  
  146.     int lenSourcex2 = 4;
  147.     int lenTargetx2 = 4;
  148.  
  149.     // *should* return 1, instead it craps out
  150.     //
  151.     // If you remove this function, compile as C, and run main,
  152.     //  it succesfully returns the correct value
  153.  
  154.     return scores(arrSourcex,arrTargetx,lenSourcex2,lenTargetx2);
  155. }
  156.  
  157. int main(void) {
  158.     // Same code as cxs_distance
  159.     // Left for ease of compiling outside of perl
  160.  
  161.     int arrSourcex[4];
  162.     int arrTargetx[4];
  163.  
  164.     arrSourcex[0] = 1;
  165.     arrSourcex[1] = 2;
  166.     arrSourcex[2] = 3;
  167.     arrSourcex[3] = 4;
  168.  
  169.     arrTargetx[0] = 1;
  170.     arrTargetx[1] = 3;
  171.     arrTargetx[2] = 2;
  172.     arrTargetx[3] = 4;
  173.  
  174.  
  175.     int lenSourcex2 = 4;
  176.     int lenTargetx2 = 4;
  177.  
  178.     return scores(arrSourcex,arrTargetx,lenSourcex2,lenTargetx2);
  179. }
  180.  
  181. MODULE = Text::Levenshtein::Damerau::XS PACKAGE = Text::Levenshtein::Damerau::XS   
  182.  
  183. PROTOTYPES: DISABLE
  184.  
  185. int
  186. cxs_edistance (arraySource, arrayTarget)
  187.     AV *    arraySource
  188.     AV *    arrayTarget
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement