2005年4月6日

ostream_iterator< int > ofile( cout, " ");

ostream_iterator
这是一个游标类,
ostream_iterator< int > ofile( cout, " ");
这个表示这是一个直接指向cout(默认打开的输出流)的游标类,两个引号中间有一个空格,我能够编译,估计是你的空格少了,这是表示流的分隔标志,也可以用其他的字符

#include
#include
#include
using namespace std;

int main(int argc, char* argv[])
{
vector v;
vector vc;
ostream_iterator< int > ofile( cout, ",");
ostream_iterator ofile2( cout,";");
for(int i=0;i<10;i++) v.push_back(i);
for(i=0;i<10;i++) vc.push_back('w');
copy(v.begin(),v.end(),ofile);
copy(vc.begin(),vc.end(),ofile2);
ofile=4;ofile2='m';
return 0;
}
看看这个程序输出什么,
0,1,2,3,4,5,6,7,8,9,
w;w;w;w;w;w;w;w;w;w;
4,m;

函数bind1st 和 bind2nd 的说明

函数bind1st 和 bind2nd 都可以用于将二元算子(binary functor, bf)转换为一元算子(unary functor, uf)。转换过程需要二个参数:bf与值(v)。

值(v)是固定参数。换句话说,uf(x)等价于:
 * bf( x, v) - 用于bind2nd函数
 * bf( v, x) - 用于bind1st函数

在处理判别问题时使用bind1st 和bind2nd 函数是很有用的。这二个函数可将二元判别条件转换为一元判别条件。在将某一范围内(如容器中)的各个值与一基准值相比较时尤其有用。例如:

std::vector< int> a;
// . . . 给a赋值

// 下面的指令将删除所有小于30的元素
a.erase( std::remove_if( a.begin(), a.end(),
std::bind2nd( std::less< int>(), 30)), a.end());

在大多情况下,使用bind2nd就足够了,如上例所示。

但在类属编程时,要用函数来处理判别问题。通常要指定判别方向,并都用小于号"<" (std::less< type>)来表示。记住,要分别建立小于号"<"的各个重载算子"<=", ">=", 和 ">"。在这种情况下,就能看到bind1st 和bind2nd函数都很有用了。举例如下:

#include
#include
#include

template< class iterator, class predicate, class doer>
void for_each_if( iterator itFirst, iterator itLast, predicate pred, doer do_it)
{
while ( itFirst != itLast)
{
if ( pred( *itFirst)) do_it( *itFirst);
++itFirst;
}
}

void print( int i) { std::cout << i << " "; }

int main(int argc, char* argv[])
{
int aNumbers[] = { 10, 5, 89, 9, 30, -2, -8, 7, 33, 25, 30, 76, 0, 2};
int nCount = sizeof( aNumbers) / sizeof( aNumbers[ 0]);

// a < b
std::cout << "\nNumbers less than 30: ";
for_each_if( aNumbers, aNumbers + nCount,
std::bind2nd( std::less< int>(), 30), print);

std::cout << "\nNumbers bigger than 30: ";
// a > b
for_each_if( aNumbers, aNumbers + nCount,
std::bind1st( std::less< int>(), 30), print);

std::cout << "\nNumbers less or equal than 30: ";
// a <= b <=> !(a > b)
for_each_if( aNumbers, aNumbers + nCount,
std::not1( std::bind1st( std::less< int>(), 30)), print);

std::cout << "\nNumbers bigger or equal than 30: ";
// a >= b <=> !(a < b)
for_each_if( aNumbers, aNumbers + nCount,
std::not1( std::bind2nd( std::less< int>(), 30)), print);

return 0;
}

下面是一个类属函数示例,将删除所有小等于最小值或大等于最大值的元素:

