All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.net.ormr.fuzzywuzzy.Ratio.kt Maven / Gradle / Ivy

package net.ormr.fuzzywuzzy

import net.ormr.fuzzywuzzy.diffutils.DiffUtils
import kotlin.math.round

public sealed interface Ratio : Applicable {
    /**
     * Applies the ratio between the two strings
     *
     * @param [s1] input string
     * @param [s2] input string
     *
     * @return integer representing ratio of similarity
     */
    public override fun apply(s1: String, s2: String): Int

    /**
     * Applies the ratio between the two strings
     *
     * @param [s1] Input string
     * @param [s2] Input string
     * @param [toString] string processor to pre-process strings before calculating the ratio
     *
     * @return integer representing ratio of similarity
     */
    public fun apply(s1: String, s2: String, toString: ToStringFunction): Int

    /**
     * Partial ratio of similarity.
     */
    public data object Partial : Ratio {
        /**
         * Returns a partial ratio between [s1] and [s2].
         */
        public override fun apply(s1: String, s2: String): Int {
            val shorter: String
            val longer: String

            if (s1.length <= s2.length) {
                shorter = s1
                longer = s2
            } else {
                shorter = s2
                longer = s1
            }

            val blocks = DiffUtils.getMatchingBlocks(shorter, longer)
            val scores = mutableListOf()

            for (block in blocks) {
                val dist: Int = block.dpos - block.spos

                val longStart = if (dist > 0) dist else 0
                var longEnd = longStart + shorter.length

                if (longEnd > longer.length) longEnd = longer.length

                val longSubstring = longer.substring(longStart, longEnd)

                val ratio: Double = DiffUtils.getRatio(shorter, longSubstring)

                if (ratio > .995) {
                    return 100
                } else {
                    scores.add(ratio)
                }
            }

            return round(100 * scores.max()).toInt()
        }

        public override fun apply(
            s1: String,
            s2: String,
            toString: ToStringFunction,
        ): Int = apply(toString(s1), toString(s2))
    }

    public data object Simple : Ratio {
        /**
         * Returns a Levenshtein distance ratio between [s1] and [s2].
         */
        public override fun apply(s1: String, s2: String): Int = round(100 * DiffUtils.getRatio(s1, s2)).toInt()

        public override fun apply(
            s1: String,
            s2: String,
            toString: ToStringFunction,
        ): Int = apply(toString(s1), toString(s2))
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy