⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 segtofile(sen).c

📁 为自然语言处理领域的中文分词程序
💻 C
📖 第 1 页 / 共 5 页
字号:
double GetElementValue(pDynamicArray p,int nRow, int nCol,PARRAY_CHAIN pStart,PARRAY_CHAIN *pRet)
{
   PARRAY_CHAIN pCur=pStart; 
   
   if(pStart==0)
	    pCur=p->m_pHead; 
   if(pRet!=0)
	   *pRet=NULL; 
   if(nRow>(int)p->m_nRow||nCol>(int)p->m_nCol) 
	   return INFINITE_VALUE;
   /*如果是动态数组行的头,则指向下一个行*/
  if(p->m_bRowFirst)
   { 
	   while(pCur!=NULL&&(nRow!=-1&&(int)pCur->row<nRow||(nCol!=-1&&(int)pCur->row==nRow&&(int)pCur->col<nCol))) 
	   {
		   if(pRet!=0)
			   *pRet=pCur;
		   pCur=pCur->next;
	   }
   }
   /*如果是动态数组列的头,则指向下一个列*/
   else
   { 
	   while(pCur!=NULL&&(nCol!=-1&&(int)pCur->col<nCol||((int)pCur->col==nCol&&nRow!=-1&&(int)pCur->row<nRow))) 
	   {
		   if(pRet!=0)
			   *pRet=pCur;
		   pCur=pCur->next;
	   }
   }
   if(pCur!=NULL&&((int)pCur->row==nRow||nRow==-1)&&((int)pCur->col==nCol||nCol==-1)) 
   { 
	   if(pRet!=0)
		   *pRet=pCur;
	   return pCur->value; 
   }
	return INFINITE_VALUE; 
}

/**************************************************************************************
  28.从动态数组中相应的行列查找其元素的值,没有的行列加入,并把词也加入动态数组
***************************************************************************************/
int SetElement(pDynamicArray p,unsigned int nRow, unsigned int nCol, double fValue,int nPOS,char *sWord)
{
   PARRAY_CHAIN pCur=p->m_pHead;
   PARRAY_CHAIN pAdd ,pPre=NULL; 
   /*得到行列*/
   if(nRow>p->m_nRow) 
	   p->m_nRow=nRow;
   if(nCol>p->m_nCol) 
	   p->m_nCol=nCol;
   /*从行或列的头遍历行列*/
   if(p->m_bRowFirst)
   { 
	   while(pCur!=NULL&&(pCur->row<nRow||(pCur->row==nRow&&pCur->col<nCol)))
	   { 
		   pPre=pCur;
		   pCur=pCur->next; 
	   }
   }
   else
   { 
	   while(pCur!=NULL&&(pCur->col<nCol||(pCur->col==nCol&&pCur->row<nRow)))
	   { 
		   pPre=pCur;
		   pCur=pCur->next; 
	   }
   }
   /*指定的行列位置找到元素值*/
   if(pCur!=NULL&&pCur->row==nRow&&pCur->col==nCol)
   { 
	   pCur->value=fValue; 
	   pCur->nPOS=nPOS; 
   }
   /*没有此行列则加入行列*/
   else
   { 
       pAdd=(PARRAY_CHAIN)malloc(sizeof(ARRAY_CHAIN)); 
	   pAdd->col=nCol; 
	   pAdd->row=nRow; 
	   pAdd->value=fValue; 
	   pAdd->nPOS=nPOS; 
        /*sWord存在,直接加入*/
	   if(sWord)
	   { 
		   pAdd->nWordLen=strlen(sWord); 
		   pAdd->sWord=(char *)malloc((pAdd->nWordLen+1)*sizeof(char)); 
		   strcpy(pAdd->sWord,sWord); 
	   }
	    /*sWord不存在,则词为空*/
	   else
	   { 
		   pAdd->nWordLen=0; 
		   pAdd->sWord=NULL; 
	   }
	   pAdd->next=pCur;
	   if(pPre==NULL) 
		   p->m_pHead=pAdd;
	   else 
		   pPre->next=pAdd;
	   pAdd=NULL;
   }
   return 0;
}

/**************************************************************************************
  29.释放动态数组的指针,包括多个sWord指针及动态数组的头指针
***************************************************************************************/
void SetEmpty(pDynamicArray p)
{
  PARRAY_CHAIN pTemp ,pCur=p->m_pHead; 
   while(pCur!=NULL)
   { 
	   pTemp=pCur->next;
       if(pCur->sWord)
	   {
			free(pCur->sWord); 
			pCur->sWord=NULL;
	   }
	   free(pCur);  
	   pCur=pTemp; 
   }
   pTemp=NULL;
   p->m_pHead=NULL;
   p->m_nCol=0; 
   p->m_nRow=0;
}

