蛮力法(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循环做了一次组合的解,还被老师笑话了一通。哈哈,很有意思。因该部分不具备实用性,跳过。