Problem 4
十月 20th, 2008
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91
99.
Find the largest palindrome made from the product of two 3-digit numbers.
int euler4()
{
int max=0;
for(int i=999;i>99;i–)
for(int j=999;j>99;j–)
{
int n=i*j;
int a6=n/100000;
int a5=(n/10000)%10;
int a4=(n/1000)%10;
int a3=(n/100)%10;
int a2=(n/10)%10;
int a1=n%10;
if(a6==a1&&a5==a2&&a4==a3)
{
if(n>max)
max=n;
}
}
return max;
}
Problem 5
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?
int euler5()
{
int n=20;
while(true)
{
bool flag=true;
for(int i=2;i<21;i+=1)
{
if(n%i!=0)
{
flag=false;
break;
}
}
if(flag)return n;
n++;
}
}
Problem 6
14 December 2001
The sum of the squares of the first ten natural numbers is,
12 + 22 + … + 102 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + … + 10)2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025
385 = 2640.
Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
int euler6()
{
int n1=0,n2=0;
for(int i=1;i<=100;i++)
{
n1+=i;
n2+=i*i;
}
return n1*n1-n2;
}
MOTOMAGX
九月 15th, 2008
Motorola这样的公司是不会缺少技术的,可是它的手机业务这几年却经营的比较惨淡,不谈外观和市场,它在手机系统选择上三心二意就让人难以理解,Moto一直是Linux手机最强劲的支持者,但却又要去和微软亲密合作推出Widows Mobile的手机,又要去诺记和索爱那边插一脚收购Symbian的股份。而Linux这边虽然开源了系统却又不提供SDK。不过这次好像真的准备发力了。MOTODEV Studio除了基于Java ME的开发工具外,最近又增加了WebUI版和MOTOMAGX版的。WebUI顾名思义就是Web2.0相关的东西比Java离底层更远了,而我关心的则是能进行Native Linux开发的MOTOMAGX,这个东西现在还是Preview版,写出来的软件只能在模拟器里跑,但是相信真正实用也是指日可待了。
http://community.developer.motorola.com/mtrl/board?board.id=Studio_Linux
了解QT
九月 15th, 2008
Qt是一个支持多平台的图形用户界面库。相似的还有wxWidgets,Gtk以及微软的MFC。Qt是Linux下的KDE桌面环境的基础,Gtk是Gnome桌面环境的基础,wxWidgets是一个老牌的界面库,MFC无需多说了,他们的稳定性都是经得起考验的。
Qt由Trolltech公司开发,现被诺基亚收购,有商业和开源两个版本。虽然Qt没有wxWidgets和Gtk自由,但有商业公司支持的好处是文档丰富,技术稳定。而且Qt有不依赖X的Qt Embedded版以及以之为基础构建的Qtopia桌面环境,选择更多。
Qt编程全是用户界面相关的设计,其他部分还是要由标准C++或其他语言完成。
GUI界面处理的最多的是用户输入并对之响应,为此Qt设计了信号槽(Signals/Slots)机制,其实相当于MFC中的消息和消息响应函数,Signals/Slots是一种安全类型,替代了C++中的CallBack回调函数。
具体实现是用Slots:声明槽,Signals:声明信号,emit触发信号,connect函数连接信号和槽。通过在类中包含Q_OBJECT来表明用到了信号槽机制,qmake看到后会让moc编译器来把上面这些非标准C++的代码转换为标准C++代码,以便让其他C++编译器生成最后的程序。
qt三部曲
qmake -project 生成pro文件。
qmake 生产MakeFile文件。
make 调用外部的make生成最终程序。
可以用Qt Designer生成UI文件,但需手工写相关的类文件,QT3有自动生成代码文件的功能,但在QT4中被去掉了,为了和IDE彻底划清界限?好在QT文档丰富,有很多example可以参考。
自己动手写一个播放器(二)
九月 5th, 2008
要写一个播放器,mplayer和vlc都是很好的参考,相对来说vlc的代码更容易看一点。
最简单的方法是用ffmpeg解码,SDL作为显示前端,这样几十行代码就可以构建一个简易的播放器出来。
SDL是跨平台的多媒体开发包www.libsdl.org去官网下载自己对应开发工具的开发包,并用自己喜欢的开发工具设置好头文件和lib文件。
同样配置好ffmpeg的头文件和lib文件,主要是
-lavutil -lavformat -lavcodec -lavdevice -lSDL.dll -lSDLmain
然后编译下面这几行代码。
//myPlayer.c
#include <avcodec.h>
#include <avformat.h>#include <SDL.h>
#include <SDL_thread.h>#ifdef __MINGW32__
#undef main /* Prevents SDL from overriding main() */
#endif#include <stdio.h>
int main(int argc, char *argv[]) {
AVFormatContext *pFormatCtx;
int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVPacket packet;
int frameFinished;
float aspect_ratio;SDL_Overlay *bmp;
SDL_Surface *screen;
SDL_Rect rect;
SDL_Event event;if(argc < 2) {
fprintf(stderr, “Usage:myPlayer xx.avi 目前不支持rmvb之类”);
exit(1);
}
//注册解码器
av_register_all();
//初始化SDL
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
exit(1);
}//打开文件
if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)
return -1;//获取流信息
if(av_find_stream_info(pFormatCtx)<0)
return -1;// Dump文件信息
dump_format(pFormatCtx, 0, argv[1], 0);//找到第一个视频流
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
videoStream=i;
break;
}
if(videoStream==-1)
return -1; //没有视频流//获取视频流的AVCodecContext
pCodecCtx=pFormatCtx->streams[videoStream]->codec;//获取视频流的解码器
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
return -1;
}// 打开解码器
if(avcodec_open(pCodecCtx, pCodec)<0)
return -1;// 分配 video frame
pFrame=avcodec_alloc_frame();//创建一个 screen。SDL用screen显示视频。
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 32, 0);
if(!screen) {
exit(1);
}//创建一个显示到screen的图像
bmp = SDL_CreateYUVOverlay(pCodecCtx->width,
pCodecCtx->height,
SDL_YV12_OVERLAY,
screen);i=0;
while(av_read_frame(pFormatCtx, &packet)>=0) {
if(packet.stream_index==videoStream) {
// 如果这个packet是视频流的包,则解码之
avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
packet.data, packet.size);//得到视频帧?
if(frameFinished) {
SDL_LockYUVOverlay(bmp); //锁定sdl的播放表面AVPicture pict;//avpicture是avframe的子集
pict.data[0] = bmp->pixels[0];//让准备显示到屏幕的bmp与pict共用YUV数据
pict.data[1] = bmp->pixels[2];
pict.data[2] = bmp->pixels[1];pict.linesize[0] = bmp->pitches[0];
pict.linesize[1] = bmp->pitches[2];
pict.linesize[2] = bmp->pitches[1];// 把图像转到sdl使用的yuv格式。即yuv420p。
img_convert(&pict, PIX_FMT_YUV420P,
(AVPicture *)pFrame, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height);SDL_UnlockYUVOverlay(bmp); //释放overlay准备显示。
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
SDL_DisplayYUVOverlay(bmp, &rect);//显示}
}// 善后
av_free_packet(&packet);
SDL_PollEvent(&event);
switch(event.type) {
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
default:
break;
}}
av_free(pFrame);
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);return 0;
}
我用Mingw版的SDL开发包和./configure -enable-memalign-hack参数编译的ffmpeg静态库在SlickEdit+MingW下编译成功。VC的话可能要修改一些语句。因为没有处理帧同步和音频流,最后生成的是一个快速播放视频并且没有声音的播放器,考虑到没有超过一百行的代码量,的确很惊人。
自己动手写一个播放器(一)
九月 5th, 2008
对我来说视频播放器是生活中比较重要的东西。
现在比较流行的播放器了解的有一下几种,
- MPC系列,国内的暴风风暴之类的山寨机都是这个系列的,它们一般的解码都是通过ffdshow来做的,而ffdshow用到了ffmpeg。
- Mplayer, VLC这两个比较相似,都有成熟的开源社区支持并因此很有技术内涵,也都是从Linux移植到Windows的,缺点是官方版的GUI界面太简陋,影响看片的心情,好在有众多不同的编译版可以下载。
- 来自韩国的Kmplayer和GOM。Kmp功能比较多,但大部分用不到,属于华丽型的,用过一段时间,直到发现很多影片它的播放效果明显不如Mplayer,才把它换了,GOM貌似也是一个类型的,而且因为用了ffmpeg而没有开源被mplayer社区列进了黑名单,比较囧。
视频播放器最重要的功能是支持尽可能多的文件格式,尽可能地还原出视频文件的真实画质,这一点通过ffmpeg再加上real的解码器基本就可以做的很好了。
其次就是灵活的字幕功能,看美剧日漫是学外语的最佳途径,播放器应该考虑到这方面的需要,能提供灵活的显示方式,如快速切换显示语种或双语同时显示(KMP有这个功能),能提供上下文而不只是当前在说的一句话,能根据字幕内容定位播放,Mplayer有根据字幕快进后退一句话的功能,但不是很好用,最好能像foobar的乐辞插件一样,用一个窗口显示对话剧本和时间轴,拖动时间轴到某句台词上来定位播放,多加一个窗口肯定会影响观看效果,但这个功能的目标群是学外语的人,并且可以用快捷键在需要的时候再呼出来,应该很有用。
另外固定间隔的快进也不是很人性化,人们总是觉得某个场景没有意思,才会快进跳过的,而不是觉得特定的十几秒没有意思,而场景的切换一般会伴随着大面积的背景变换,如从室内走到室外,可以根据分析视频的总体背景确定场景的切换,在用户要求快进的时候自动切换到下一幕,不过这种检测可能对一幕一幕拍的很有条理的肥皂剧比较适合,要是碰到从头到尾灰蒙蒙一片的另类电影效果肯定不理想。这时候可以考虑另外一个比较容易确定的信息,音频。通过检测演员说话的间隔,也可以大概的猜测剧情的进展(除非是那种一直有一个画外音喋喋不休的片子)。把这些手段结合起来,再设定一个跳跃的最大范围,保持检测不准确时快进功能的可用性,或者用一个内部的检测准确度阀值来控制智能快进功能的使用,当算法自己都觉得不太准确的时候就用普通基于固定秒数的快进方式。显然这些方法都需要预先读取和分析视频文件信息, 限制非常大甚至不太现实,最好的解决方法是弄一个新的视频格式标准,在压制的时候直接把相关信息写人文件,扯远了,总之还是觉得用看着字幕剧本拖时间轴的方法比较实用而且靠谱。
MingW vs Cygwin
九月 2nd, 2008
首先MingW和cygwin都可以用来跨平台开发。
MinGW是Minimalistic GNU for Windows的缩写,也就是Win版的GCC。
Cygwin则是全面模拟了Linux的接口,提供给运行在它上面的的程序使用,并提供了大量现成的软件,更像是一个平台。
相对的MingW也有一个叫MSys(Minimal SYStem)的子项目,主要是提供了一个模拟Linux的Shell和一些基本的Linux工具。因为编译一个大型程序,光靠一个GCC是不够的,还需要有Autoconf等工具来配置项目,所以一般在Windows下编译ffmpeg等Linux下的大型项目都是通过Msys来完成的,当然Msys只是一个辅助环境,根本的工作还是MingW来做的。
用MingW和cygwin编译出来的程序的区别。
首先MingW和cygwin都不能让Linux下的程序直接运行在Windows上,必需通过源代码重新编译。
现代操作系统包括Windows和Linux的基本设计概念像进程线程地址空间虚拟内存这些都是大同小异的,之所以二者上的程序不能兼容,主要是它们对这些功能具体实现上的差异,首先是可执行文件的格式,Window使用PE的格式,并且要求以.EXE为后缀名。Linux则使用Elf。其次操作系统的API也不一样,如Windows用CreateProcess()创建进程,而Linux使用fork()。
所以要移植程序必然要在这些地方进行改变,MingW有专门的W32api头文件,来把代码中Linux方式的系统调用替换为对应的Windows方式。而Cygwin则通过cygwin1.dll这个文件来实现这种API的转换,并模拟一个Linux系统调用接口给程序,程序依然以Linux的方式调用系统API,只不过这个API在cygwin1.dll上,cygwin1.dll再调用Windows对应的实现,来把结果返回给程序。
可以用查看他们编译好的程序的导入表来验证这点。
二者生成的程序都是能在Windows上运行的EXE文件,显然都是PE格式,用一个PE格式查看工具检查一下就能发现,Cygwin生成的程序依然有fork()这样的Linux系统调用,但目标库是cygwin1。而MingW生成的程序,则全部使用从KERNEL32导出的标准Windows系统API。
这样看来用Mingw编译的程序性能会高一点,而且也不用带着那个接近两兆的cygwin1.dll文件。
但Cygwin对Linux的模拟比较完整,甚至有一个Cygwin X的项目,可以直接用Cygwin跑X。
另外Cygwin可以设置-mno-cygwin的flag,来使用Mingw编译。
而与Cygwin更有可比性的MSys上的工具也是通过Cygwin这种模拟的方式来提供的。
总之这两个项目有千丝万缕的关系,一个不恰当的比方,如果Mingw是MFC,Cygwin就是.NET了。
SlickEdit使用OpenCV的方法
九月 1st, 2008
使用Mingw g++编译,需要安装Mingw。http://www.mingw.org/
打开SE,Project,New,Customize,New…

