Getting the difference rating between two strings

example:
123
123
rating: 0
124
123
rating: 1/3

go trough each character, if the character of other string at the same index does not match, reduce from #str

Expanding on xHeptc’s suggestion, you could take the larger string, iterate over it’s characters, and up the diff accordingly.

local function compareStrings(str1: string, str2: string): number
    local len1 = #str1
    local len2 = #str2
    local maxlen = math.max(len1, len2)
    local diff = 0
    
    for i = 1, maxlen, 1 do
        --etc.
    end

    return (diff / maxlen) * 100
end

does it also count the null characters that would come from the string not being as long as the other
I.E
12
123
diff: 1/3
(actually maybe just fill up the missing characters in the other string with spaces since that would always be different then the other :eyes: atleast for what im using )

looking back, it might be a better idea to stick with one string and not jumble them into other variables…

but you would just do a length check on the string, then you can iterate the string length and string.sub out the character itself

i think you can actually just add the difference in length to diff itself

you probably could, i havent really tried to optimise this algorithm yet lol

ok so 2nd question
how do i use this to have strings with closer/lower differences near each other like
{123, 124, 985, 193} → {123, 124, 193, 985}

Well pick a starting string, 123. Then go through each of your strings and compare them to the starting string, using @12345koip’s script. Then sort the strings by how close they are. Smaller to larger difference.

Does sorting tables of strings using table.sort not normally sort them lexicographically? Also, I think the comparison operators in Luau compare strings by lexicographical order.

If you want to consider string length before lexicographical order, consider the following comparator function:

local strings = {}  -- update this

table.sort(strings, function(a, b)
	local la, lb = #a, #b

	if la == lb then
		return a < b
	else
		return la < lb
	end
end)

Another day of waiting for Luau to be added to the highlight.js list on this Discourse forum.

Stick with the shorter string and then add the difference between the lengths of the longer and shorter string as “differences”, no?

This reduces your total no. of computations on average.

don’t numbers count as characters for the purposes of table.sort

If the “difference rating” is defined by how similar two strings are, you can use Levenshtein distance for it. Levenshtein distance calculates how many edits you need to do to a string to convert it to the other, the operations are defined as either insertion, deletion or substitution of a character and depending on your implementation you can set custom costs for each operation.

This type of distance is often used in word autocorrection software, to figure out which correct word most closely matches a user misstyped word.

If you want the rating to be between 0 and 1 you can normalize it by dividing with math.max(#word1, #word2)

For example the difference between the word uninformed and uniformed using levenshtein would be one, since you only need to remove the letter n to get from string A to string B. But using the solutions provided above will consider the strings much different, because n is near the start of the string(which influences normal string sorting a lot).

1 Like

I think OP should clarify not only what they are using this calculation for but also be a bit more specific with what they are trying to find. Given the test example, I immediately thought instead of how many characters differed between strings. If, however, one considered the operations of incrementing or decrementing any digit in the number representation of the string, I’d also recommend finding the Levenshtein distance..? If my understanding of what OP wants is correct, I believe it might be more computationally expensive to employ an algorithm for finding the Levenshtein distance than linearly iterating through the indices of the string, right?

What does this mean? I assumed you were using strings instead of numbers, despite not setting the literals to strings. The title mentions strings and the message I replied to mentions strings as well

If you are referring to string comparison being ordered lexicographically, then yeah, that’s what I said. numbers aren’t lexicographically sorted using table.sort

As long they don’t plan to use Levenshtein distance for comparing very large strings or running it thousand of times in a small timeframe efficiency should not be an issue. If they want to lets say autocorrect an entire paragraph of words, they should cut it into words by spaces, then check each word individually(instead of checking the entire paragraph at once).

Although I do agree that the OP must define the problem they’re trying to solve more specifically.

1 Like

After seeing the example you added, I understand the benefit of using the LD.

I still don’t clearly understand what OP is trying to make though, and having a clearer objective would make the right choice of the solutions presented here more evident

strings include numbers for my usecase

anyways the objection
Making my compression compress better by having things closely related in a table compressed down
(it already works, i just need the most amount of compression as possible)

I’m sorry, I still don’t understand what “closely related” would be in terms of heuristics