#include

#include

#include

#include

using namespace std;

#define ISSAME 0

#define ISPREFIX 1

#define NOTPREFIX 2

#define ISUDC 0 //唯一可译码

#define ISRTC 1 //即时码

#define NOTUDC 2 //非唯一可译码

typedef vector pCharVector;

/**************************************************************************/

/* 判断chPrefix是否为chWord的前缀.*/

/**************************************************************************/

int IsPrefix(const char* chPrefix,const char* chWord);

/**************************************************************************/

/* 往后缀码集合中插入不重复的键,*/

/*************************************************************************/

bool PushBackUniqueValue(pCharVector& pCode,char* pValue);

/**************************************************************************/

/* 判断码字序列的类型,非回溯法*/

/**************************************************************************/

int IsUDC(const pCharVector& pCode);

/**************************************************************************/

/* 回溯计算,如果不是唯一可译码则可以得到一串有歧义的码字序列(即有多种译法的

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

/* 该方法的缺点是没有检测码字序列中是否有重复码字*/

/**************************************************************************/

int IsUDC_Backtrace(const pCharVector& pCode,char** pInvalidSeqBuf);

//#define TEST_BY_FILE

int main()

{

#ifdef TEST_BY_FILE

freopen("in","r",stdin);

#endif

pCharVector VCode;

int nCodeNum;

int i;

char chContinue;

do

{

cout<

cin>>nCodeNum;

cout<

for (i = 0; i < nCodeNum; i++)

{

//将输入读取到缓冲区

string strBuffer;

cin>>strBuffer;

//copy字符到动态数组中已进行比较

char* pTemp = new char[strBuffer.size() + 1];

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

VCode.push_back(pTemp);

}

char * pRetn = NULL;

int nRetn = IsUDC_Backtrace(VCode,&pRetn);

if (NOTUDC != nRetn)

{

cout<

}

else

{

cout<

cout<

}

if (ISRTC == nRetn)

{

cout<

}

else

{

cout<

}

//清除内存

delete[] pRetn;

for (i = 0; i < VCode.size(); i++)

{

delete[] VCode.at(i);

}

VCode.clear();

cout<

cin>>chContinue;

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

#ifdef TEST_BY_FILE

fclose(stdin);

#endif

return 0;

}

int IsPrefix(const char* chPrefix,const char* chWord)

{

assert(chPrefix != NULL && chWord != NULL);

int nLenPrefix,nLenWord;

nLenPrefix = strlen(chPrefix);

nLenWord = strlen(chWord);

//前缀长度大于整个词的长度,返回false

if (nLenPrefix > nLenWord)

{

return NOTPREFIX;

}

int nRetn = memcmp(chPrefix,chWord,sizeof(char) * strlen(chPrefix));

if(0 == nRetn && nLenPrefix == nLenWord) return ISSAME;

if(0 == nRetn) return ISPREFIX;

return NOTPREFIX;

}

bool PushBackUniqueValue(pCharVector& pCode,char* pValue)

{

assert(pValue != NULL);

for (int i = 0; i < pCode.size(); i++)

{

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

return false;

}

pCode.push_back(pValue);

return true;

}

int IsUDC(const pCharVector& pCode)

{

assert(pCode.size() != 0);

//用于存放后缀码

pCharVector CodePostfix;

//第一轮比较,码字内部比较,得到第一个后缀码集合

char *iter1,*iter2;

int i,j;

for (i = 0; i < pCode.size(); i++)

{

iter1 = pCode.at(i);

for (j = 0; j < pCode.size(); j++)

{

//不比较自身

if(i == j) continue;

iter2 = pCode.at(j);

int nRetn = IsPrefix(iter1,iter2);

if(ISSAME == nRetn) return NOTUDC;

if (ISPREFIX == nRetn)

{

//将iter2的后缀填入CodePostfix

PushBackUniqueValue(CodePostfix,iter2+strlen(iter1));

}

}

}

if(CodePostfix.size() == 0) return ISRTC;

//第二轮比较,比较后缀码集合中是否含有码字集合中的元素

//有则返回NOTUDC,如果后缀码集合中没有再出现新元素了表明该码字是

//UDC

//指向当前集合在整个后缀码集合中的位置,也即是

//前面所有后缀码的个数

int nPointer = CodePostfix.size();

//指向当前集合的大小

int nNewAssembleSize = nPointer;

do

{

nPointer = CodePostfix.size();

for (i = 0; i < pCode.size(); i++)

{

iter1 = pCode.at(i);

for (j = nPointer - nNewAssembleSize; j < nPointer; j++)

{

iter2 = CodePostfix.at(j);

int nRetn = IsPrefix(iter1,iter2);

if (nRetn == ISSAME)

{

cout<

//两个码字相同,返回false

return NOTUDC;

}

if (ISPREFIX == nRetn)

{

//将iter2的后缀填入CodePostfixTemp

PushBackUniqueValue(CodePostfix,iter2+strlen(iter1));

}

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

{

//将iter1的后缀填入CodePostfixTemp

PushBackUniqueValue(CodePostfix,iter1+strlen(iter2));

}

}

}

nNewAssembleSize = CodePostfix.size() - nPointer;

} while(nNewAssembleSize != 0);

CodePostfix.clear();

return ISUDC;

}

/************************************************************************/

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

/* 返回本身.并返回1.否则如果没有得到新的后缀码的话返回0表示无重复*/

/* Stack用来存储递归中产生的后缀码集合,这样确保每次得到的后缀码不会重复

/* 防止进去死循环

/************************************************************************/

int GetBacktraceSeq(const pCharVector& pCode,char* pPostfix,pCharVector& Stack,char** pRetnBuf)

{

char* iter1;

for (int i = 0; i < pCode.size(); i++)

{

iter1 = pCode.at(i);

int nRetn = IsPrefix(iter1,pPostfix);

if (nRetn == ISSAME)

{

//第一次进来的话由于是码字序列内部的比较,所以

//肯定会遇到自己跟自己比较然后相等的情况,对该情况不允考虑

if(Stack.size() == 0) continue;

*pRetnBuf = new char[strlen(pPostfix) + 1];

strcpy(*pRetnBuf,pPostfix);

return 1;

}

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 = new char[strlen(iter1) + strlen(pTemp) + 1];

pNewTraceSeq[0] = 0;

strcat(pNewTraceSeq,iter1);

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

delete[] pTemp;

*pRetnBuf = pNewTraceSeq;

return 1;

}

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 = new char[strlen(pPostfix) + strlen(pTemp) + 1];

pNewTraceSeq[0] = 0;

strcat(pNewTraceSeq,pPostfix);

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

delete[] pTemp;

*pRetnBuf = pNewTraceSeq;

return 1;

}

}