Name栏输入OpenCV,Copy setting from下拉框选GNU C/C++ Wizard。

Directories里设置需要include的头文件路径。G:\OpenCV是安装目录。

打开Tools标签,Build,Options。 
link标签下设置OpenCV的库。
OK,返回新建项目对话框,输入项目名称,并在左边的Project Type中选择OpenCV。




Finsh。
去G:\OpenCV\samples\c里面找一个例子,复制它的代码来替换自动生成的空main。Ctrl+M生成。
通过HTTP代理使用SVN
八月 31st, 2008
修改%APPDATA%\Subversion目录下的servers文件。
command line版的svn http://www.sliksvn.com/en/download
写一个使用ffmpeg动态链接库的vc程序
八月 24th, 2008
在MingG下使用./configure –enable-shared –enable-memalign-hack选项编译ffmpeg,并make install。
新建一个vc控制台项目,取消 “Precompiled headers” 选项。
ALT+F7呼出项目属性面板,把c:\msys\1.0\local\include以下的目录加入到include路径。
下载http://code.google.com/p/msinttypes/downloads/list放到vc的include目录,使vc兼容c99语法。
同样因为VC和GCC的兼容问题会一些出现错误。
在合适的地方加上
#define inline _inline
#define snprintf _snprintf_s
把c:\msys\1.0\local\bin加到lib路径。
并把avcodec.lib avformat.lib avutil.lib avdevice.lib加到Additional Dependencise.
删了main文件,用ffmpeg里的apiexample.c或output_example.c代替。 c->time_base= (AVRational){1,25};把这句改为下面的形式
c->time_base.num = 1;
c->time_base.den = 25;
F5生成程序,运行的时候把提示缺少的dll从c:\msys\1.0\local\bin目录拷过来。
VC++2008下编译通过。
http://ffmpeg.mplayerhq.hu/general.html#SEC11
http://arrozcru.no-ip.org/ffmpeg_wiki/tiki-index.php?page=Static