Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  jaro_winkler.c   Sprache: C

 

/*****************************************************************************
 * jaro_winkler.c: jaro winkler string similarity algorithm implementation
 *****************************************************************************
 * Copyright 2015 Danny Guo
 * Copyright 2018 Lyndon Brown
 *
 * Authors: Danny Guo <dguo@users.noreply.github.com>
 *          Lyndon Brown <jnqnfe@gmail.com>
 *
 * Licensed under the MIT license. You may not copy, modify, or distribute this
 * file except in compliance with said license. You can find a copy of this
 * license either in the LICENSE file, or alternatively at
 * <http://opensource.org/licenses/MIT>.
 *****************************************************************************
 * This file is based upon the Jaro Winkler implementation of the `strsim`
 * Rust crate, authored by Danny Guo, available at
 * <https://github.com/dguo/strsim-rs>; more specifically the (as yet un-merged)
 * optimised copy authored by myself (Lyndon Brown), available at
 * <https://github.com/dguo/strsim-rs/pull/31>. The code is available under the
 * MIT license.
 *****************************************************************************/


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <sys/types.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
#include <assert.h>

#include "vlc_jaro_winkler.h"

#define MAX(a, b) ( ((a) > (b)) ? (a) : (b) )
#define MIN(a, b) ( ((a) < (b)) ? (a) : (b) )

/**
 * Checks both strings for a common prefix, returning the number of matching
 * bytes.
 */

static inline size_t split_on_common_prefix(const char *a, const char *b) {
    size_t len = 0;
    while (*(a) && *(b) && *(a++) == *(b++)) len++;
    return len;
}

/**
 * This is the inner Jaro algorithm, with a parameter for passing back the
 * length of the prefix common to both strings, used for efficiency of the
 * Jaro-Winkler implementation.
 */

static inline int jaro_inner(const char *a, const char *b, size_t *ret_prefix_cc, float* res) {
    assert(a && b && ret_prefix_cc && res);

    if ((a[0] == '\0') ^ (b[0] == '\0')) {
        *res = 0.0;
        return 0;
    }

    size_t prefix_char_count = split_on_common_prefix(a, b);
    const char *a_suffix = a + prefix_char_count;
    const char *b_suffix = b + prefix_char_count;

    if (a_suffix[0] == '\0' && b_suffix[0] == '\0') {
        *res = 1.0;
        return 0;
    }

    *ret_prefix_cc = prefix_char_count;

    size_t a_numchars = strlen(a_suffix) + prefix_char_count;
    size_t b_suffix_len = strlen(b_suffix);
    size_t b_numchars = b_suffix_len + prefix_char_count;

    // The check for lengths of one here is to prevent integer overflow when
    // calculating the search range.
    if (a_numchars == 1 && b_numchars == 1) {
        *res = 0.0;
        return 0;
    }

    size_t search_range = (MAX(a_numchars, b_numchars) / 2) - 1;

    /* catch overflow */
    assert(a_numchars <= INT_MAX);
    assert(search_range <= INT_MAX);

    bool *b_consumed = calloc(b_numchars, sizeof(*b_consumed));
    if (!b_consumed) {
        *res = 0.0;
        return -1;
    }

    size_t matches = prefix_char_count;
    size_t transpositions = 0;
    size_t b_match_index = 0;

    const char *a_char = a_suffix;
    for (size_t i = 0; *a_char; i++) {
        size_t bound_start = i > search_range ? i - search_range : 0;
        size_t bound_end = MIN(b_numchars, i + search_range + 1);

        if (bound_start >= bound_end) {
            a_char++;
            continue;
        }

        if (bound_start > b_suffix_len) {
            // end of b string
            break;
        }

        const char *b_char = b_suffix + bound_start;
        for (size_t j = bound_start; *b_char && j < bound_end; j++) {
            if (*a_char == *b_char && !b_consumed[j]) {
                b_consumed[j] = true;
                matches++;

                if (j < b_match_index) {
                    transpositions++;
                }
                b_match_index = j;

                break;
            }
            b_char++;
        }
        a_char++;
    }
    free(b_consumed);

    if (matches == 0) {
        *res = 0.0;
        return 0;
    }

    *res = (1.0 / 3.0) *
           (((float)matches / (float)a_numchars) +
            ((float)matches / (float)b_numchars) +
            (((float)matches - (float)transpositions) / (float)matches));
    return 0;
}

int vlc_jaro_winkler(const char *a, const char *b, float* res) {
    size_t prefix_char_count = 0;
    float jaro_distance;
    if (jaro_inner(a, b, &prefix_char_count, &jaro_distance) != 0) {
        return -1;
    }

    float jaro_winkler_distance =
        jaro_distance + (0.1 * (float)prefix_char_count * (1.0 - jaro_distance));

    *res = (jaro_winkler_distance <= 1.0) ? jaro_winkler_distance : 1.0;
    return 0;
}

Messung
CHZG
849710093

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104852
#Domains=417165