return 0;

}

/*************************************************************************/

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

/* 码字序列

/************************************************************************/

int IsUDC_Backtrace(const pCharVector& pCode, char** pInvalidSeqBuf)

{

assert(pCode.size() != 0);

//用于存放后缀码

pCharVector CodePostfix;

//第一轮比较,码字内部比较,得到第一个后缀码集合

char *iter1,*iter2;

int i,j;

pCharVector Stack;

for (i = 0; i < pCode.size(); i++)

{

iter1 = pCode.at(i);

char* pTemp = NULL;

int nRetn = GetBacktraceSeq(pCode,iter1,Stack,&pTemp);

if(nRetn == 1)

{

*pInvalidSeqBuf = pTemp;

return NOTUDC;

}

}

*pInvalidSeqBuf = NULL;

return ISUDC;

}

唯一可译码的判定方法matlab,用c++编写程序判定唯一可译码?相关推荐

  1. c语言判定三角形流程图_c语言编写程序:输入三角形的三条边,判断它们能否构成三角形,若能则指出何种三角形。...

    展开全部 &&.||运算符使用错误32313133353236313431303231363533e58685e5aeb931333431353362,代码为: #include in ...

  2. 1.编写程序判定给定年份是否为闰年。年份由键盘输入。

    #include <iostream> using namespace std; int main() {     int year;     bool run;          cou ...

  3. MATLAB学习笔记:程序流程控制

    这里介绍一下如何利用matlab语言来编写程序,也就是程序控制. 一. 顺序结构程序 1,程序是用某种计算机能够理解并且能够执行的语言来描述的解决问题的方法和步骤.程序设计并不是简单的编写代码,而是反 ...

  4. 时滞电力系统matlab,基于Wirtinger不等式的时滞电力系统稳定性判定方法

    基于Wirtinger不等式的时滞电力系统稳定性判定方法 [专利摘要]本发明公开了一种基于Wirtinger不等式的时滞电力系统稳定性判定方法,用于分析电力系统所能承受的最大时滞稳定裕度.该方法的具体 ...

  5. 直接法 matlab,解线性方程组直接方法matlab用法.doc

    解线性方程组直接方法matlab用法 在这章中我们要学习线性方程组的直接法,特别是适合用数学软件在计算机上求解的方法. 2.1 方程组的逆矩阵解法及其MATLAB程序 2.1.3 线性方程组有解的判定 ...

  6. matlab中fminunc函数使用方法,[分享]无约束非线性规划函数\fminunc函数使用方法(MATLAB)...

    [分享]无约束非线性规划函数\fminunc函数使用方法(MATLAB) 无约束非线性规划函数\fminunc函数使用方法(MATLAB) %用于求解无约束非线性规划的函数有:fminsearch和f ...

  7. 7.边缘检测:2D运算——Canny的不同结果、单个2D边缘检测滤波器、实现边缘3种方法Matlab实战_3

    目录 Canny的不同结果 单个2D边缘检测滤波器 实现边缘3种方法Matlab实战 第一种 图像差异 第二种 Canny边缘检测器 第三种 高斯拉普拉斯变换 Canny的不同结果 右边的图像是左边的 ...

  8. matlab解方程组方法,第二章解线性方程组的直接方法matlab用法

    第二章解线性方程组的直接方法matlab用法 第二章 解线性方程组的直接方法的 MATLAB 程序24. 在这章中我们要学习线性方程组的直接法,特别是适 合用数学软件在计算机上求解的方法. 2.1 方 ...

  9. 0.618方法matlab流程图,0.618法的matlab实现

    (3)从上述计算结果可以看出,利用 MATLAB 实现的黄金分割法,通过 14 次 迭代可以满足收敛精度要求,并且计算结果和理论结果基本一致,误差为 (1.0013) (1) 0....... 暂无评 ...

