您的位置:程序门 -> 专题开发/技术/项目 -> 数据结构与算法



快速内存块的匹配算法!


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


快速内存块的匹配算法![已结贴,结贴人:bosee]
发表于:2007-06-18 00:39:12 楼主
其实是在一块大图片中查找其中的一块小图片,我已经把其内容的内存块取出,写了一个最笨的匹配算法,4层嵌套循环逐个象素比较,能正确找到图片位置,但速度很慢(在1024*1280图片中查找16*16图片,极端情况下要比较(1024-16)*(1280-16)*16*16次,在800mhz电脑上需要3秒,需求起码要快10倍)。哪位大哥能推荐一款最快速的算法吗?非常感谢!
发表于:2007-06-18 14:44:241楼 得分:0
用更快速的电脑,用双核cpu,两个线程同时比较。
发表于:2007-06-18 14:45:112楼 得分:5
代码贴出来也许可以优化
发表于:2007-06-18 15:04:213楼 得分:5
找一下kmp算法的资料,应该会有帮助
发表于:2007-06-18 21:45:244楼 得分:0
相关代码如下(vb):
blnmatch   =   false
        for   i   =   0   to   ubound(rgqsource,   2)                 'height
                for   j   =   0   to   ubound(rgqsource,   1)         'width
                        for   m   =   0   to   ubound(rgqmatch,   2)             'height
                                for   n   =   0   to   ubound(rgqmatch,   1)     'width
                                        v   =   i   +   m       'height
                                        w   =   j   +   n       'width
                                        if   w   <=   ubound(rgqsource,   1)   and   v   <=   ubound(rgqsource,   2)   then
                                                if   rgqsource(w,   v)   <>   rgqmatch(n,   m)   then
                                                        goto   nextcol
                                                end   if
                                        else
                                                goto   nextrow
                                        end   if
                                next
                        next
                        blnmatch   =   true
                        goto   nextstep
nextcol:
                next
nextrow:
        next
       
nextstep:
        if   blnmatch   =   true   then
                msgbox   "match!   x:   "   &   j   &   ",   y:   "   &   i
        else
                msgbox   "not   match! "
        end   if
发表于:2007-06-18 21:46:595楼 得分:0
其中rgqsource是大图片数组,rgqmatch是小图片数组。
发表于:2007-06-18 21:57:536楼 得分:0
用c语言写会快很多.
发表于:2007-06-18 22:31:307楼 得分:20
这东西不应该用   vb   搞的吧,   用   c   很快的,   即使最简单的写法,   一次也不应该超过   100   毫秒的吧,   简单的试了试,   在pm1.4g   上大概10毫秒   .....

#include   <stdio.h>
#include   <stdlib.h>
#include   <string.h>
#include   <time.h>

typedef   unsigned   long   pixclr;

#define width (1024)
#define height (1280)
#define scanline_dlen (1024)
#define subwidth (16)
#define subheight (16)

#define   xalgo_prekmp(   __patt__   ,   __p_len__   ,   __i__   ,   __j__   ,   __kmp_next__   ,   __compare_eq_xi_xj__   ,   __n_type__   ) \
do   { \
(__i__)   =   0; (__j__)   =   (__kmp_next__)[0]   =   (__n_type__)(-1); \
while(   (__i__)   <   (__p_len__)   ) { \
while(   (__j__)   >   -1   &&   !   (__compare_eq_xi_xj__)   ) \
(__j__)   =   (__kmp_next__)[   (__j__)   ]; \
++   (__i__);   ++   (__j__); \
if(   (__compare_eq_xi_xj__)   ) \
(__kmp_next__)[(__i__)]   =   (__kmp_next__)[(__j__)]; \
else \
(__kmp_next__)[(__i__)]   =   (__n_type__)   (__j__); \
}   }   while(0)

#define   xalgo_kmp(   __patt__   ,   __p_len__   ,   __src__   ,   __s_len__   ,   __i__   ,   __j__   ,   __kmp_next__   ,   __compare_eq_xi_yj__   ,   __pattern_find_do__   ) \
do   { \
while(   (__j__)   <=   (__s_len__)   -   (__p_len__)   ) { \
while(   __i__   >   -1   &&   !(__compare_eq_xi_yj__)   ) \
(__i__)   =   (__kmp_next__)   [   __i__   ]; \
++   (__i__)   ;   ++   (__j__); \
if(   (__i__)   > =   (__p_len__)   )   { \
__pattern_find_do__ ; \
(__i__)   =   (__kmp_next__)   [   __i__   ]; } \
}   }   while(0)

pixclr picture[   height         ][   scanline_dlen   ];
pixclr subpic   [   subheight   ][   subwidth   ];

void   check1(   int   i   ,   int   j   )
{
int   x   ;
for(   x   =   1;   x   <   subheight;   ++x   )
{
if(   0   !=   memcmp(   picture[   i   +   x   ]   +   j   ,   subpic[   x   ]   ,   subwidth   *   sizeof(   pixclr   )   )   )
return   ;
}
printf(   "match   @   %d   %d\n "   ,   i   ,   j   );
}

#define   use_kmp

void slove()
{
int   i   ;
#ifdef   use_kmp
int   kmpnext[   subwidth   +   1   ]   ,   j;
#endif

pixclr   *begin   =   picture[0]   ,   *ptr   =   begin   ,   *end   =   picture[   height   -   subheight   ];

#ifdef   use_kmp
xalgo_prekmp(   subpic[0]   ,   subwidth   ,   i   ,   j   ,   kmpnext   ,   subpic[0][i]   ==   subpic[0][j]   ,   int   );

for(   ;   ptr   !=   end;   ptr   +=   scanline_dlen   )
{
i   =   j   =   0;
xalgo_kmp(   subpic[0]   ,   subwidth   ,   ptr   ,   width   ,   i   ,   j   ,   kmpnext   ,   subpic[0][i]   ==   ptr[j]   ,  
check1(   (ptr-begin)/scanline_dlen   ,   j   -   i   ) );
}
#else
for(   ;   ptr   !=   end;   ptr   +=   scanline_dlen   )
{
for(   i   =   0;   i   <   width   -   subwidth;   ++i   )
{
if(   0   ==   memcmp(   ptr   +   i   ,   subpic[0]   ,   subwidth   *   sizeof(   pixclr   )   )   )
check1(   (ptr-begin)/scanline_dlen   ,   i   );
}
}
#endif
}

int   main()
{
int   xx;
srand(   time(0)   );
for(   xx   =   0;   xx   <   100;   ++xx   )
{
int   i   ,   j   ,   i0   ,   j0;
clock_t   clk   ;

printf(   "------round   %d   -------\n "   ,   xx   );

for(   i   =   0;   i   <   width   ;   ++i   )
for(   j   =   0;   j   <   height;   ++j   )
picture[j][i]   =   rand();

i0   =   rand()   %   (width   -   subwidth);
j0   =   rand()   %   (height   -   subheight   -   500)   +   500;

for(   i   =   0;   i   <   subwidth;   ++i   )
for(   j   =   0;   j   <   subheight;   ++j   )
subpic[j][i]   =   picture[j+j0][i+i0];

clk   =   clock();
slove();
printf(   "%d   %d   :   time   used   %lg(sec)\n "   ,   j0   ,   i0   ,   1.   *   (   clock()   -   clk   )   /   clocks_per_sec   );
}


return   0;
}

发表于:2007-06-19 08:45:348楼 得分:0
mark


快速检索

最新资讯
热门点击