2014-04-16 2 views
1

Я пытаюсь найти подходящий алгоритм, который соответствует 3 атрибутам, и я не могу придумать эффективного решения. Вот psuedocode для моего алгоритмаКак эффективно сопоставлять несколько значений

Алгоритм выполняет следующие действия:

  • Проверьте, есть ли совпадение по первым критериям.
  • Если есть совпадение по первым критериям, я попытаюсь сузить совпадение по другим критериям 2 .
  • Если нет совпадений по первым критериям, попробуйте сделать совпадение по второму критерию.
  • Если есть совпадение по второму критерию , я попытаюсь сузить совпадение по последним критериям .
  • Etc ...

Похоже, этот алгоритм просто повторяется, а если добавить еще одно значение для сопоставления, то этот алгоритм становится очень большой реальный быстро.

//try to match on criteria 1 
if results exist for match on criteria 1 { 
    //try to match on criteria 1 & 2 
    if results exist for match on criteria 1 & 2 { 
     //try to match on criteria 3 
     if result exist for match on criteria 1,2,3 { 
      return results for match on 1,2,3 
     } 
     else 
      return results for match on 1,2 
    } 
    else 
     return results for match on 1 
} 
//try to match on criteria 2 
else if results exist for match on criteria 2 { 
    //try to match on criteria 2 & 3 
    if result exist for match on criteria 2,3 { 
     return results for match on 2,3 
    } 
    else 
     return results for match on 2 
} 
//try to match on criteria 3 
else if results exist for match on criteria 3 { 
    return results for match on 3 
} 
else { 
    no match 
} 

Есть ли лучший способ сделать это? Кажется

+0

@MitchWheat если объединить результаты, то я не буду получать наиболее сузили результаты можно. Я бы получил большой результирующий набор, который содержит как близкие, так и узкие совпадения. Этот алгоритм пытается получить самое близкое совпадение. – user2158382

+0

, если в списке были значения, подтверждающие критерий X, добавление нового значения в список может привести к аннулированию критерия X? –

ответ

1

Вот реализация в Javascript, если я вас правильно понимаю.

function filter(arr, condition) { 
    var retval = []; 
    for (i in arr) if (condition(arr[i])) retval.push(arr[i]); 
    return retval; 
} 

function first_match(arr, conditions) { 
    if (conditions.length == 0) return("No match"); 
    var initial_arr = Array.prototype.slice.call(arr); 
    var prev_arr; 
    var i = 0; 
    for (; i < conditions.length && arr.length != 0; i++) { 
    prev_arr = Array.prototype.slice.call(arr); 
    arr = filter(arr, conditions[i]); 
    } 
    if (i <= 1 && arr.length == 0) return first_match(initial_arr, Array.prototype.slice.call(conditions, 1)); 
    else if (i == conditions.length && arr.length != 0) return arr; 
    else return prev_arr; 
} 

Примеры

var conditions = [function(x) { return x > 3; }, 
        function(x) { return x % 2 == 0; }, 
        function(x) { return Math.sqrt(x) % 1 == 0; }]; 

var example1 = [1,2,3,4,5,6,7,8,9,10]; 
console.log(first_match(example1, conditions)); // [4] - all three hold 
var example2 = [1,2,3,5,6,7,8,9,10]; 
console.log(first_match(example2, conditions)); // [6, 8, 10] - First two hold 
var example3 = [5, 7, 9]; 
console.log(first_match(example3, conditions)); // [5, 7, 9] - First one holds 
var example4 = [-2, 0, 2]; 
console.log(first_match(example4, conditions)); // [0] - 2 & 3 hold 
var example5 = [-2, 2]; 
console.log(first_match(example5, conditions)); // [-2, 2] - Only 2 holds 
var example6 = [1]; 
console.log(first_match(example6, conditions)); // [1] - Last one holds 
var example7 = [-1]; 
console.log(first_match(example7, conditions)); // "No match" - None hold 
+0

Какова временная сложность входного списка размера n? –

+0

'O (n * c^2)', где 'n' - длина массива, а' c' - длина условий. Вы не можете добиться большего успеха, поскольку в худшем случае вы должны применить фильтр как минимум 'n * c (c-1)/2' раз. –

Смежные вопросы