Jump to content

Recommended Posts

Posted (edited)

Can someone help me to write this in AutoIt? Actually I don't understand this part: str[stroff] != 0

int srchstr( const char *str, char c, int pos )
{
    for(int stroff = pos; str[stroff] != 0; ++stroff)
    {
        if(str[stroff] == c)
        {
            return stroff;
        }
    }

    return -1;
}
and

void swap( T &a, T &b )
{
    T temp = a;
    a = b;
    b = temp;
}
Edited by Andreik
Posted (edited)

I believe != means not equal. I'm not a c++ guy, but it looks like a continuous loop until str[stroff] = 0

edit:

I believe the StringInstr func should accomplish the first piece of code.

Edited by spudw2k
Posted (edited)

This is already built in to AutoIt

$istroff = StringInStr($str,$c,1,1,$ipos,1)
$istroff-= 1

Swap function

Func _Swap(ByRef $a, ByRef $b )
 Local $Temp
 $Temp = $a
 $a = $b
 $b = $Temp
EndFunc
Edited by Bowmore

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Posted (edited)

Thanks guys but something is still wrong. I tried to convert this function:

// search a character inside a string
int srchstr( const char *str, char c, int pos )
{
    for(int stroff = pos; str[stroff] != 0; ++stroff)
    {
        if(str[stroff] == c)
        {
            return stroff;
        }
    }

    return -1;
}

// template function for 
// swaping two variables
template<class T>
void swap( T &a, T &b )
{
    T temp = a;
    a = b;
    b = temp;
}

// search for a number inside an array
// if that number is found,the function
// returns true otherwise it returns false
bool is_in( int *array, int index, int val )
{
    for(int i=0; i <= index; i++)
    {
        if(array[i] == val) return true;
    }
    return false;
}

float fuzzymatch( char *pattern, char *text )
{
    int Plen = strlen(pattern);
    int Tlen = strlen(text);
    // if the length of the strings are not the same
    // then we might need to swap them to make sure that 
    // the first string is the longest one
    if (Tlen > Plen) 
    {
        swap(pattern, text);
        swap(Plen, Tlen);
    }

    // variable for holding the total penalty
    // for a given charcater search
    float cost = 0.0f;

    // variable for holding the total number
    // of chacters found during the fuzzy search
    // that variable is incremented with a value
    // between 0 and 1 each time a character is found
    float hit = 0.0f;

    // this variable will be use for holding the position
    // of the current character search
    int Textloc = 0;

    // when a character is not found at the expected position
    // there should be a penalty and the penalty value will be 
    // directly proportional to the distance to which 
    // that character was found.
    // This distance is simply calculated by using the following formula.
    // distance = abs(found_position - expected_position)
    
    // seting the minimum value for a penalty
    float min_cost = (float)1/Plen;

    // declaring the "hit_pos" array
    // that array will be use to avoid
    // duplication during the search
    int *hit_pos = new int[Plen];

    // looping over the first string: "pattern"
    for(int Textoff = 0; Textoff < Plen; ++Textoff)
    {
        // search for the current character
        // belonging to the first string
        // inside the second string
        Textloc = srchstr( text, pattern[Textoff], 0 );

        // if the current character was already found 
        // at that same position makes a new search 
        // by starting at a new postion
        if ( is_in( hit_pos, Textoff, Textloc ))
        {
            int Tempoff = Textloc + 1;
            // continues the search till we found
            // a chacaracter that is not already
            // in the hit_pos array
            while( Tempoff < Tlen )
            {
                Textloc = srchstr( text, pattern[Textoff], ++Tempoff );
                if ( Textloc != -1 && !is_in( hit_pos, Textoff, Tempoff )) break;
            }
        }

        // if a character was found during the previous character search,
        // then we need to make some variable updating. Otherwise,the search will 
        // continue with the next character of the first string: "pattern"
        if (Textloc != -1)
        {
            // saving the current position to the hit_pos array
            // so that we do not reuse characters found in this position
            // later while performing the search
            hit_pos[Textoff] = Textloc;

            // calculating distance
            // expected position: Textoff
            // found position: Textloc
            int distance = abs(Textloc - Textoff);

            // calculating penalty value
            cost = distance * min_cost;

            // updating the number of characters found
            hit += 1 - cost;
        }
    }
    delete hit_pos;
    return hit/Plen;
}
Here is all source.

Here is my try:

Func FuzzyMatch($PATTERN,$STRING)
    Local $COST = 0, $HIT = 0
    Local $TEXT_LOC = 0
    $PLEN = StringLen($PATTERN)
    $SLEN = StringLen($STRING)
    If $SLEN > $PLEN Then
        Swap($PATTERN,$STRING)
        Swap($PLEN,$SLEN)
    EndIf
    $MIN_COST = 1/$PLEN
    Dim $HIT_POS[$PLEN]
    For $INDEX = 0 To $PLEN-1
        $TEXT_LOC = StringInStr($STRING,StringMid($PATTERN,$INDEX,1),1,1,0)-1
        If _IsIn($HIT_POS,$INDEX,$TEXT_LOC) Then
            $TEMP = $TEXT_LOC + 1
            While $TEMP < $SLEN
                $TEXT_LOC = StringInStr($STRING,StringMid($PATTERN,$INDEX,1),1,1,$TEMP+1)-1
                If $TEXT_LOC <> -1 And _IsIn($HIT_POS,$INDEX,$TEMP) Then ExitLoop
            WEnd
            If $TEXT_LOC <> -1 Then
                $HIT_POS[$INDEX] = $TEXT_LOC
                $DIST = Abs($TEXT_LOC-$INDEX)
                $COST = $DIST * $MIN_COST
                $HIT += 1 - $COST
            EndIf
        EndIf
    Next
    $HIT_POS = 0
    Return $HIT/$PLEN
EndFunc
        
Func _IsIn($ARRAY,$INDEX,$VAL)
    For $I = 0 To $INDEX
        If $ARRAY[$I] == $VAL Then Return True
    Next
    Return False
EndFunc

Func Swap(ByRef $A,ByRef $B)
    Local $TEMP = $A
    $A = $B
    $B = $TEMP
EndFunc

MsgBox(0,"",FuzzyMatch("how do you do?","how are you?"))
Edited by Andreik

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...