644 - Immediate Decodability

 

  Immediate Decodability 

An encoding of a set of symbols is said to be immediately decodable if no code for one symbol is the prefix of a code for another symbol. We will assume for this problem that all codes are in binary, that no two codes within a set of codes are the same, that each code has at least one bit and no more than ten bits, and that each set has at least two codes and no more than eight.

 


Examples: Assume an alphabet that has symbols {A, B, C, D}

 


The following code is immediately decodable:

 


A:01 B:10 C:0010 D:0000

 


but this one is not:

 


A:01 B:10 C:010 D:0000 (Note that A is a prefix of C)

 

Input 

Write a program that accepts as input a series of groups of records from a data file. Each record in a group contains a collection of zeroes and ones representing a binary code for a different symbol. Each group is followed by a single separator record containing a single 9; the separator records are not part of the group. Each group is independent of other groups; the codes in one group are not related to codes in any other group (that is, each group is to be processed independently).

 

Output 

For each group, your program should determine whether the codes in that group are immediately decodable, and should print a single output line giving the group number and stating whether the group is, or is not, immediately decodable.

 


The Sample Input describes the examples above.

 

Sample Input 

 

01
10
0010
0000
9
01
10
010
0000
9

 

Sample Output 

Set 1 is immediately decodable
Set 2 is not immediately decodable

很简单,题目就是判断是否是前缀码,学数据结构知道哈夫曼树编码原理应该都明白,没办法无聊了只能刷一下水题呵呵,下面我贴一下我的水代码:
看一下运行情况,速度太慢是因为用了STL的缘故:


#include <iostream>
#include <algorithm>
#include <vector>
//#include "boost/foreach.hpp"
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
    int i = 1;
    string str;
    vector<string > v;
    while(cin>>str)
    {
        if(str == "9")
        {
          //  BOOST_FOREACH(string t,v){ cout<<t<<endl;}
            int temp = i;
            typedef vector<string>::iterator Itype;
            for(Itype It = v.begin(); It != v.end()&& temp ==i ; It++)
            {
                for(Itype It2 = It+1; It2!= v.end() ; ++It2)
                {
                    Itype str1It = It , str2It = It2;
                    if(str1It->length() > str2It->length()) swap(str1It,str2It);

                    pair<string::iterator,string::iterator> p =
                            mismatch(str1It->begin(),str1It->end(),str2It->begin());
                    if(p.first == str1It->end())
                    {
                        cout<<"Set "<<i++<<" is not immediately decodable"<<endl;
                        break;
                    }
                }
            }
            if(temp == i)
                cout<<"Set "<<i++<<" is immediately decodable"<<endl;
            v.clear();
        }
        else
        {
            v.push_back(str);
        }

    }
    cin>>i;
    return 0;
}

 

 这是我在网上找到的一份代码,自己构建了一棵树,可能想得有点复杂了但是挺不错的,测试之后没有AC,但是想法是没错的,原帖的代码在下面,
我基于这个思想自己用ANCI C写了一遍http://www.cnblogs.com/UnGeek/archive/2012/06/25/2561560.html,发现运行时间是0.028s,的确很快,比下面第三份代码还快
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
using namespace std;
const int kMaxn(10007);

bool cmp(const string &sa,const string &sb)
{
    return (sa.size()>sb.size() || (sa.size()==sb.size() && sa<sb));
}

struct TreeNode
{
    TreeNode():left_(NULL),right_(NULL) {}

    TreeNode *left_,*right_;
};
class Trie
{
    public:
        Trie()
        {
            father_=new TreeNode;
        }
        bool Insert(const string &s)
        {
            bool re(false);
            TreeNode *p(father_);
            for(int i=0;i<s.size();i++)
            {
                if(s[i]=='0' && !p->left_)
                {
                    p->left_=new TreeNode;
                    if(i==s.size()-1)
                        re=true;
                }
                else if(s[i]=='1' && !p->right_)
                {
                    p->right_=new TreeNode;
                    if(i==s.size()-1)
                        re=true;
                }
                if(s[i]=='0')
                    p=p->left_;
                else
                    p=p->right_;
            }
            return re;
        }

    private:
        TreeNode *father_;
};

int main()
{
    /*
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    //*/

    int T(0);
    string t;
    while(cin>>t)
    {
        vector<string> r;
        while(t!="9")
        {
            r.push_back(t);
            cin>>t;
        }

        sort(r.begin(),r.end(),cmp);
        Trie trie;
        bool success(true);
        for(vector<string>::iterator i=r.begin();i!=r.end();i++)
            if(!trie.Insert(*i))
            {
                success=false;
                break;
            }

        T++;
        if(success)
            cout<<"Set "<<T<<" is immediately decodable"<<endl;
        else cout<<"Set "<<T<<" is not immediately decodable"<<endl;
    }

    return 0;
}

 下面是第三份代码,也很不错的,值得学习

View Code 

#include<stdio.h>
#include<string.h>
char st[200][20];
int judge(int top)
{
    int i, j, k;
    for(i = 0;i < top; i++)
    {
        for(j = 0;j < top; j++)
        {
            if((strlen(st[i]) < strlen(st[j])) && (i != j))
            {
                for(k = 0;k < strlen(st[i]); k++)
                if(st[i][k] != st[j][k])
                break;
                if(k == strlen(st[i]))
                return 0;
            }
        }
    }
    return 1;
}
int main()
{
    int top = 0, j = 1;
    while(gets(st[top]) != NULL)
    {
        if(st[top][0] == '9')
        {
            if(judge(top))
            printf("Set %d is immediately decodable\n",j++);
            else
            printf("Set %d is not immediately decodable\n",j++);
            top = 0;
        }
        else
        top++;
    }
    return 0;
}

 


posted @ 2012-06-24 20:54  godjob  Views(301)  Comments(0Edit  收藏  举报