蛮力法实验

一、实验目的

1 掌握蛮力法的设计思想(利用计算机去穷举所有的可能解,再从中依次找出可行解)

2 掌握蛮力法的具体实现和时间复杂度分析

3 理解蛮力法的常见特性

二、实验内容

  1. 完成百元买百鸡\串匹配问题
  2. 完成求差\分数化简问题
    • 问题分析

(1) 百元买百鸡:公鸡5元一只,母鸡3元一只,三只小鸡1元,所以就可以设公鸡i只,母鸡j只,小鸡k只,所以i+k+j=100,5*i+3*j+k/3=100,所以使用for循环,第一层循环,循环变量为公鸡数量,第二层循环,循环变量为母鸡的数量,第三层变量,循环变量为小鸡的数量,并且要注意小鸡的数量要能被3整除,最后输出方案即可;

(2)串匹配:首先将串A与串B的首字母对齐,然后逐个判断相对的字符是否相等,此时i和j都指向第一个字符

https://i-blog.csdnimg.cn/blog_migrate/345263082581b5bcf444369850879923.gif

然后当出现匹配失败的情况,将串A往后移动一个字符的位置,再继续同串B匹配此时i指向B串的第二个字符,而j仍指向A串的第一个字符,以此类推,直到匹配成功

(3)一维数组求差:首先定义一个差值,并将其初始化为0,然后运用for循环,每次都用差值减去每个数组的值,最后得出结果返回即可

(4)分式化简:要先求出分子和分母的最大公约数,运用for循环,循环变量为分子,开始逐一递减到1,每次都判断分子和分母能不能被这个循环变量整除,若能则此时的循环变量便是最大公约数,然后分子和分母同时除以最大公约数即可。

  • 问题解决
  1. 百元买百鸡:

(1)、算法描述:

算法:百元买百鸡 void getChicken()

过程:1、定义公鸡母鸡小鸡数量i,j,k;

      2、循环变量i从1到20,j从1到33,k从1到100,重复执行以下操作;

          2.1如i+j+k=100且5*i+3*j+k/3=100且k%3==0,则输出I,j,k(即百元买百鸡的方案)

    (2)、算法实现

public class ch1 {

    /*

    百元买百鸡,公鸡5元一只,母鸡3元一只,小鸡三只一元

    */

    void getChicken(){

        int i,j,k;/*定义母鸡,公鸡,小鸡数*/

        for (i=1; i<20; i++)    /*公鸡*/

            for (j=1;j<33;j++)     /*母鸡*/

                for (k=1;k<100;k++)    /*小鸡*/

                    if(i+j+k==100&&i*5+j*3+k/3==100&&k%3==0)

                        System.out.println("母鸡有:"+i+"只,"+"公鸡有:"+j+"只,"+"小鸡有:"+k+"只。");

}

   算法时间复杂度为:O(1)

(3)、运行结果

  1. 串匹配:

(1)、算法描述

算法:串匹配 getString(char []str,char []sub)

输入:字符串数组str,字符串数组sub

输出:串的位置

过程:1、定义循环变量i和j,并将其初始化为0;

      2、当主串str和子串sub都未遍历完时,重复执行以下操作:

        2.1如str[i]==sub[j],则i++;j++;

        2.2如str[i]!=sub[j],则i=i-j+1;j=0;

      3、如子串遍历完了之后,则返回i-j;

      4、返回-1(没找到);

(2)、算法实现

int getString(char[] str, char[] sub) { /*主串str,字串sub*/

        int lenStr = str.length;

        int lenSub = sub.length;

        int i = 0, j = 0;

        while (i < lenStr && j < lenSub) {

            if (str[i] == sub[j]) {

                i++;

                j++;

            } else {

                i = i - j + 1;

                j = 0;

            }

        }

        if (j >= lenSub) /*匹配完了之后如果找到则返回下标*/

            return i - j;

        return -1;

    }

}

算法时间复杂度:假设主串长度n,子串长度m,最好O(n+m),最坏O(n*m)

(3)、运行结果

  1. 一维数组求差:

(1)、算法描述:

 算法:一维数组求差 getDiffer(int a[],int n)

 输入:一维数组a[],数组长度n

 输出:一维数组之差result

 过程:1、定义整型变量result,并将其初始化为0;

       2、定义循环变量i并将其初始化为0;

       3、循环变量i从0到n-1,重复执行以下操作

         3.1、result=result-a[i];

         3.2、i++;

       4、返回result;

 (2)、算法实现:

    public class ch3 {

    /*

    一维数组求差

     */

    int getDiffer(int []a,int n){

        int result=0,i;

        for (i=0;i<n;i++){

            result=result-a[i];  /*  数组中的每个元素逐个相减  */

        }

        return result;

    }

}

算法时间复杂度为O(n);

(3)、运行结果

4、分数化简:

     (1)、算法描述:

         算法:分式化简getSimple(int a,int b)

         输入:分子a,分母b

         输出:化简后的分子和分母

         过程:1、定义循环变量i,并将其初始化为0;

               2、循环变量i从a到1,重复以下操作

                 2.1、如a%i==0&&b%i==0,则a=a/i;b=b/i;

                 2.2、i--;

               3、输出化简后的分子a和分母b

     (2)、算法实现:

             public class ch4 {

    /*

    分数化简

     */

    void getSimple(int a,int b){

        for(int i=a;i>=1;i--){     /*   从分子开始依次排查最大公约数   */

            if ((a%i==0)&&(b%i==0)){

                a=a/i;

                b=b/i;

            }

        }

        System.out.println("分式化简后为"+a+"/"+b);

    }

}

算法时间复杂度为O(n)

     (3)、运行结果

主函数

public class Main {

    public static void main(String[] args){

        /*  百元买百鸡  */

        ch1 cha1=new ch1();

        cha1.getChicken();

        /*  串匹配  */

        ch2 cha2=new ch2();

        char []s={'a','b','a','c','b','a'};/*  主串  */

        char []t={'c','b','a'};/*  子串  */

        int k;  /*  子串在主串中的位置的下标  */

        k=cha2.getString(s,t);

        System.out.println("子串在主串中的位置为"+k);

        /*  一维数组求差  */

        ch3 cha3=new ch3();

        int []m={1,5,-9,100,85,-45,62,66};

        int Differ;

        Differ = cha3.getDiffer(m,8);

        System.out.println("一维数组的差值为"+Differ);

        /*  分数化简  */

        ch4 cha4=new ch4();

        int i=16,j=36;  /*  分数16/36化简  */

        cha4.getSimple(i,j);

    }

}

五、实验结果总结

      1. 在本次蛮力法的实验中,我认识到蛮力法是一种简单直接地解决问题的方法,是一种暴力求解的方法,它的优点有适应能力很强,是唯一种几乎什么问题都能解决的一般性方法,但是它也仅限于解决小规模的问题,对于大规模的问题,它的效率会变得很低,就变得不实用了。
      2. 请列出对你实验中算法的改进之处。

对于分式化简问题,我并没有另外求分子与分母的最大公约数,而是直接用分子逐一递减来求最大公约数

      1. 列出你在本次实验中遇到的各种问题

由于对于Java语言的不熟悉,在串匹配的问题中,对于字符串数组的定义及调用屡屡碰壁,后来不断查阅资料才得以解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值