算法挑战:模糊搜索

发布于 2025-01-17 16:20:17 字数 1160 浏览 2 评论 0原文

我最近参加了一项算法挑战,使用以下条件创建模糊搜索:

给定一个集合数组,创建一个函数,该函数接收一个参数并返回一个仅包含以以下任一开头的值的新数组:

A)提供的参数 B) 提供了参数,但有 1 个差异(即 1 个不正确的字母)

数组为:fruits = [apple, apricot,banana,pear,mango,cherry,tomato]

所以:

  • fuzzySearch('ap') = ['apple, apricot ']
  • fuzzySearch('app') = ['苹果', '杏']
  • fuzzySearch('appl') = ['苹果']
  • fuzzySearch('pa') = ['banana', 'mango']

这是我想出的解决方案:

const fruits = ['apple', 'apricot', 'banana', 'pear', 'mango', 'cherry', 'tomato']

function fuzzySearch(str) {
  return fruits.filter(fruit => 
      {
             let letterCount = 0
    const fruitLetArr = fruit.toLowerCase().split('')
    const strArr = str.toLowerCase().split('')

    for (var i = 0; i < strArr.length; i++) {
     
        console.log(fruitLetArr[i], strArr[i], i, letterCount)
      if (fruitLetArr[i] !== strArr[i]) letterCount++
      if (letterCount === 2) break;
    }
     if (letterCount < 2) return true
      });
   
}

fuzzySearch(str)

有人能想到一种更快的方法,在找到解决方案之前不需要迭代每个值吗?

I recently took part in an algorithm challenge to create a Fuzzy search with the following criteria:

Given a set array, create a function that receives one argument and returns a new array containing only the values that start with either:

A) The argument provided
B) The argument provided but with 1 difference (i.e. 1 incorrect letter)

The array was: fruits = [apple, apricot, banana, pear, mango, cherry, tomato]

so:

  • fuzzySearch('ap') = ['apple, apricot']
  • fuzzySearch('app') = ['apple', 'apricot']
  • fuzzySearch('appl') = ['apple']
  • fuzzySearch('pa') = ['banana', 'mango']

This is the solution I came up with:

const fruits = ['apple', 'apricot', 'banana', 'pear', 'mango', 'cherry', 'tomato']

function fuzzySearch(str) {
  return fruits.filter(fruit => 
      {
             let letterCount = 0
    const fruitLetArr = fruit.toLowerCase().split('')
    const strArr = str.toLowerCase().split('')

    for (var i = 0; i < strArr.length; i++) {
     
        console.log(fruitLetArr[i], strArr[i], i, letterCount)
      if (fruitLetArr[i] !== strArr[i]) letterCount++
      if (letterCount === 2) break;
    }
     if (letterCount < 2) return true
      });
   
}

fuzzySearch(str)

Can anyone think of a faster way that doesn't involve iterating over every value before a soltion can be found?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落在眉间の轻吻 2025-01-24 16:20:17

这是应该稍微更有效率的东西。也更容易阅读。在此解决方案中,我假设“差异”是指用一个字母替换另一个字母,而不是添加另一个字母。

const fruits = ['apple', 'apricot', 'banana', 'pear', 'mango', 'cherry', 'tomato'];

const fuzzySearch = (str) => {
    return fruits.filter((fruit) => {
        // If our first case is met, immediately return
        if (fruit.startsWith(str)) return true;

        // Split the fruit based on the length of input string
        const test = fruit.slice(0, str.length).split('');
        let diffs = 0;

        // Compare + keep track of differences between input + sliced fruit
        test.forEach((letter, i) => letter !== str[i] && diffs++);

        // If we have more than one difference, it doesn't meet case #2
        if (diffs > 1) return false;
        return true;
    });
};

const testCases = ['ap', 'app', 'appl', 'pan', 'bp'];

for (const testCase of testCases) {
    console.log(fuzzySearch(testCase));
}

轻微更新。实际上没有必要切片水果。我们可以循环输入字符串:

const fruits = ['apple', 'apricot', 'banana', 'pear', 'mango', 'cherry', 'tomato'];

const fuzzySearch = (str) => {
    return fruits.filter((fruit) => {
        // If our first case is met, immediately return
        if (fruit.startsWith(str)) return true;

        let diffs = 0;

        // Compare + keep track of differences between input + fruit
        for (let i = 0; i < str.length; i++) {
            if (str[i] === fruit[i]) continue;
            diffs++;
        }

        // If we have more than one difference, it doesn't meet case #2
        return !(diffs > 1);
    });
};

const testCases = ['ap', 'app', 'appl', 'pan', 'bp'];

for (const testCase of testCases) {
    console.log(fuzzySearch(testCase));
}

Here's something that should be slightly more efficient. Also easier to read. In this solution, I am assuming that by "difference" you mean a substitution of a letter for another letter, rather than the addition of another letter.

const fruits = ['apple', 'apricot', 'banana', 'pear', 'mango', 'cherry', 'tomato'];

const fuzzySearch = (str) => {
    return fruits.filter((fruit) => {
        // If our first case is met, immediately return
        if (fruit.startsWith(str)) return true;

        // Split the fruit based on the length of input string
        const test = fruit.slice(0, str.length).split('');
        let diffs = 0;

        // Compare + keep track of differences between input + sliced fruit
        test.forEach((letter, i) => letter !== str[i] && diffs++);

        // If we have more than one difference, it doesn't meet case #2
        if (diffs > 1) return false;
        return true;
    });
};

const testCases = ['ap', 'app', 'appl', 'pan', 'bp'];

for (const testCase of testCases) {
    console.log(fuzzySearch(testCase));
}

Slight update. Slicing the fruit is not actually necessary. We can just loop through the input string:

const fruits = ['apple', 'apricot', 'banana', 'pear', 'mango', 'cherry', 'tomato'];

const fuzzySearch = (str) => {
    return fruits.filter((fruit) => {
        // If our first case is met, immediately return
        if (fruit.startsWith(str)) return true;

        let diffs = 0;

        // Compare + keep track of differences between input + fruit
        for (let i = 0; i < str.length; i++) {
            if (str[i] === fruit[i]) continue;
            diffs++;
        }

        // If we have more than one difference, it doesn't meet case #2
        return !(diffs > 1);
    });
};

const testCases = ['ap', 'app', 'appl', 'pan', 'bp'];

for (const testCase of testCases) {
    console.log(fuzzySearch(testCase));
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文