(Greedy approach)Find longest word in dictionary that is a subsequence of a given string

Find longest word in dictionary that is a subsequence of a given string

贪心算法:

1)将D按字符串的长度,从长到短排序。

2)从D[0]开始,尝试找到这个字符串(这里叫word)是S的子序列。

3)从word[0]开始,遍历S,尝试在S中找到这个字符;一旦找到,接着从当前位置的后面找word[1]是否在S中,以此类推。

// pch.cpp: 与预编译标头对应的源文件;编译成功所必需的

#include "pch.h"

// 一般情况下,忽略此文件,但如果你使用的是预编译标头,请保留它。
#include<stdio.h>
#include<stdlib.h>
#include<unordered_map>
#include<iostream>
#include<string>
#include<assert.h>
#include<set>

using namespace std;
struct length_more {
    bool operator()(const string& s1, const string& s2) {
        if (s1.length() == s2.length())
            return true;
        return s1.length() > s2.length();
    }
};

/* 错误写法:
string find(string MainWord, set<string, length_more> WordPool) {
    set<string>::iterator it;
    string res="";
    //bool notBreak = true;  //判断循环是否继续的标志
    for (it = WordPool.begin(); it != WordPool.end(); ++it) {
        int i = 0;
        string word = *it;
        char w;
        for (int j = 0; j < word.length(); ++j) {
            for (;i < MainWord.length(); ++i ) {
                if (word[j] == MainWord[i]) {
                    res += word[j];
                    w = word[j];
                    break;
                }
            }
            if (word[j] != w)
                break;
            else
                i = 0;
        }
        if (WordPool.count(res)) {

            break;
        }
        else {
            res.clear();
        }
    }
    return res;
}


*/

//正确:
string find(string MainWord, set<string, length_more> WordPool) {
    set<string>::iterator it;
    string res = "";

    for (it = WordPool.begin(); it != WordPool.end(); ++it) {
        int i = 0;
        string word = *it;
        bool flag = false;
        for (int j = 0; j < word.length(); ++j) {

            flag = false;
            for (;i < MainWord.length(); ++i) {
                if (word[j] == MainWord[i]) {
                    res += word[j];
                    flag = true;
                    break;
                }
            }
            if (!flag)
                break;
        }
        if (flag)
            return res;
        else
            res.clear();

    }
    if(res.length()==0) return "";
}


int main() {
    string MainWord = "abppplee";
    set<string, length_more> WordPool;
    WordPool.insert("able");
    WordPool.insert("ale");
    WordPool.insert("apple");
    WordPool.insert("bale");
    WordPool.insert("kangaroo");
    cout << find(MainWord, WordPool) << endl;
    //set<string>::iterator it;
    //for (it = WordPool.begin(); it != WordPool.end(); it++)
    //    cout << (*it) << endl;
    return 0;
}

 

改进的贪心算法:将MainWord 插入到map中,记录每个元素对应得位置。感觉改进的这个更麻烦了,需要用到multimap来记录一个键值(字符)对应的多个位置,然后再用equal_range() 把这些位置给找到,循环遍历一遍:若找到比前一个字符索引大的,就看下一个字符,否则还要试这个字符的下一个索引位置。

 

// pch.cpp: 与预编译标头对应的源文件;编译成功所必需的

#include "pch.h"

// 一般情况下,忽略此文件,但如果你使用的是预编译标头,请保留它。
#include<stdio.h>
#include<stdlib.h>
#include<map>
#include<iostream>
#include<string>
#include<assert.h>
#include<set>

using namespace std;

struct more{
    bool operator()(const string& s1, const string& s2) {
        if (s1.length() == s2.length())
            return true;
        else
            return s1.length() > s2.length();
    }
};

string find(string MainWord, set<string, more> WordPool) {
    multimap<char, int> mp;
    int i = 0;
    string res="";

    for (char a : MainWord) {
        mp.insert(make_pair(a, i));
        ++i;
    }

    
    for (auto a : WordPool) {
        int k = -1;
        pair<multimap<char, int>::iterator, multimap<char, int>::iterator> it;
        bool flag;

        for (auto b : a) {
            flag = false;
             it = mp.equal_range(b);
             multimap<char, int>::iterator i = it.first;
             for ( ;i != it.second; ) {
                 if (i->second > k) {
                     k = i->second;
                     res += i->first;
                     flag = true;
                     break;
                 }
                 else
                     ++i;
             }
        }
        if (!flag) res.clear();
        else 
            return res;
    }
    if(res.length()==0) return "";
    
}


int main() {
    string MainWord = "abppplee";
    set<string, more> WordPool;
    WordPool.insert("able");
    WordPool.insert("ale");
    WordPool.insert("apple");
    WordPool.insert("bale");
    WordPool.insert("kangaroo");
    cout << find(MainWord, WordPool) << endl;
    //set<string>::iterator it;
    //for (it = WordPool.begin(); it != WordPool.end(); it++)
    //    cout << (*it) << endl;
    return 0;
}

multimap: 

http://www.cplusplus.com/reference/map/multimap/equal_range/

posted @ 2019-07-08 19:27  爱学英语的程序媛  阅读(248)  评论(0编辑  收藏  举报