[笔记]蛮力法

  蛮力法(brute force method),也称穷举法,是一种简单而直接地解决问题的方法,常常直接基于问题的描述,因此,也是最容易应用的方法。

蛮力法的设计思想

  满立法所依赖的技术是扫描技术,即采用一定的策略将待求解问题的所有元素依次处理一次,从而找出问题的解。依次处理所有元素是蛮力法的关键,为了避免陷入重复试探,赢保证处理过的元素不再被处理。

查找问题中的蛮力法

顺序查找

  顺序查找从表的一端向另一端将元素与给定值进行比较,若相等,则查找成功,给出该元素在表中的位置;若整个表检测完仍未找到与给定值相等的元素,则查找失败,给出失败信息。
  查找方式:

int SeqSearch1(int r[], int n, int k) //数组r[1]~r[n]存放查找集合
{
    i = n;
    while(i > 0 && r[i] != k)
    {
        i--;
    }

    return i;
}

  改进方法可以通过设置哨兵,免去每次比较后都要判断查找位置是否越界,提高查找速度。

int SeqSearch2(int r[], int n, int k) //数组r[1]~r[n]存放查找集合
{
    r[0] = k;
    i = n;
    while(r[i] != k)
    {
        i--;
    }

    retunr i;
}

串匹配问题

概念:给定两个串$S="s_1s_2...s_n"$和$T="t_1t_2..t_m"$,在主串S中查找子串T的过程称之为串匹配(也称模式匹配),T称为模式。
  基础蛮力型解法:

int Violent_Str_Match(char *s, char *p)
{
    int sLen = strlen(s);
    int pLen = strlen(p);

    int i = 0;
    int j = 0;

    while(i < sLen && j < pLen)
    {
        if(s[i] == p[j])
        {
            i++;
            j++;
        }
        else
        {
            i = i - j + 1;
            j = 0;
        }
    }

    //匹配成功,返回模式串p在文本串s中的位置,否则返回-1
    if(j == pLen)
        return i - j;
    else
        return -1;

}

KMP方法:
  讲解可以参考:从头到尾彻底理解KMP
  完整例子如下:

#include 
#include 
#include 

/***
优化后的Next数组求法
****/
void GetNextVal(char *p, int next[])
{
    int pLen = strlen(p);
    next[0] = -1;
    int k = -1;
    int j = 0;

    while(j < pLen - 1)
    {
        /* p[k]表示前缀,p[j]表示后缀*/
        if(k == -1 || p[j] == p[k])
        {
            ++j;
            ++k;
            if(p[j] != p[k])
            {
                next[j] = k;
            }
            else
            {
                next[j] = next[k];
            }
        }
        else
        {
            k = next[k];
        }

    }
}

int KmpSearch(char *s, char *p)
{
    int i = 0;
    int j = 0;
    int sLen = strlen(s);
    int pLen = strlen(p);
    int *next = NULL;

    next = (int *)malloc(sizeof(int)*pLen);
    if(NULL == next)
    {
        return -1;
    }
    memset(next,0,sizeof(int)*pLen);

    while(i < sLen && j < pLen)
    {
        //如果j==-1,或者当前字符串匹配成功,即(S[i]==P[j]),都令  i++,j++
        if(j == -1 || s[i] == p[j])
        {
            i++;
            j++;
        }
        else
        {
            //若果j!=-1,且当前字符匹配失败,即(s[i]!=p[j]),则令i不变,j=next[j]
            j = next[j];
        }
    }

    free(next);
    if(j == pLen)
    {
        return i - j;
    }
    else
    {
        return -1;
    }
}

int main(int argc, char const *argv[])
{
    int index = 0;

    char T[] = "ababxbababcadfdsss";
    char P[] = "ababx";
    printf("%s\n",T);
    printf("%s\n",P );

    index = KmpSearch(T, P);

    printf("%d\n", index);
    return 0;
}

排序问题中的蛮力法

  选择排序和起泡排序是应用蛮力法设计排序算法最直观的例子,它们都以一种清晰的方式应用了蛮力法。

选择排序

  思路很简单,直接上代码:

//数组从下标1开始
void SelectSort(int r[], int n)
{
    int tmp;
    //对n个记录进行n-1趟简单选择排序
    for(i = 1; i < n-1; i++)
    {
        index = i;
        //在无序区中找最小记录
        for(j=i+1; j <=n; j++)
            if(r[j] < r[index])
                index = j;
        //若最小记录不在最终位置则交换
        if(index != i)
        {
            tmp = r[i];
            r[i] = r[index];
            r[index] = tmp;
        }
    }
}

组合问题中的蛮力法

  对于组合问题来说,穷举查找是一种最简单的蛮力方法,它要求生成依次考察问题域中的每一个元素,从中选出满足问题约束的元素。对组合问题应用蛮力法,除非问题规模很小,否则会由于问题的解空间太大而产生组合爆炸现象。从前用多重for循环做了一次组合的解,还被老师笑话了一通。哈哈,很有意思。因该部分不具备实用性,跳过。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