3.4 马尔科夫链算法具体实现(C语言)

18人阅读 评论(1) 收藏 举报
分类:

3.4 马尔科夫链算法具体实现

    在这一篇笔记中,我不打算说很多了。因为所有的理论知识都在3.3节中讨论过了。我在这里直接给出代码。另外给个彩蛋,某公司的面试题可就和这道特别类似哦。

    在这里,我要说的是:

    1.读取文本和代码之间的配合要掌握好

    2.时间与空间消耗要掌握好

    而对于C语言来说,最强的地方就是给了程序员对实现方式的完全控制,用它写出的程序趋向于快速。但是这也有代价,这就是C程序员必须做更多的工作,包括分配和释放存储,建立散列表和链接表,以及其他许多类似的事项。 C语言像一把飞快的剃刀,使用它,你可以创造优雅和高效的程序,或者弄出些一塌糊涂的东西来。

    代码时间:

#include "stdafx.h"
#include "stdlib.h"
#include "string.h"
#include <iostream>

using namespace std;

enum
{
	NPREF = 2,			/*前缀中词的数量*/
	NHASH = 99999,		/*哈希表(散列表)大小*/
	MAXGEN = 10000,		/*录入的最大单词数量*/
	MULTIPLIER = 31,
	BUFSIZE = 100
};
char NONWORD = '\n';

typedef struct State State;
typedef struct Suffix Suffix;
/*散列表中的元素*/
struct State
{
	/*前缀数量是确定的*/
	char *pref[NPREF];
	/*状态中要可以包含后缀及指向下一个前缀*/
	Suffix *suf;
	State *next;
};
/*后缀*/
struct Suffix
{
	char *word;
	/*可以构成多个后缀*/
	Suffix *next;
};
/*这个就是散列表*/
State *statetab[NHASH] = { NULL };

unsigned int hash_number(char *s[NPREF]);
State *lookup(char *prefix[NPREF], int create);
void build(char *prefix[NPREF], FILE *f);
void add(char *prefix[NPREF], char *suffix);
void addsuffix(State *sp, char *suffix);

int main()
{
	State *begin;
	FILE *fp = NULL;
	char box[NPREF][256];
	fp = fopen("..\\test.txt", "r");
	if (fp == NULL)
	{
		cout << "Error in opening the file" << endl;
		exit(0);
	}
	begin = (State *)malloc(sizeof(State));
	begin->next = NULL;
	for (int i = 0; i < NPREF; i++)
	{
		fscanf(fp, "%s", box[i]);
		begin->pref[i] = box[i];
		//cout << begin->pref[i] << endl;
	}
	build(begin->pref, fp);
	for (int i = 0; i < NHASH; i++)
	{
		if (statetab[i] != NULL)
		{
			cout << statetab[i]->pref[0] << " " << statetab[i]->pref[1] << " " << statetab[i]->suf->word << endl;
                        /*插入的位置同样正确*/
			if (statetab[i]->suf->next != NULL)
			{
				cout << statetab[i]->suf->next->word << endl;
			}
		}
	}
    return 0;
}

/*哈希表键值计算函数*/
unsigned int hash_number(char *s[NPREF])
{
	unsigned int h;
	unsigned char *p;
	int i;

	h = 0;
	for (i = 0; i < NPREF; i++)
	{
		for (p = (unsigned char *)s[i]; *p != '\0'; p++)
		{
			h = MULTIPLIER * h + *p;
		}
	}
	/*返回哈希表中的键值*/
	return h;
}

State *lookup(char *prefix[NPREF], int create)
{
	int i, h;
	State *sp = NULL;

	h = hash_number(prefix);
	for (sp = statetab[h]; sp != NULL; sp = sp->next)
	{
		for (i = 0; i < NPREF; i++)
		{
			/*如果输入的prefix和哈希表中对应的sp->pref[i]不相同*/
			/*证明不是要找的前缀*/
			/*注意前缀中含有两个单词*/
			if (strcmp(prefix[i], sp->pref[i]) != 0)
			{
				break;
			}
		}
		if (i == NPREF)
		{
			return sp;
		}
	}
	/*在哈希表中没有与输入前缀相对应的部分时*/
	if (create)
	{
		sp = (State *)malloc(sizeof(State));
		for (i = 0; i < NPREF; i++)
		{
			sp->pref[i] = prefix[i];
		}
		sp->suf = NULL;
		/*将新生成的状态(State)加入到散列表中(哈希表)*/
		sp->next = statetab[h];
		statetab[h] = sp;
	}
	return sp;
}

