【问题标题】:ignore extra occurrences of user input variable for partial matching between user input and reference array忽略用户输入变量的额外出现以在用户输入和参考数组之间进行部分匹配
【发布时间】:2020-01-22 01:41:16
【问题描述】:

这是一个逐字比较两个句子并返回字数部分匹配的代码。

在单词部分匹配的情况下,代码按预期工作,但有一个问题我无法解决:

我想根据expectSt 评估用户提供所需单词的能力。 (用户可以提供多少预期单词)

句子是这样的,第一个是用户输入,第二个是用来比较用户输入的参考:

// variables of user input (speechResult) and the reference to compare (expectSt)
let speechResult = 'introducing introducing introduced';
let expectSt = 'introduced';

如您所见,'introduced'expectSt 中出现了一次单词'introduced',但用户输入(speechResult)出现了三个匹配项。这里的预期结果当然是返回一个匹配。 ('introduced''introducing' 总是返回匹配项)

现在,如果我们有这个:

let speechResult = 'introducing introducing introducing ';
let expectSt = 'introducing introducing';

这次我们应该返回 2 个匹配项。

预期匹配将是 2 个匹配,因为用户能够猜测/提供预期中有两个 introducing 单词。但我的代码返回一个!

那是因为我所有的计算都是基于这些删除重复项的行:

 let uniqA = [...new Set(arrA)]; // remove duplicates
 let uniqB = [...new Set(arrB)]; // remove duplicates
 return Math.min(uniqA.length, uniqB.length);

无论如何这里是完整的代码:

// variables of user input (speechResult) and the reference to compare (expectSt)
let speechResult = 'introducing introducing introduced';
let expectSt = 'introduced';

// Create arrays of words from speechResult and expectSt
let speechResultWords = speechResult.split(/\s+/);
let expectStWords = expectSt.split(/\s+/);

// Initiate the function
let includedWords = includeWords(speechResultWords, expectStWords);

// Here is the result
console.log(includedWords)


// Function to see how many words are in speechResult and expectSt similar
function includeWords(speech, expect){

    let arrA = []; // array to hold simillar words of speechResult 
    let arrB = []; // array to hold simillar words of expectSt 

    for(let a = 0; a < speech.length; a++){
            
        for(let b = 0; b < expect.length; b++){
              /* Check each word of 'speechResult' and 'expectSt' word by word and 
               if there is more than 69 percent simillarity based on levenshtein algorithm accept them as equal words*/
            if(similarity(speech[a], expect[b]) > 69){
               arrA.push(speech[a]);
               arrB.push(expect[b]);          
               console.log(speech[a] + ' includes in ' + expect[b]);
            }
                  
        }  // End of first for loop  
        
    } // End of second for loop
        let uniqA = [...new Set(arrA)]; // remove duplicates
        let uniqB = [...new Set(arrB)]; // remove duplicates
        return Math.min(uniqA.length, uniqB.length); // This line is not what I want and needs some modifucation perhaps..
};


// Levenshtein algorithm as the string metric We Have Nothing To Do With This Part
function similarity(s1, s2) {
        var longer = s1;
        var shorter = s2;
        if (s1.length < s2.length) {
            longer = s2;
            shorter = s1;
        }
        var longerLength = longer.length;
        if (longerLength == 0) {
            return 1.0;
        }
        return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength)*100;
}

function editDistance(s1, s2) {
        s1 = s1.toLowerCase();
        s2 = s2.toLowerCase();

        var costs = new Array();
        for (var i = 0; i <= s1.length; i++) {
            var lastValue = i;
            for (var j = 0; j <= s2.length; j++) {
                if (i == 0)
                    costs[j] = j;
                else {
                    if (j > 0) {
                        var newValue = costs[j - 1];
                        if (s1.charAt(i - 1) != s2.charAt(j - 1))
                            newValue = Math.min(Math.min(newValue, lastValue),
                                costs[j]) + 1;
                        costs[j - 1] = lastValue;
                        lastValue = newValue;
                    }
                }
            }
            if (i > 0)
                costs[s2.length] = lastValue;
        }
        return costs[s2.length];
 }

【问题讨论】:

    标签: javascript


    【解决方案1】:

    好吧,如果我正确理解了您的需求,我建议您将您的 includeWords 函数替换为这个:

    function includeWords(speech, expect){
    
        let arrA = []; // array to hold expected words found in user speech 
    
        arrA = expect.filter(item => {
          return speech.some(speechItem => similarity(item, speechItem) > 69)
        });
    
        return arrA.length
    };
    

    在您的示例中的测试数据上,它返回 2。请测试另一个数据并告诉我它是否按您的需要工作:)

    希望对你有帮助

    【讨论】:

    • 嗨,谢谢你的回答......加一个......我会测试这个
    • 对于这个日期,我们期望2,因为用户只能猜到两个预期的单词,相反,我们会通过您的函数得到3let speechResult = 'introducing introducing' let expectSt = 'introducing introducing introduce';
    • @SaraRee 感谢您的更新。在这种情况下,我可以提供以下内容:首先,修剪一些初始字符串以避免数组 let speechResultWords = speechResult.trim().split(/\s+/); let expectStWords = expectSt.trim().split(/\s+/); 中的空字符串,并在我的函数中更改 return 语句,如下所示:return Math.min(arrA.length, speech.length);
    • 上帝,这里有一些东西:这会按预期返回一个事件:let speechResult = 'introducing' let expectSt = 'introducing introducing '; 但是这个返回两个! :let speechResult = 'they introducing' let expectSt = 'we introducing introducing ';
    • @SaraRee 这是适用于所有示例的版本:function includeWords(speech, expect){ let arrA = []; // array to hold simillar words of speechResult let workingSpeech = [...speech]; expect.forEach(item =&gt; { const i = workingSpeech.findIndex(speechItem =&gt; similarity(item, speechItem) &gt; 69); if (i &gt;= 0) { arrA.push(item); workingSpeech = workingSpeech.filter((wItem, index) =&gt; index !== i); } }); return arrA.length; };
    【解决方案2】:

    这是对我的功能的修改,效果很好:

    // Function to see how many words are in user speech and expected similar
    function includeWords(speech, expect){
    
        let similar = []; // array to hold simillar words of expectSt 
        let ignore = [];
    
        for(let a = 0; a < speech.length; a++){
    
            for(let b = 0; b < expect.length; b++){
                  /* Check each word of 'speechResult' and 'expectSt' word by word and 
                   if there is more than 69 percent simillarity based on levenshtein algorithm accept them as equal words*/
                   if(!ignore.includes(b)){
    
                      if(similarity(speech[a], expect[b]) > 69){
                         similar.push(expect[b]); 
                         ignore.push(b);
                         //console.log(speech[a] + ' includes in ' + expect[b]);
                         break;
                       }
    
                   }
    
            }  // End of first for loop  
    
        } // End of second for loop
    
        return similar.length;   
    
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-06
      • 2011-06-25
      • 2018-08-01
      • 2013-11-24
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 2022-09-24
      相关资源
      最近更新 更多