// 删除所有满足'x <= least' 或 'x >= biggest'条件的元素
template< class iterator, class value_type, class predicate>
iterator remove_least_and_biggest(
iterator itFirst, iterator itLast,
value_type least, value_type biggest, predicate pred)
{
// 删除所有x <= least的元素
iterator itAfterRemovingLeast =
std::remove_if( itFirst, itLast,
std::not1( std::bind1st( pred, least)));
// 删除所有x >= biggest的元素
iterator itNewLast =
std::remove_if( itFirst, itAfterRemovingLeast,
std::not1( std::bind2nd( pred, biggest)));
return itNewLast;
}

如果进行忽略大小写字母的字符串比较,可用以下代码:

bool case_insensitive( const std::string & first, const std::string & second)
{ /* 代码 */ }

std::string aStrs[] = { "john", "John Doe", "Mircea", "nicole", "Nicole
Kidman", "Abraham", "Zeek" };
int n = sizeof( aStrs) / sizeof( aStrs[ 0]);
std::vector< std::string> a( aStrs, aStrs + n);
std::copy( a.begin(), a.end(),
std::ostream_iterator< std::string>( std::cout, ", "));
std::cout << std::endl;
// 删除不是"John Doe", "Mircea", "nicole"的所有元素
a.erase( remove_least_and_biggest(
a.begin(), a.end(), "John", "nicole kidman",
std::ptr_fun(case_insensitive)), a.end());
std::copy( a.begin(), a.end(),
std::ostream_iterator< std::string>( std::cout, ", "));


2005年4月5日

FSNLP第五章

周五,我将讲述FSNLP的第五章。最近任务太多,不得不先完成相对容易而且很紧的任务。

昨天下午在寝室一觉醒来,想要找个地方上自习开始看看FSNLP的第五章。拿上书包准备出去的时候发现寝室自习未尝不可。安安静静的一个人开始看书。一个半小时左右后心潮彭湃,有想要赶紧做slides的冲动。

约莫三点四十,来到实验室,打开自己的工作音乐--Bandari,开始写起slides来。截至刚才,我的slides已经完成,检查了一下基本没有什么问题。就差周五上午再温习一下了。

正如昨天的blog一样,读一遍书和做slides给大家讲完全不是一样的概念。做slides的时候脑袋里需要想着听众,想着内容如何展现。还需要细细体会的书中内容。

以前听说过抄书的好处,我也手抄过英文版的FSNLP的第一册。现在看来效果最好的还是读完后给大家作个slides介绍介绍书中的内容。同样的感觉出现在若干次在实验室例会以及reading group上的论文主讲。

想到一个笨方法:以后发现一些非常值得阅读的文献资料,读完一遍后再做个slides试着给大家讲讲。

Good idea. 最笨的方法也是最有效的方法。

2005年4月4日

指代消歧

准备周五的FSNLP第五章的报告的过程中想到了一个关于指代消歧的问题。

第五章主要内容是搭配。章末提到了专有名词的识别,对于专有名词的识别存在一些很大的挑战:指代( coreference)(怎样才能说IBM和International Bussiness Machines是指向同一个实体),消歧(disambiguation)(AMEX什么时候指的是American Exchange,什么时候指的是Americam Express)?

看到这里不禁想到了卢老师昨天在实验室报告会上的一个缩略语--TCL。大家刚看到这个词的时候最先想到的就是“王牌高频电子有限公司”,而卢老师的报告中的TCL是Thai Computaional Linguistic(泰国语言学研究所)的简称。这里的TCL就像FSNLP书中提到的AMEX那样。

我对这个问题仔细思考了一下。对于某些人未曾听说过TCL能指代“泰国语言学研究所”之前,他会认为TCL就是指代“王牌高频电子有限公司”。纯粹就是指代消解需要解决的问题,细化一下就是缩略型的共指消解。但是在听说TCL能指代“泰国语言学研究所”之后再谈这个问题那就不一样了。按照FSNLP书中的说法,这个问题是消歧的问题。但是究竟是什么消歧呢?我开始以为是指代消歧的问题。因为这里其实是共指上有两种可能。再网上查证自己的想法(输入“指代消歧”或者“coreference disambiguation”或者"anaphora disambiguation")结果找到的我需要的信息一点也没有。我认为指代消歧应该是指代消解研究体系下的一个较为深入的题目。

我把我的想法和实验室专做词义消歧的卢老师讨论了一下。卢老师说在上下文中确定“他”的指向问题的时候,备选答案可能就是几个人名。确定“他”的指向问题的时候,和我所说的TCL指向的问题本身就是很类似的。

我认为按照卢老师的提示问题确实是一致的。但是,正如FSNLP书中所说的那样,AMEX有两个意思(缩略对象也可以看成是意思):American Exchange和Americam Express。如果是在上下文中确定AMEX是什么意思时那就是一个词义消歧的问题。

这个问题还需要深入考虑。待续。

2005年4月3日

月末小结

又到了月末小结的时刻,撰写这种文档的时候总有一种疏理自己生活的感觉。疏理是必要的,人就应改经常的总结自己。正如周明老师一次在咱们学校大礼堂上送给我们的话一样。“经常的总结自己,发现自己取得成功的原因,找出失败的教训,争取以后做事时取得更大的成绩”。

“疏理”自己之前,我对于自己在三月份的工作只有模糊的映象。只是感觉自己成天都在忙忙碌碌,没有条理的那种忙法。细细查看自己在一个月里的几个报告内容和完成的一些任务,这才将自己三月份做过什么整理清楚。原来自己在三月份做了那么多的事情。这在一定程度上减轻了自己浪费时间的感觉。

一个月的时间本不是很长,四个忙忙碌碌而又周期性的工作周就会让人感觉不清楚它的存在。同样是一个月,以寒假为例,时间却过得很慢,总觉得时钟会随着一年的节日而发生转速的改变。时间真是一个奇特的东西。

月末总结还需要包含下月计划。在制定的下月计划时,一不小心我发现我的时间表上已经占据了好几次的报告,加上我带领的研究小组的研究任务以及自己的研究生课程,我感觉自己的2005年4月将是一个更加忙碌的月份。

忙碌是什么?我一直在反思这个问题。其实忙碌是一个双刃剑。有些人碌碌无为,有人过劳死掉,有人在忙碌中体验并享受人生。不同的生活习惯和生活内容导致了不同的忙碌内容。忙碌需要规范化,那自然就是计划的重要性。

提起做计划我就想到了自己在这方面存在的不足之处。原先自己在做计划的时候总是将时间安排的满满的,而且一次就是好几十天的内容,但是计划没有变化快,真正完全执行到底的计划没有几个。这就自然涉及到一个如何做计划的东西。其实这是一门很高深的学问。经过了这么多,加上自己的体会以及别人的心得,我觉得如下的方案对我比较可行:

月初撰写上月月末小结,包含月度计划;每周末撰写周末小结并且制定下周计划;每天晚上撰写blog并且制定第二天的计划;每个小结的开头需要对上月、周、日的计划内容进行考核,找出没有完成任务的原因并且找出解决方案,适当调整计划内容。

原先我的各种计划缺少最为关键的一个部分:计划完成状况的监督。

忙碌的四月已经到来,加上完善的计划监督方案相信自己会更加充实,不会再有那种模糊的感觉。

2005年4月2日

研究生课程

眨眼功夫已经到了四月,根据研究生教学计划我们研一的课程将在这个月结束,下个月月初进行各科的考试。

这学期开学以来,忙忙碌碌的生活我选择了听好每一堂课,最后一个月好好复习的策略。这个计划中的最后一个月已经到来,我需要开始好好的准备各个科目的作业和考试了。

时间--紧,任务--多,迫切需要详细周密的计划。

2005年4月1日

遗传算法初探

下午的实验室TS小组例会上,我负责指导的IR俱乐部学生李正华给大家做了《遗传算法初探》的报告。报告内容丰富,大家对于遗传算法也都有了更深入的认识。

看着李正华在台上精彩的演讲,我知道了他现在对机器学习已经有了浓厚的兴趣。他现在对于机器学习的激情自一定程度上也给了我很大的影响。互相学习嘛!

祝福他能子遗算法方面取得一定的成绩。