/**************************************************************************************
  30. 得到行列中动态数组的元素,由RetWord返回词,由pRetPOS返回位置
***************************************************************************************/
int GetElement(pDynamicArray p,int nRow, int nCol, double *pRetValue, int *pRetPOS,char *sRetWord)
{
    PARRAY_CHAIN pCur=p->m_pHead; 
	*pRetValue=INFINITE_VALUE;
	*pRetPOS=0;
	  if(nRow>(int)p->m_nRow||nCol>(int)p->m_nCol) 
	   return FALSE;

   if(p->m_bRowFirst)
   { 
	   while(pCur!=NULL&&(nRow!=-1&&(int)pCur->row<nRow||(nCol!=-1&&(int)pCur->row==nRow&&(int)pCur->col<nCol)))
	   { 
		   pCur=pCur->next;
	   }
   }
   else
   { 
	   while(pCur!=NULL&&(nCol!=-1&&(int)pCur->col<nCol||((int)pCur->col==nCol&&nRow!=-1&&(int)pCur->row<nRow)))
	   { 
		   pCur=pCur->next;
	   }
   }
   if(pCur!=NULL&&((int)pCur->row==nRow||nRow==-1)&&((int)pCur->col==nCol||nCol==-1))
   { 
		*pRetValue=pCur->value; 
		if(pRetPOS)
			*pRetPOS=pCur->nPOS; 
	    if(sRetWord)
		{
		   strcpy(sRetWord,pCur->sWord); 
		}
   }
	return TRUE;
}

/**************************************************************************************
  31. 得到动态数组的头指针
***************************************************************************************/
PARRAY_CHAIN GetHead(pDynamicArray p)
{
	return p->m_pHead;
}

/**************************************************************************************
  32. 得到动态数组的节点个数
***************************************************************************************/
unsigned int GetTail(pDynamicArray p,PARRAY_CHAIN *pTailRet)
{
	PARRAY_CHAIN pPrev=NULL;
    PARRAY_CHAIN pCur=p->m_pHead; 
	unsigned int nCount=0;
	while(pCur!=NULL)
	{ 
		nCount+=1;
		pPrev=pCur;
		pCur=pCur->next;
	}
	*pTailRet=pPrev; 
	return nCount;
} 

/**************************************************************************************
  33. 得到动态数组的行指针
***************************************************************************************/
int SetRowFirst(pDynamicArray p,int RowFirst)
{	
	p->m_bRowFirst=RowFirst;
	return TRUE;
}

/**************************************************************************************
  34. 释放动态数组的指针
***************************************************************************************/
void UDynamicArray(pDynamicArray p)
{
   PARRAY_CHAIN pTemp ,pCur=p->m_pHead;
   while(pCur!=NULL)
   { 
	   pTemp=pCur->next;
       if(pCur->sWord)
	   {
			free(pCur->sWord); 
			pCur->sWord=NULL;
	   }
	   free(pCur);  
	   pCur=pTemp; 
   }
   free(pTemp);
   pTemp=NULL;   
   p->m_pHead=NULL;
}

/**************************************************************************************
  35. 初始化动态数组的头指针为NULL,行列均为0,赋值给第一个行指针
***************************************************************************************/
void IDynamicArray(pDynamicArray p,int bRowFirst)
{
	p->m_pHead=NULL;  
    p->m_nRow=0; 
    p->m_nCol=0; 
    p->m_bRowFirst=bRowFirst; 
}

/**************************************************************************************
  36. 释放队列的各个节点指针,头指针和p->m_pLastAccess指针
***************************************************************************************/
void UQueue(pQueue p)
{
   PQUEUE_ELEMENT pTemp,pCur=p->m_pHead;
   while(pCur!=NULL)
   {
	   pTemp=pCur->next;
	   free(pCur);
	   pCur=pTemp;
   }
   pTemp=NULL;
   free(p->m_pHead);
   p->m_pHead=NULL;
   free(p->m_pLastAccess);
   p->m_pLastAccess=NULL;
}

/**************************************************************************************
  37. 初始化队列的各个节点指针,头指针和p->m_pLastAccess指针
***************************************************************************************/
int Push(pQueue p,unsigned int nValue,unsigned int nIndex, double eWeight)
{
   PQUEUE_ELEMENT pAdd,pCur=p->m_pHead;
   PQUEUE_ELEMENT pPre=NULL;
   while(pCur!=NULL&&pCur->eWeight<eWeight)
   {
	   pPre=pCur;
	   pCur=pCur->next;
   }
   pAdd=(PQUEUE_ELEMENT)malloc(sizeof(QUEUE_ELEMENT));
   pAdd->nParent=nValue;
   pAdd->nIndex=nIndex;
   pAdd->eWeight=eWeight;
   pAdd->next=pCur;
   if(pPre==0)
	   p->m_pHead=pAdd;
   else
	   pPre->next=pAdd;
   pAdd=NULL;
   return 1;
}

