阿里校招编程题第一题 字典查询

使用字典树Trie存储

#include 
#include 
#include 
#include 
using namespace std;
class TrieNode {
public:
    TrieNode() {
        isWord = false;
        memset(next, 0, sizeof(next));
    }

    bool isWord;
    TrieNode* next[26];
};
class Trie {
public:
    Trie() {
        root = new TrieNode();
    }
    // Inserts a word into the trie.
    void insert(string word) {
        TrieNode *node = root;
        for(int i = 0; i < word.size(); i++)
        {
            int index = word[i] - 'a';
            if(node->next[index] == NULL){
                node->next[index] = new TrieNode();
            }
            node = node->next[index];
        }
        node->isWord = true;
    }
    // Returns if the word is in the trie.
    bool search(string word) {
        TrieNode *node = root;
        for(int i = 0; i < word.size(); i++)
        {
            int index = word[i] - 'a';
            if(node->next[index] == NULL)
                return false;
            node = node->next[index];
        }
        if(node->isWord)
            return true;
        else
            return false;
    }
    // Returns if there is any word in the trie
    // that starts with the given prefix.
    bool startsWith(string prefix) {
        TrieNode *node = root;
        for(int i = 0; i < prefix.size(); i++)
        {
            int index = prefix[i] - 'a';
            if(node->next[index] == NULL)
                return false;
            node = node->next[index];
        }
        return true;
    }
private:
    TrieNode* root;
};
int flag;
int minCutSteps;
vector curPath;
vector resultPath;
void copyVector(vector &src, vector &target) {
    target.clear();
    for (int i = 0; i < src.size(); i++) {
        target.push_back( src[i] );
    }
}
void mincutHelper(string &str, Trie *trie, int curIdx, int steps, vector &path) {
    if ( curIdx >= str.length() ) {
        flag = true;
        // cout << "found steps: " << steps << endl;
        if (minCutSteps > steps) {
            minCutSteps = steps;
            copyVector(path, resultPath);
        }
        return;
    }

    //start with curIdx
    for (int wordRIdx = curIdx; wordRIdx < str.length(); wordRIdx++) {
        int curStrLen = wordRIdx - curIdx + 1;
        string subStr = str.substr(curIdx, curStrLen);
        if ( !trie->startsWith(subStr) )
            break;
        else {
            if ( trie->search(subStr) ) {
                path.push_back(wordRIdx + 1);
                mincutHelper(str, trie, wordRIdx + 1, steps + 1, path);
                path.pop_back();
            }
        }
    }
}
// void showVector(vector &v) {
//     for (int i = 0; i < v.size(); i++)
//         cout << v[i] << " ";
//     cout << endl;
// }
void mincut(string &str, set& dict) {
    Trie *trie = new Trie();
    set::iterator iter;
    for (iter = dict.begin(); iter != dict.end(); iter++) {
        trie->insert( (string)*iter );
    }
    int strLen = str.length();
    flag = false;
    minCutSteps = strLen + 1;
    mincutHelper(str, trie, 0, 0, curPath);
    if (flag) {
        // cout << minCutSteps << endl;
        int startIdx = 0;
        // showVector(resultPath);
        for (int i = 0; i < resultPath.size(); i++) {
            int curLen = resultPath[i] - startIdx;
            if (startIdx > 0)
                cout << " ";
            cout << str.substr(startIdx, curLen);
            startIdx = resultPath[i];
        }
        cout << endl;
    } else {
        cout << "n/a" << endl;
    }
}
/*
ilikealibaba
6
i
like
ali
liba
baba
alibaba
*/
int main(int argc, char const *argv[])
{
    string strS;
    string dictStr;
    int nDict;
    set dict;
    cin >> strS;
    cin >> nDict;
    for (int i = 0; i < nDict; i++) {
        cin >> dictStr;
        dict.insert(dictStr);
    }
    mincut(strS, dict);
    return 0;
}

更新版本

如果strS比较长,nDict集比较少,优先采用字典存在长度迭代

#include <iostream>
#include <string>
#include <set>
#include <vector>
#include <algorithm>

using namespace std;

class TrieNode {
public:
    TrieNode() {
        isWord = false;
        memset(next, 0, sizeof(next));
    }

    bool isWord;
    TrieNode* next[26];
};

class Trie {
public:
    Trie() {
        root = new TrieNode();
    }

    // Inserts a word into the trie.
    void insert(string word) {
        TrieNode *node = root;
        for(int i = 0; i < word.size(); i++)
        {
            int index = word[i] - 'a';
            if(node->next[index] == NULL){
                node->next[index] = new TrieNode();
            }
            node = node->next[index];
        }
        node->isWord = true;
    }

    // Returns if the word is in the trie.
    bool search(string word) {
        TrieNode *node = root;
        for(int i = 0; i < word.size(); i++)
        {
            int index = word[i] - 'a';
            if(node->next[index] == NULL)
                return false;
            node = node->next[index];
        }

        if(node->isWord)
            return true;
        else
            return false;
    }

    // Returns if there is any word in the trie
    // that starts with the given prefix.
    bool startsWith(string prefix) {
        TrieNode *node = root;
        for(int i = 0; i < prefix.size(); i++)
        {
            int index = prefix[i] - 'a';
            if(node->next[index] == NULL)
                return false;
            node = node->next[index];
        }
        return true;
    }

private:
    TrieNode* root;
};


int flag;
int minCutSteps;
vector<int> curPath;
vector<int> resultPath;
vector<int> strLenItems;

void copyVector(vector<int> &src, vector<int> &target) {
    target.clear();
    for (int i = 0; i < src.size(); i++) {
        target.push_back( src[i] );
    }
}

void mincutHelper(string &str, Trie *trie, int curIdx, int steps, vector<int> &path) {
    if ( curIdx >= str.length() ) {
        flag = true;
        // cout << "found steps: " << steps << endl;
        if (minCutSteps > steps) {
            minCutSteps = steps;
            copyVector(path, resultPath);
        }
        return;
    }



    /*
    **version 1
    //start with curIdx
    for (int wordRIdx = curIdx; wordRIdx < str.length(); wordRIdx++) {
        int curStrLen = wordRIdx - curIdx + 1;
        string subStr = str.substr(curIdx, curStrLen);
        if ( !trie->startsWith(subStr) )
            break;
        else {
            if ( trie->search(subStr) ) {
                path.push_back(wordRIdx + 1);
                mincutHelper(str, trie, wordRIdx + 1, steps + 1, path);
                path.pop_back();
            }
        }
    }
    */


    // iter with word's length
    for (int i = 0; i < strLenItems.size(); i++) {
        if ( i > 0 && strLenItems[i] == strLenItems[i - 1])
            continue;
        if ( curIdx + strLenItems[i] > str.length() )
            break;
        string subStr = str.substr(curIdx, strLenItems[i]);

        if ( !trie->startsWith(subStr) )
            break;
        else {
            if ( trie->search(subStr) ) {
                path.push_back( curIdx + strLenItems[i] );
                mincutHelper(str, trie, curIdx + strLenItems[i], steps + 1, path);
                path.pop_back();
            }
        }        
    }
}

// void showVector(vector<int> &v) {
//     for (int i = 0; i < v.size(); i++)
//         cout << v[i] << " ";
//     cout << endl;
// }

void mincut(string &str, set<string>& dict) {
    Trie *trie = new Trie();
    set<string>::iterator iter;
    for (iter = dict.begin(); iter != dict.end(); iter++) {
        trie->insert( (string)*iter );
        strLenItems.push_back( (*iter).length() );
    }
    sort(strLenItems.begin(), strLenItems.end());

    int strLen = str.length();
    flag = false;
    minCutSteps = strLen + 1;

    mincutHelper(str, trie, 0, 0, curPath);

    if (flag) {
        // cout << minCutSteps << endl;
        int startIdx = 0;
        // showVector(resultPath);
        for (int i = 0; i < resultPath.size(); i++) {
            int curLen = resultPath[i] - startIdx;
            if (startIdx > 0)
                cout << " ";
            cout << str.substr(startIdx, curLen);
            startIdx = resultPath[i];
        }
        cout << endl;
    } else {
        cout << "n/a" << endl;
    }
}

/*
ilikealibaba
6
i
like
ali
liba
baba
alibaba
*/
int main(int argc, char const *argv[])
{
    string strS;
    string dictStr;
    int nDict;
    set<string> dict;

    cin >> strS;
    cin >> nDict;
    for (int i = 0; i < nDict; i++) {
        cin >> dictStr;
        dict.insert(dictStr);
    }

    mincut(strS, dict);

    return 0;
}
#阿里巴巴#
全部评论
666,笔试能手写字典树,已经是大神了
点赞 回复 分享
发布于 2017-08-26 02:10
666
点赞 回复 分享
发布于 2017-08-25 23:45
这么长你写了多久?为什么我暴力试一下就过了。。。
点赞 回复 分享
发布于 2017-08-25 22:37

相关推荐

10-13 22:56
门头沟学院 C++
rt,鼠鼠的浪潮网签明天过期,鼠鼠是山东人,好像自己也能接受。之前的面试大厂基本挂干净了,剩下小米二面后在泡,问了下面试官没有挂,但要泡。还有海信似乎也通过了,不过在深圳,鼠鼠也不是很想去。其它还有一些公司应该陆陆续续还有一些面试,现在有些纠结是直接签了还是再等再面呢?大佬们能不能给鼠鼠提一些意见,万分感谢!!!
牛客78696106...:浪潮可不是开摆,当初我还是开发的时候我组长跟我说他们组有段时间天天1,2点走,早上5点就来,全组肝出来心肌炎,浪潮挣钱省立花可不是说说,当然也看部门,但是浪潮普遍就那dio样,而且你算下时薪就知道不高,没事也是9点半走,不然算你旷工
投递小米集团等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务