java实现唯一可译码的判别_唯一可译码与即时码的判决

#include#include#include#includeusingnamespacestd;#defineISSAME        0#defineISPREFIX    1#defineNOTPREFIX    2#defineISUDC        0//唯一可译码#defineISRTC        1//即时码#defineNOTUDC        2//非唯一可译码typedef vectorpCharVector;/**************************************************************************//*判断chPrefix是否为chWord的前缀.*//**************************************************************************/intIsPrefix(constchar*chPrefix,constchar*chWord);/**************************************************************************//*往后缀码集合中插入不重复的键,*//*************************************************************************/boolPushBackUniqueValue(pCharVector&pCode,char*pValue);/**************************************************************************//*判断码字序列的类型,非回溯法*//**************************************************************************/intIsUDC(constpCharVector&pCode);/**************************************************************************//*回溯计算,如果不是唯一可译码则可以得到一串有歧义的码字序列(即有多种译法的

/* 序列),该序列用参数中的pInvalidSeqBuf返回,调用者需记得释放内存

/* 该方法的缺点是没有检测码字序列中是否有重复码字*//**************************************************************************/intIsUDC_Backtrace(constpCharVector&pCode,char**pInvalidSeqBuf);//#define TEST_BY_FILEintmain()

{

#ifdef TEST_BY_FILE

freopen("in","r",stdin);#endifpCharVector VCode;intnCodeNum;inti;charchContinue;do{

cout<

cin>>nCodeNum;

cout<

{//将输入读取到缓冲区stringstrBuffer;

cin>>strBuffer;//copy字符到动态数组中已进行比较char*pTemp=newchar[strBuffer.size()+1];

memcpy(pTemp,strBuffer.c_str(),sizeof(char)*(strBuffer.size()+1));

VCode.push_back(pTemp);

}char*pRetn=NULL;intnRetn=IsUDC_Backtrace(VCode,&pRetn);if(NOTUDC!=nRetn)

{

cout<

}else{

cout<

cout<

}if(ISRTC==nRetn)

{

cout<

}else{

cout<

}//清除内存delete[] pRetn;for(i=0; i

{

delete[] VCode.at(i);

}

VCode.clear();

cout<

cin>>chContinue;

}while(toupper(chContinue)=='Y');

#ifdef TEST_BY_FILE

fclose(stdin);#endifreturn0;

}intIsPrefix(constchar*chPrefix,constchar*chWord)

{

assert(chPrefix!=NULL&&chWord!=NULL);intnLenPrefix,nLenWord;

nLenPrefix=strlen(chPrefix);

nLenWord=strlen(chWord);//前缀长度大于整个词的长度,返回falseif(nLenPrefix>nLenWord)

{returnNOTPREFIX;

}intnRetn=memcmp(chPrefix,chWord,sizeof(char)*strlen(chPrefix));if(0==nRetn&&nLenPrefix==nLenWord)returnISSAME;if(0==nRetn)returnISPREFIX;returnNOTPREFIX;

}boolPushBackUniqueValue(pCharVector&pCode,char*pValue)

