当前位置:编程学习 > C/C++ >>

C++实现语音识别词典内存存储模型

对于给定的词典,如下
[html] 
一 ii i1  
一一 ii i1 ii i1  
一一一 ii i1 ii i1 ii i1  
一一一一 ii i4 ii i1 ii i4 ii i1  
一一一七 ii i1 ii i1 ii i1 q i1  
一一一三 ii i1 ii i1 ii i1 s an1  
一一一九 ii i1 ii i1 ii i1 j iu3  
一一一二 ii i1 ii i1 ii i1 ee er4  
一一一五 ii i1 ii i1 ii i1 uu u3  
一一一八 ii i1 ii i1 ii i1 b a1  
一一一六 ii i1 ii i1 ii i1 l iu4  
一一一四 ii i1 ii i1 ii i1 s iy4  
一一一零 ii i1 ii i1 ii i1 l ing2  
一一七 ii i1 ii i1 q i1  
此处略去很多个字  
在语音识别时,训练和解码时都要用到词典,本文说明一个词典处理时的内存存储模型。
一,模型需求
模型包括如下信息
词典共有多少个词,这包括正常的词和特殊的词。
句子或文法的起始和结束用词。
停顿词,就是静音词,用于静音建模。
词的发音个数。可能有些词有多个发音,如“和”,就是一个常见的多音词。
建立语言模型时,是否依赖词。
二,模型实现
[cpp]  
class Vocabulary  
{  
public:  
    int         nWords ;       // 总共多少个词  
    char        **words ;      // 所有词的数组,下标为词的序数,包括正常词和特殊词  
  
  
    int         nNormWords ; // 正常词个数  
    int         *normWordInds ; 正常词的序数  
     
     
    char        specWordChar ; // 特殊词的标识,就是标识一个特殊词,如!一,表示一为特殊词  
    int         nSpecWords ; // 特殊词的个数  
    int         *specWordInds ; //所有特殊词的序数数组  
     
  
    int         sentStartIndex ; // 句子或文法开始的词序号  
    int         sentEndIndex ;// 句子或文法结束的词序号  
    int         silIndex ;//静音词  
  
  
    bool        fromBinFile ;  
    // 构造函数  
  
    Vocabulary() ;   
    Vocabulary(const char *lexFName , char specWordChar_='\0' ,  
        const char *sentStartWord=NULL , const char *sentEndWord=NULL ,  
        const char *silWord=NULL) ;  
  
    virtual ~DecVocabulary() ;  
  
    char *getWord( int index ) ; // 根据给定的序号,获取词,这个从词数组中获取。  
  
    int getNumPronuns( int index ) ; // 根据给定的序号,获取该词的发音个数,如果不是多音词,就返回1。  
  
    bool isSpecial( int index ) ; //序号对应的词是否是特殊词  
  
    bool getIgnoreLM( int index ); // 标记是否用于语言模型建模,一般都是依赖的,这个提高识别率。  
  
    int getIndex( const char *word , int guess=-1 ) ;//根据词获取序号,可以指定起始位置开始查找  
  
private:  
    int         nWordsAlloc ; // nWords记录词典包含多少个词,这个值记录共为内存词典大小。  
    bool        *special ;     // 指示词典中的词是否为特殊词  
    int         *nPronuns ;    // 每个词对应多少种不同的发音  
  
    /***  添加一个词至内存词典中 ,并指示是否需要更新发音**/  
    int addWord( const char *word , bool registerPronun=true ) ;  
};  
 
三,构造函数过程
 
打开构造参数的词典文件,参数名lexFName,FILE *fd。
调用while( fgets(line,1000,fd)!=NULL )从fd中一行一行读取,然后分割取第一个域,并调用成员函数addWord往词典中加入词。
将开始和结束词加入词典中。
根据specWordChar来处理特殊词,就是判断第一个字节是否为specWordChar。统计特殊词和正常词的个数,并存入相应的内存中(见上文的类定义)。
四,加词实现
代码如下:
[cpp]  
int Vocabulary::addWord( const char *word , bool registerPronun )  
{  
    int cmpResult=0 , ind=-1 ;  
   
    //分配足够的空间存储  
    if ( nWords == nWordsAlloc ){  
        nWordsAlloc += 100 ;  
        words = (char **)realloc( words , nWordsAlloc*sizeof(char *) ) ;  
        nPronuns = (int *)realloc( nPronuns , nWordsAlloc*sizeof(int) ) ;  
        for ( int i=nWords ; i<nWordsAlloc ; i++ ){  
            words[i] = NULL ;  
            nPronuns[i] = 0 ;  
        }  
    }  
  
    if ( (word == NULL) || (word[0] == '\0') )  
        return -1 ;  
  
    if ( nWords > 0 )  
        cmpResult = strcasecmp( words[nWords-1] , word ) ;  
  
    //确保新词在适当的位置  
    if ( (cmpResult < 0) || (nWords == 0) ){  
        // The new word belongs at the end of the list  
  
        words[nWords] = new char[strlen(word)+1] ;  
        nPronuns[nWords] = 0 ;  
        strcpy( words[nWords] , word ) ;  
        ind = nWords ;  
        nWords++ ;  
    }else if ( cmpResult > 0 ){  
        for ( int i=0 ; i<nWords ; i++ ){  
            cmpResult = strcasecmp( words[i] , word ) ;  
            if ( cmpResult > 0 ){  
                nWords++ ;  
                for ( int j=(nWords-1) ; j>i ; j-- ){  
                    words[j] = words[j-1] ;  
                    nPronuns[j] = nPronuns[j-1] ;  
                }  
                words[i] = new char[strlen(word)+1] ;  
                strcpy( words[i] , word ) ;  
                nPr
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,