zoukankan      html  css  js  c++  java
  • (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/

  • 相关阅读:
    Tomcat线程参数
    CDH平台规划注意事项
    python 不同数据类型的序列化
    Python 中__new__方法详解及使用
    线程生命周期
    如何在JAVA中每隔一段时间执行一段程序
    手动开启是事务提交回滚
    MySQL数据类型转换函数CAST与CONVERT的用法
    mybatis插入是返回主键id
    解决dubbo注册zookepper服务IP乱入问题的三种方式
  • 原文地址:https://www.cnblogs.com/Bella2017/p/11153231.html
Copyright © 2011-2022 走看看