2013-03-05 2 views
-1

나는 PHP를 사용하고 있습니다. 5 개의 텍스트 문자열이 있다고 가정 해보십시오. 나머지 2 가지와 가장 다른 2 가지를 어떻게 찾습니까?

내가 5 개 문자열이 말 :

"The quick brown fox" 
"The sly brown fox" 
"The sly brown chicken" 
"Totally different text here" 
"Not like the others" 

을하고 난 나머지 대부분의 "다른"있는 2를 찾고 싶어요. 나는 그것을 1000 개의 텍스트 문자열로 확장하고, 말하자면, 가장 많이 "다른"300 개가되도록하고 싶습니다.

어디서부터 시작해야할까요?

편집

논의를 위해입니다 "다른"을 정의하는 방법!

EDIT * 2 * 당사 PHP similar_text 함수에 따라 상이한 같은 "다른"정의

. 그러나 다른 정의가있을 수 있습니다. 진짜 문제는 모든 텍스트 문자열을 비교하는 방법입니다. 진은 합계를 계산 제안했다, 이것은 그렇게 필립의 코드의 해킹 버전 :

$strings = array(
    "The quick brown fox", 
    "The sly brown fox", 
    "The sly brown chicken", 
    "Totally different text here", 
    "Not like the others" 
); 

$n = 3; 
$sim = array(); 

for ($i = 0; $i < count($strings); $i++) { 

    $total = 0; 

    for ($j = 0; $j < count($strings); $j++) { 

     if($strings[$i] != $strings[$j]) { 

      $sim_val = similar_text($strings[$i], $strings[$j]); 
      $total += $sim_val; 
      $sim[$strings[$i]][] = array(
       "sim" => $sim_val, 
       "w1" => $strings[$i], 
       "w2" => $strings[$j] 
      ); 

     } 
    } 

    $sim[$strings[$i]]['total'] = $total; 

} 

uasort($sim, function($w1, $w2) { 
    return $w1["total"] > $w2["total"]; 
}); 

$sim = array_keys($sim); 
$sim = array_slice($sim,0,$n); 

정답처럼 보인다

Array 
(
    [0] => Not like the others 
    [1] => Totally different text here 
    [2] => The quick brown fox 
) 

를 돌려줍니다. 따로 질문입니다. Booo을을 downvoted 사람들의 모든 (덕분에 당신은

EDIT 3 *

OK ;-), 그래서 난 내 1000 문자열이 테스트를했습니다. 그들은 각각 약 500 개의 고유 한 단어와 약 14000의 strlen을 가지고 있습니다. 그래서 ...이 실행을 빨리하기 위해 우리는 즉시 similar_text을 지적 할 수 있습니다. 빠른 compare_words 함수를 작성했습니다 :

function same_words($text1,$text2) { 

    $words_1 = array_unique(explode(" ",$text1)); 
    $words_2 = array_flip(array_unique(explode(" ",$text2)));  

    foreach($words_1 AS $word) { 
     if($words_2[$word]) { 
      $count++; 
     } 
    } 

    return $count; 

} 

하지만 너무 느립니다.

+2

지구상의 "다름"이란 무엇을 의미합니까? –

+2

"다른"을 정의하십시오. 문자 수는? 구두 소리? 의미? – Jodes

+0

나는 그가 다른 단어를 의미한다고 생각한다 – MIIB

답변

0

음, 여기에 생각이다 는 다른 존재라고 부르는 정의합니다. 다양한 종류의 차이를 확인하고 점수를 부여하십시오.

  • 동일한 문자열 : 0
  • 일반적인 단어, 같은 순서 : 예를 들어 점수는 순서의 범위와 일반적인 단어의 수에 따라 달라집니다.
  • 일반적인 단어 만 등 (예를 들어 가상 거의) 같은 순서
  • 같은 순서로 글자의 공통 집합을 가지고 어떤 단어에 비 ...

점수를 더 높은, 조사 된 기준에 대한 문자열 간의 차이가 커집니다.

그런 다음 두 문자열에 대해 "차이"점수를 계산하십시오. 가장 높은 점수, 가장 다른 점수입니다.

이러한 접근 방식은 일반적으로 여러 매개 변수를 기반으로 결정해야 할 때 사용됩니다. 스팸 방지 소프트웨어가 스팸을 식별하는 방법입니다. 단, 전자 메일이 스팸과 얼마나 유사한 지 판단하기 위해 점수를 계산하는 것을 제외하고는.

문제는 : 항상 비교에 관한 것입니다. 따라서 두 문자열을 서로 비교할 수 있지만 나머지 문자열은 비교할 수 없습니다. 그래서 두 개의 가장 다른 문자열을 식별하려면 평균 시스템에 의존해야하며 평균보다 멀리 떨어진 점수를 가진 시스템을 선택해야합니다.

+3

또는 휠을 다시 발명하지 않고 jimjimmy1995에서 제안한 similar_text() 함수를 사용할 수도 있습니다. – Jean

+1

"다른", 많은 감사를 정의하는 방법에 대한 흥미로운 토론. 예, 제가 정신적으로 이것을 개념화하려고 할 때 겪는 문제는 비슷한 두 개의 텍스트 문자열이 어떻게 생겼는지 알 수 있지만 나머지는 하나의 문자열이 아닙니다. 나는 너의 평균적인 생각을 생각할 것이다. – rastaboym

+2

또는 각 문자열을 다른 모든 문자열과 비교하고 점수를 추가 할 수도 있습니다. 누적 된 점수가 가장 높은 문자열은 다른 모든 사람들과 가장 다른 문자열입니다. – Jean

2

당신이해야 할 것은 약간의 폭력이고 (즉, similar_text 기준) 유사성을 저장, 다른 단어 모든 단어를 테스트하고 유사성

$strings = array(
    "The quick brown fox", 
    "The sly brown fox", 
    "The sly brown chicken", 
    "Totally different text here", 
    "Not like the others" 
); 

$n = 5; 
$sim = array(); 
$sum = 0; 

for ($i = 0; $i < count($strings); $i++) { 
    $t = 0; 
    for ($j = 0; $j < count($strings); $j++) { 
     if ($j != $i) { 
      $t += similar_text($strings[$i], $strings[$j]); 
     } 
    } 

    $avg = $t/(count($strings) - 1); 
    $sim[] = array(
     "sim" => $avg, 
     "word" => $strings[$i] 
    ); 

    $sum += $avg; 
} 

$avg = $sum/count($strings); 
usort($sim, function($w1, $w2) use ($avg) { 
    return abs($w1["sim"] - $avg) < abs($w2["sim"] - $avg); 
}); 

for ($i = 0; $i < $n && $i < count($sim); $i++) { 
    echo $sim[$i]['word'] . "<br />"; 
} 

하여 결과를 주문하지만 당신은 이 방법은 매우 빠르고하지 않고 O(n^2 * m^3 + n log n)

대신 당신은 또한

(m 입력 문자열의 최대 길이) O(n^2*m^2 + n log n) 같은 상당히 더 나은 결과를 수행 levenshtein를 사용할 수 similar_text에서 실행되는 것을 염두에 두어야
+0

대단히 감사합니다. 나는 우리가 단지 "무력"을 가지고 있을지도 모른다고 생각했다 – rastaboym

+0

3 개의 가장 다른 .. 또는 1000 개의 문자열 중에서 300 개의 가장 다른 문자열로 이것을 확장하는 방법을 궁금해한다. – rastaboym

+0

은 $ n을 3 또는 300으로 설정합니다. – Philipp

관련 문제