在手机键盘上查找字母组合

本文关键字:组合 查找 手机 键盘 | 更新日期: 2023-09-27 18:20:52

我正在开发一个应用程序,它是一个拨号器,我想在用户按键时搜索联系人。我想搜索与电话号码以及联系人姓名匹配的联系人。我已经实现了一种基于电话号码搜索联系人的方法,当用户按键时,它会搜索与按键类似的号码。

我的代码是:

List<string> a = new List<string>();
var alphabet = "abc";
var al2 = "def";
var q = alphabet.Select(x => x.ToString());
int size = 3;
for (int i = 0; i < size - 1; i++)
    q = q.SelectMany(x => al2, (x, y) => x + y);
foreach (var item in q)
    a.Add(item);
SearchListbox.ItemsSource = listobj
    .FindAll(x => x.Phone.Contains(str) || 
        x.FirstName.Contains(a.Any().ToString()));

它适用于数字搜索,但不适用于姓名搜索。

我想在用户按键时搜索匹配字母组合的联系人。我该怎么做?我正在为windows phone构建一个应用程序,所以它必须在c#中。

在手机键盘上查找字母组合

这对正则表达式来说是一项不错的工作!下面是我用正则表达式搜索的一个例子:

        var names = new List<string>();
        names.Add("alice");
        names.Add("bob");
        names.Add("charlie");
        var digitMap = new Dictionary<int, string>()
        {
            { 1, "" },
            { 2, "[abcABC]" },
            { 3, "[defDEF]" },
            { 4, "[ghiGHI]" },
            { 5, "[jklJKL]" },
            { 6, "[mnoMNO]" },
            { 7, "[pqrsPQRS]" },
            { 8, "[tuvTUV]" },
            { 9, "[qxyzQXYZ]" },
            { 0, "" },
        };
        var enteredDigits = "26";
        var charsAsInts = enteredDigits.ToCharArray().Select(x => int.Parse(x.ToString()));
        var regexBuilder = new StringBuilder();
        foreach (var val in charsAsInts)
            regexBuilder.Append(digitMap[val]);
        var pattern = regexBuilder.ToString();
        //append a ".*" to the end of the regex to make it "StartsWith", beginning for "EndsWith", or both for "Contains";
        pattern = ".*" + pattern + ".*";
        var matchingNames = names.Where(x => Regex.IsMatch(x, pattern));
        Console.WriteLine("Matching input: " + enteredDigits + " as regex: " + pattern);
        foreach (var n in matchingNames)
            Console.WriteLine(n);

在这个例子中,我有"26"作为输入,它过滤掉了除"bob"之外的所有内容。如果你去掉6,你会发现它会返回所有三个,因为它们的名字中都有a、b或c。

仅供参考,如果您希望它也与数字匹配,只需将数字添加到字典中的regex字符串值中即可。

我不太熟悉Windows Phone的开发,但我知道Windows Phone SDK中有联系人搜索功能。

你试过研究Contacts类的SearchAsyc方法吗?

它可能不适用于这种类型的搜索,但它似乎是一种常见的电话联系人搜索类型。

如果这不可能的话,我认为DLeh的解决方案会很好。

您可以使用这个C#代码,它将存储数据Trie数据结构,然后对其执行搜索。TrieNode表示Trie中的一个节点,它包含一个子节点的字典和一个布尔值,该布尔值指示该节点是否表示单词的末尾

   class TrieNode
{
     public Dictionary<char, TrieNode> children = new Dictionary<char, TrieNode>();
     public bool isEndOfWord;
     public string contact;
}
class Trie
{
public TrieNode root = new TrieNode();
public void Insert(string contact)
{
    TrieNode current = root;
    foreach (char c in contact)
    {
        if (!current.children.ContainsKey(c))
        {
            current.children.Add(c, new TrieNode());
        }
        current = current.children[c];
    }
    current.isEndOfWord = true;
    current.contact = contact;
}
public List<string> Search(string prefix)
{
    TrieNode current = root;
    List<string> contacts = new List<string>();
    foreach (char c in prefix)
    {
        if (!current.children.ContainsKey(c))
        {
            return new List<string>();
        }
        current = current.children[c];
    }
    GetAllContacts(current, contacts);
    return contacts;
}
private void GetAllContacts(TrieNode node, List<string> contacts)
{
    if (node.isEndOfWord)
    {
        contacts.Add(node.contact);
    }
    foreach (var child in node.children)
    {
        GetAllContacts(child.Value, contacts);
    }
}
}
class Program
{
static void Main(string[] args)
{
    // Add some contacts to the Trie
    Trie trie = new Trie();
    trie.Insert("John Smith");
    trie.Insert("Jane Smith");
    trie.Insert("Bob Johnson");
    trie.Insert("Mike Taylor");
    trie.Insert("Michael Jordan");
    // Search for contacts that match the prefix "Mi"
    List<string> contacts = trie.Search("Mi");
    foreach (string contact in contacts)
    {
        Console.WriteLine(contact);
    }
}
}

作为替代方案,您可以使用弹性搜索或Solr

我可以在0.5秒内过滤1500+个联系人

您可以创建与List<字符串>或者您可以使用Object like List<联系人>并且只是改变条件

FYI:java代码,但需要检查逻辑

import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
class Scratch {
    public static void main(String[] args) {
        List<String> contactList= new ArrayList<String>();
        contactList.add("Jason  Arnold 9875454454");
        contactList.add("Joshua Ferguson 789455482121");
        contactList.add("Sarah  Churchill 78452165982");
        contactList.add("Brandon    Walsh 78452121");
        contactList.add("Justin Cameron 452197821");
        contactList.add("Rebecca    Howard 784521983232");
        contactList.add("Trevor Smith 372753221");
        contactList.add("Heather    Fraser 9884562145");
        contactList.add("Caroline   Peters 6598421");
        contactList.add("Chloe  Lyman");

        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("2", "[2abc]");
        hm.put("3", "[3def]");
        hm.put("4", "[4ghi]");
        hm.put("5", "[5jkl]");
        hm.put("6", "[6mno]");
        hm.put("7", "[7pqrs]");
        hm.put("8", "[8tuv]");
        hm.put("9", "[9wxyz]");
        hm.put("1", "[1]");
        hm.put("0", "[0]");
        Instant startTime = Instant.now();
        String findContact = "3727"; // todo
        String regEx = "";
        for (int i = 0; i < findContact.length(); i++) {
            regEx = regEx + hm.get(findContact.charAt(i) + "");
        }
        String finalRegEx = "^"+regEx+".*$";
        System.out.println("!_!_" + finalRegEx);
        List<String> ll = contactList.stream().filter(s -> isMatched(s, finalRegEx))
                .collect(Collectors.toList());
                
        for (int i = 0; i < ll.size(); i++) {
            System.out.println("-->: " + ll.get(i));
        }
        Instant current = Instant.now();
        System.out.println("'nFound List size: " + ll.size());
        long milliseconds = (current.toEpochMilli() - startTime.toEpochMilli());
        System.out.println("'nmilliseconds: " + milliseconds);
    }
    private static boolean isMatched(String str, String finalRegEx) {
        String[] arrOfStr = str.split("''s");
        for (String a : arrOfStr) {
            if (a.toUpperCase().matches(finalRegEx.toUpperCase()))
                return true;
        }
        return false;
    }
}

结果:

Trevor Smith 372753221(电话号码以3727开头)

Heather Fraser 9884562145(姓氏与3727拨号键匹配)