最新文章

  1. Linux shell 自启动脚本写法
  2. Java并发编程之线程同步
  3. 【视频课】一课掌握模型设计核心理论与实战技巧
  4. 使用Eclipse创建maven项目
  5. URL 地址含汉字无法解析问题
  6. salt grains详解
  7. python进程池和线程池_Python中的进程池与线程池(包含代码)
  8. 量化策略回测DCCV2
  9. JMeter java.lang.OutOfMemoryError: PermGen space错误
  10. MAC地址生成器(可带跳数)
  11. 罗技鼠标G304驱动与讲解(其余类型驱动见文末)
  12. 互联网金融学习总结(1)——互联网金融(ITFIN)概念相关学习
  13. 从百度世界大会2014中所看到,所感受到的
  14. 武林传奇之七剑下天山java游戏开发商_武林传奇之七剑下天山
  15. Hwclock用法介绍
  16. 8人Python-----day04
  17. 62套儿童行业响应式Html5儿童慈善机构网站模板儿童公益组织企业官网模板儿童慈善CSS模板下载婴儿树儿童健康食品整站模板html5网页静态模板Bootstrap扁平化网站源码css3手机seo自适响
  18. Atitit. 常用街机系统and 模拟器总结 snk neo geo cps mame sfc smc
  19. mt6355功率设计注意事项 [仅为mt 6758资料汇总]
  20. 3月18日云栖精选夜读 | 开发者必看!探秘阿里云Hi购季开发者分会场:海量学习资源0元起!... 1

热门文章

  1. Composer fails to download http json files on update, not a network issue, https fine
  2. SCOM 2012 SP1---安装SCOM 2012 SP1
  3. 现在有一个map集合如下: Map<Integer,String> map = new HashMap<Integer, String>(); map.put(1, “
  4. android获取年月日时分秒毫秒,Android获取两个日期其间间隔的天数
  5. 信息学奥赛一本通 1413:确定进制 | OpenJudge NOI 1.13 34:确定进制 | OpenJudge NOI 2.1 1973:确定进制
  6. 支配树(洛谷-P5180)
  7. 理论基础 —— 树 —— 树的存储结构
  8. 训练日志 2019.4.6
  9. 3.2 SE11创建数据元素
  10. python判断文件是否存在 中文_python如何判断文件是否存在