{

assert(pValue!=NULL);for(inti=0; i

{if(0==strcmp(pValue,pCode[i]))//有重复,直接返回returnfalse;

}

pCode.push_back(pValue);returntrue;

}intIsUDC(constpCharVector&pCode)

{

assert(pCode.size()!=0);//用于存放后缀码pCharVector CodePostfix;//第一轮比较,码字内部比较,得到第一个后缀码集合char*iter1,*iter2;inti,j;for(i=0; i

{

iter1=pCode.at(i);for(j=0; j

{//不比较自身if(i==j)continue;

iter2=pCode.at(j);intnRetn=IsPrefix(iter1,iter2);if(ISSAME==nRetn)returnNOTUDC;if(ISPREFIX==nRetn)

{//将iter2的后缀填入CodePostfixPushBackUniqueValue(CodePostfix,iter2+strlen(iter1));

}

}

}if(CodePostfix.size()==0)returnISRTC;//第二轮比较,比较后缀码集合中是否含有码字集合中的元素//有则返回NOTUDC,如果后缀码集合中没有再出现新元素了表明该码字是//UDC//指向当前集合在整个后缀码集合中的位置,也即是//前面所有后缀码的个数intnPointer=CodePostfix.size();//指向当前集合的大小intnNewAssembleSize=nPointer;do{

nPointer=CodePostfix.size();for(i=0; i

{

iter1=pCode.at(i);for(j=nPointer-nNewAssembleSize; j

{

iter2=CodePostfix.at(j);intnRetn=IsPrefix(iter1,iter2);if(nRetn==ISSAME)

{

cout<

}if(ISPREFIX==nRetn)

{//将iter2的后缀填入CodePostfixTempPushBackUniqueValue(CodePostfix,iter2+strlen(iter1));

}if(ISPREFIX==IsPrefix(iter2,iter1))

{//将iter1的后缀填入CodePostfixTempPushBackUniqueValue(CodePostfix,iter1+strlen(iter2));

}

}

}

nNewAssembleSize=CodePostfix.size()-nPointer;

}while(nNewAssembleSize!=0);

CodePostfix.clear();returnISUDC;

}/************************************************************************//*该函数是用来对每个pPostfix和原码字序列进行比较, 如果重复了则在pRetnBuf中

/* 返回本身.并返回1.否则如果没有得到新的后缀码的话返回0表示无重复*//*Stack用来存储递归中产生的后缀码集合,这样确保每次得到的后缀码不会重复

/* 防止进去死循环

/************************************************************************/intGetBacktraceSeq(constpCharVector&pCode,char*pPostfix,pCharVector&Stack,char**pRetnBuf)

{char*iter1;for(inti=0; i

{

iter1=pCode.at(i);intnRetn=IsPrefix(iter1,pPostfix);if(nRetn==ISSAME)

{//第一次进来的话由于是码字序列内部的比较,所以//肯定会遇到自己跟自己比较然后相等的情况,对该情况不允考虑if(Stack.size()==0)continue;*pRetnBuf=newchar[strlen(pPostfix)+1];

strcpy(*pRetnBuf,pPostfix);return1;

}if(ISPREFIX==nRetn)

{//新得到的后缀码已经重复了,跳过对他的处理if(PushBackUniqueValue(Stack,iter1)==false)continue;char*pTemp=NULL;//递归处理下一个后缀码if(GetBacktraceSeq(pCode,pPostfix+strlen(iter1),Stack,&pTemp)==0)

{*pRetnBuf=NULL;

Stack.pop_back();continue;

}

Stack.pop_back();//递归过程中遇到重复码字,算法应立即返回.//将自身和递归得到的后面的后缀码组合成一个歧义序列返回char*pNewTraceSeq=newchar[strlen(iter1)+strlen(pTemp)+1];

pNewTraceSeq[0]=0;

strcat(pNewTraceSeq,iter1);

strcat(pNewTraceSeq+strlen(iter1),pTemp);

delete[] pTemp;*pRetnBuf=pNewTraceSeq;return1;

}if(ISPREFIX==IsPrefix(pPostfix,iter1))

{if(PushBackUniqueValue(Stack,pPostfix)==false)continue;char*pTemp=NULL;if(GetBacktraceSeq(pCode,iter1+strlen(pPostfix),Stack,&pTemp)==0)

{*pRetnBuf=NULL;

Stack.pop_back();continue;

}

Stack.pop_back();char*pNewTraceSeq=newchar[strlen(pPostfix)+strlen(pTemp)+1];

pNewTraceSeq[0]=0;

strcat(pNewTraceSeq,pPostfix);

strcat(pNewTraceSeq+strlen(pPostfix),pTemp);

delete[] pTemp;*pRetnBuf=pNewTraceSeq;return1;

}

}return0;

}/*************************************************************************//*用递归的方法实现唯一可译码的判决,当码字序列不是唯一可译码时,输出有歧义的

/* 码字序列

/************************************************************************/intIsUDC_Backtrace(constpCharVector&pCode,char**pInvalidSeqBuf)

{

assert(pCode.size()!=0);//用于存放后缀码pCharVector CodePostfix;//第一轮比较,码字内部比较,得到第一个后缀码集合char*iter1,*iter2;inti,j;

pCharVector Stack;for(i=0; i

{

iter1=pCode.at(i);char*pTemp=NULL;intnRetn=GetBacktraceSeq(pCode,iter1,Stack,&pTemp);if(nRetn==1)

{*pInvalidSeqBuf=pTemp;returnNOTUDC;

}

}*pInvalidSeqBuf=NULL;returnISUDC;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值