ZOJ1166

ZOJ1166-Anagram Checker

算法分析:

一、数据结构


二、数据读取与预处理

1.读取字典(无需排序)

2,.读取短语(要排序)


三、统计每个字母出现次数

构造变位词时,只关注有哪些字母,以及字母频数。统计结果存放在数组中。


四、采用回溯算法,构造变位词

1.判断短语中字母是否构造完毕

2.使用回溯算法,构造变位词短语


ps:对字典剪枝优化,若被测试字符串不包含字典中某条目,则该条目可被剪枝,加速搜索过程。

#include 
#include 
#include 
#include 
#include 
using namespace std;
/**
dictionary words
**/
string word[2000];
/**
Word in phrase
**/
string sword[20];
/**
phrase sorted in alphabetic order
**/
string phrase;
string oldphrase;
/**
Number of dictionary words, number of words in phrase.
**/
int n=0, m;
/**
Count of letters in phrase.
**/
int cont[26];
void findAnagram(int idx, vector &v)
{
     bool find=true;
     for (int i=0; i<26; i++) 
     {
       if (cont[i] > 0)
        { find = false;  break; }
     }
     if (find)
     {
        string s;
        for (int i=0; i 0) s += " ";
            s += v[i];
        }
        if (s != phrase) cout<>sword[m];
          if ("#" == sword[m++]) break;
          if (cin.get() == '/n')
          {
          /**
          Keep the old phrase for output.
          **/
             oldphrase = "";
             for (int i=0; i v;
             findAnagram(0, v);
             m = 0;
          }
    }
}
#include  
#include  
#include  
#include  
#include  
#include  
  
using namespace std;  
  
namespace  
{  
    set words;  
    int src[26];  
    vector dict;  
    string line;  
    vector stack;  
  
    bool match(const string &s)  
    {  
        int temp[26];  
        memset(temp, 0, sizeof(temp));  
        for (size_t i = 0; i < s.size(); i++)  
            temp[s[i] - 'A']++;  
        for (int i = 0; i < 26; i++)  
            if (temp[i] && temp[i] > src[i])  
                return false;  
        return true;  
    }  
  
    void forward(const string &s)  
    {  
        for (size_t i = 0; i < s.size(); i++)  
            src[s[i] - 'A']--;  
    }  
  
    void back(const string &s)  
    {  
        for (size_t i = 0; i < s.size(); i++)  
            src[s[i] - 'A']++;  
    }  
  
    bool find()  
    {  
        for (int i = 0; i < 26; i++)  
            if (src[i])  
                return false;  
        return true;  
    }  
  
    void dfs()  
    {  
        if (find())  
        {  
            cout << line << " =";  
            for (size_t i = 0; i < stack.size(); i++)  
                cout << " " << stack[i];  
            cout << endl;  
            return;  
        }  
  
        for (size_t i = 0; i < dict.size(); i++)  
            if (stack.empty() || (!stack.empty() && dict[i] > stack.back()))  
                if (words.find(dict[i]) == words.end() && match(dict[i]))  
                {  
                    forward(dict[i]);  
                    stack.push_back(dict[i]);  
                    dfs();  
                    stack.pop_back();  
                    back(dict[i]);  
                }  
    }  
}  
  
int main()  
{  
    string word;  
    while (cin >> word, word != "#")  
        dict.push_back(word);  
    cin >> ws;  
    while (getline(cin, line), line != "#")  
    {  
        words.clear();  
        istringstream ism(line);  
        while (ism >> word)  
            words.insert(word);  
        memset(src, 0, sizeof(src));  
        for (size_t i = 0; i < line.size(); i++)  
            if (line[i] >= 'A' && line[i] <= 'Z')  
                src[line[i] - 'A']++;  
  
        stack.clear();  
        dfs();  
    }  
    return 0;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值