두 문자열 간의 백분율 차이

두 문자열 간의 백분율 차이

두 문자열 사이의 백분율 차이를 얻는 방법이나 도구가 있습니까(개행 없이, 파일 없이)?

예를 들어, 각각 길이가 10자이고 1자만 다른 문자열 2개가 있는 경우 차이는 10%여야 합니다.

문자열 길이는 다양할 수 있으며 30자를 초과하는 경우는 거의 없습니다.

답변1

이것거리 편집두 문자열 간의 차이를 이해하는 데 유용한 측정항목입니다. 한 문자열에서 다른 문자열로 이동하는 데 필요한 삽입, 삭제 및 대체 횟수를 측정합니다.

abcdef예를 들어 와 를 비교하면 bcdef일대일 비교를 하면 문자는 다 다르지만 하나만 비교하면 됩니다.삭제하나에서 다른 것으로 이동해야합니다.

따라서 백분율을 거리 / 최대 길이로 설정할 수 있습니다.

perl -MList::Util=max -MText::LevenshteinXS -le '
  ($x, $y) = @ARGV
  print 100 * distance($x, $y) / max(length $x , length $x)
  ' -- "$string1" "$string2"

또는 awk:

awk '
    function min(x, y) {
      return x < y ? x : y
    }
    function max(x, y) {
      return x > y ? x : y
    }
    function lev(s,t) {
      m = length(s)
      n = length(t)

      for(i=0;i<=m;i++) d[i,0] = i
      for(j=0;j<=n;j++) d[0,j] = j

      for(i=1;i<=m;i++) {
        for(j=1;j<=n;j++) {
          c = substr(s,i,1) != substr(t,j,1)
          d[i,j] = min(d[i-1,j]+1,min(d[i,j-1]+1,d[i-1,j-1]+c))
        }
      }

      return d[m,n]
    }

    BEGIN {
      print 100 * lev(ARGV[1], ARGV[2]) / max(length(ARGV[1]), length(ARGV[2]))
      exit
    }' "$string1" "$string2"

이는 avs 또는 에 대해 b100을 제공 하지만 vs 또는 에 bc대해서는 50을 제공합니다 . 빈 문자열을 자신과 비교하려고 하면 0으로 나누기 오류가 발생합니다.abacababcd

이는 명령 인수의 최대 길이(최신 Linux 시스템에서는 128KiB)로 제한되지만 필요한 경우 다른 방법(예: 파일에서 문자열 읽기)으로 문자열을 가져와서 이 문제를 해결할 수 있습니다.

고려해야 할 또 다른 측정항목은 다음과 같습니다.다메라우-르벤슈타인 거리( Text::Levenshtein::Damerau모듈에서 perl). 이는 연속 문자의 전치가( abvs에서 와 같이 ba) 2 대신 1로 계산된다는 점을 제외하면 Levenshtein 거리와 동일합니다 .

이는 대략적인 일치(예: 최대 거리 2 내에서 동일한 지 확인) zsh에 사용되는 거리 이며, 인간의 철자 오류나 DNA 돌연변이를 고려할 때 일반적입니다.[[ abcd = (#a2)acbe ]]abcdacbe

답변2

ram="rambo"

ram1="rimbo"

awk -v ram=$ram -v ram1=$ram1 '{ for (i=1;i<=length(ram);i++) { if (substr(ram,i,1) != substr(ram1,i,1)) { count++ } }} END { print (count/length(ram)*100"% difference") }' <<< ""

산출:

20% difference

위의 예에서는 변수 ram과 ram1의 길이가 항상 같다고 가정합니다. 두 개의 변수를 awk에 전달하고 차이점을 추적하기 위해 count 변수를 사용하여 각 문자를 다른 문자열의 문자와 하나씩 확인합니다.

마지막으로, 서로 다른 문자열의 백분율을 계산합니다.

답변3

쉘 함수만 사용하십시오:

s1=ka3ak
s2=Raman

maxlen=${#s1}
diffs=0
[[ ${#s2} -gt $maxlen ]] && maxlen=${#s2}
for((i=0; i < maxlen; i++))
do
  [[ ${s1:i:1} == ${s2:i:1} ]] || ((++diffs))
done
echo $((100 * diffs / maxlen))

관련 정보