/*读取文档并且构建前缀、后缀*/

void build(char *prefix[NPREF], FILE *f)
{
	char buf[100], fmt[10];
	//sprintf(fmt, "%%%ds", sizeof(buf) - 1);
	/*将文本中符合“fmt”定义的单词读取到buf中*/
	/*fmt定义为最大99个字符,因为基本所有单词不会超过20个字符*/
	while (fscanf(f, "%s", buf) != EOF)
	{
		/*将符合“fmt”标准的单词复制到buf中*/
		/*使用字符串复制函数strdup*/
		add(prefix, _strdup(buf));
	}
}

/*添加函数,将会把整篇文档都加到散列表中*/
/*遍历文档,文章中所有前缀都能涉及*/
void add(char *prefix[NPREF], char *suffix)
{
	/*定位到prefix,并且把后缀suffix加入到prefix对应的sp中*/
	State *sp;
	sp = lookup(prefix, 1);
	addsuffix(sp, suffix);
	/*前缀的更新*/
	memmove(prefix, prefix + 1, (NPREF - 1) * sizeof(prefix[0]));
	prefix[NPREF - 1] = suffix;
}

/*为某一个特定的前缀添加后缀*/
void addsuffix(State *sp, char *suffix)
{
	Suffix *suf;
	suf = (Suffix *)malloc(sizeof(Suffix));
	suf->word = suffix;
	suf->next = sp->suf;
	sp->suf = suf;
}

查看评论

马尔科夫链C语言实现

  • 2011年08月16日 17:02
  • 17KB
  • 下载

马尔可夫链算法

引言:   我们现在准备做的就是给定一个由不同的单词组成的句子,由这个句子产生一些随机的可以读的英语文本。 马尔可夫链可以比较好的完成这个任务!   该算法把每个短语分割为两个部分:一部分是由多个词构...
  • leolinsheng
  • leolinsheng
  • 2014-03-25 18:01:35
  • 3340

随机文本生成与马尔科夫链

1. 随机文本生成            如何生成随机文本?要解决这个问题,首先必须知道什么是随机文本。这里说的”随机文本“是一种有”意义“的”随机文本“。有“意义”是指所生成的随机文本在一定程度上...
  • w396507790
  • w396507790
  • 2012-03-23 08:44:56
  • 1911

操作系统实验-页面置换算法C语言实现

  • 2009年05月30日 10:20
  • 37KB
  • 下载

马尔可夫链算法原理与实现

马尔可夫链算法原理与实现@(ML)[machine learining]马尔可夫链算法原理与实现 一概述 二基本流程 1得到语句 2句子出现的概率 3马尔可夫假设 4计算条件概率 5结果 (一)概述参...
  • jediael_lu
  • jediael_lu
  • 2017-08-06 21:43:15
  • 740

随机文本生成技术---order-k马尔科夫链文本生成技术

这里的k = 2:        int k = 2;    char inputchars[5000000];    char *word[1000000];    int nword = 0;  ...
  • baiwen1979
  • baiwen1979
  • 2008-03-24 17:32:00
  • 832

a*算法C实现

  • 2017年04月18日 20:43
  • 11KB
  • 下载

程序设计实践 双语版3.1---马尔可夫链算法

给我看你的流程图而藏起你的表,我将仍然是莫名其妙。如果给我你的表,那么我将不再要你的流程图,因为它们太明显了。—Frederick P. Brooks, Jr., 《人月神话》 以上从Bro...
  • cuizhangbo
  • cuizhangbo
  • 2013-09-29 19:49:23
  • 715

马尔科夫链算法的JAVA实现

首先  马尔可夫链,是指数学中具有马尔可夫性质的离散事件随机过程。该过程中,在给定当前知识或信息的情况下,对于预测将来会发生什么,发生的概率是多少。 算法实现原理 本文章讲述的是如何使用JAVA来简单...
  • wjt_csdn
  • wjt_csdn
  • 2017-05-03 22:53:55
  • 114894

马尔科夫链蒙特卡洛(MCMC)

在以贝叶斯方法为基础的机器学习技术中,通常需要计算后验概率,然后通过最大后验概率(MAP)等方法进行参数推断和决策。然而,在很多时候,后验分布的形式可能非常复杂,这个时候寻找其中的最大后验估计或者对后...
  • baimafujinji
  • baimafujinji
  • 2016-12-30 20:34:49
  • 9568
    个人资料
    持之以恒
    等级:
    访问量: 4027
    积分: 513
    排名: 9万+
    最新评论