/**************************************************************************************
  38. 将Queue中内容读出
***************************************************************************************/
int Pop(pQueue p,unsigned int *npValue,unsigned int *npIndex,double *epWeight, int  bModify,int  bFirstGet)
{
	PQUEUE_ELEMENT pTemp;
	/*如果修改,头指针指向临时指针*/
	if(bModify)
		pTemp=p->m_pHead;
    /*如果不修改,头指针指向最后访问指针*/
	else
	{
	  if(bFirstGet)
		   p->m_pLastAccess=p->m_pHead;
	  pTemp=p->m_pLastAccess;
	}
	if(pTemp==NULL)
		return -1;
	/*Parent赋值pValue*/
    if(npValue!=0)
	    *npValue=pTemp->nParent;
	/*Index付给nIndex*/
    if(npIndex!=0)
	    *npIndex=pTemp->nIndex;
	/*Weight付给pWeight*/
    if(epWeight!=0)
		*epWeight=pTemp->eWeight;
        if(bModify)
	{
	   p->m_pHead=pTemp->next;
	}
	else
	{
       p->m_pLastAccess=pTemp->next;
    }
    return 1;
}

/**************************************************************************************
  39. 将Queue的指针为NULL
***************************************************************************************/
int IsEmpty(pQueue p,int bBrowsed)
{
	if(bBrowsed==TRUE)
		return (p->m_pLastAccess==NULL);
   return (p->m_pHead==NULL);
}


/**************************************************************************************
  39. Queue为单节点
***************************************************************************************/
int IsSingle(pQueue p)
{
   return (p->m_pHead!=NULL&&p->m_pHead->next==NULL);
}

/**************************************************************************************
  40. 初始化Queue的指针为NULL
***************************************************************************************/
void IQueue(pQueue p)
{	
	p->m_pHead=NULL; 
	p->m_pLastAccess=NULL; 
}

/**************************************************************************************
  41. 释放Queue的指针为NULL
***************************************************************************************/
void USpan(pSpan p)
{	
	free(p->m_context);
	p->m_context=NULL;	
}

/**************************************************************************************
  42. 得到最佳前驱权重和频率
***************************************************************************************/
int Disamb(pSpan p)
{
	int i,j,k,nMinCandidate;
	double dMinFee=0,dTmp;
	for(i=1;i<p->m_nCurLength;i++) 
	{
		for(j=0;p->m_nTags[i][j]>=0;j++) 
		{
			nMinCandidate=MAX_POS_PER_WORD+1;
			for(k=0;p->m_nTags[i-1][k]>=0;k++)
			{
				dTmp=-log(GetContextPossibility(p->m_context,0,p->m_nTags[i-1][k],p->m_nTags[i][j]));
				dTmp+=p->m_dFrequency[i-1][k]; 
				if(nMinCandidate>10||dTmp<dMinFee) 
				{
					nMinCandidate=k;
					dMinFee=dTmp;
				}
			}
			p->m_nBestPrev[i][j]=nMinCandidate; 
			p->m_dFrequency[i][j]=p->m_dFrequency[i][j]+dMinFee;
		}
	}	
	return TRUE;
}

/**************************************************************************************
  43. 词性标注初始化
***************************************************************************************/
int Reset(pSpan p,int bContinue)
{
	if(!bContinue)
	{ 
		if(p->m_tagType!=TT_NORMAL) 
		      p->m_nTags[0][0]=100; 
		else
		      p->m_nTags[0][0]=0; 
		p->m_nUnknownIndex=0;
		p->m_dFrequency[0][0]=0;
		p->m_nStartPos=0;
	}
	else
	{
		p->m_nTags[0][0]=p->m_nTags[p->m_nCurLength-1][0]; 
		p->m_dFrequency[0][0]=p->m_dFrequency[p->m_nCurLength-1][0];
	}
    p->m_nTags[0][1]=-1; 
	p->m_nCurLength=1;
	p->m_nWordPosition[1]=p->m_nStartPos;	
	p->m_sWords[0][0]=0;
	return TRUE;
}

/**************************************************************************************
  44. 文件的内容load到词性标注的结构中
***************************************************************************************/
int LoadContext(pSpan p,char *sFilename)
{
	return LoadContextState(p->m_context,sFilename);
}

/**************************************************************************************
  45. 词性标注最好位置  m_nBestTag[词数] 每个句词的最好标注数组
	 m_sWords[词数][词长] 每个句中的词内容,m_nTags[词数][每词的位置]元素为词标注,行是句中词数,列是词位置
	 m_nBestPrev[词数][每词的位置] 元素为最佳前驱词,m_nCurLength 当前长度
	
***************************************************************************************/
int GetBestPOS(pSpan p)
{
	int i,j,nEnd;
    /*得到最佳前驱权重和频率*/
	Disamb(p);

	for(i=p->m_nCurLength-1,j=0;i>0;i--)
	{
	 if(p->m_sWords[i][0])

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -