2021-05-30

算法试验

试验一:统计求最大、最小元素的平均比较次数

编写一个程序,随机产生10个1~20的整数,设计一个高效算法找其中的最大元素和最小 元素,并统计元素之间的比较次数。调用该算法执行10次并求元素的平均比较次数。

import java.util.ArrayList;
import java.util.Random;

public class Experiment1 {
    private ArrayList<Integer> list = new ArrayList();
    private int length;
    private int max;
    private int min;
    private int compareNum = 0;

    //寻找最大值与最小值并返回比较次数
    private int findMaxAndMin() {
        compareNum = 0;
        max = min = list.get(0);
        for (int i = 1; i < list.size(); i++) {
            if (list.get(i) < min) {
                min = list.get(i);
                compareNum++;
                continue;
            } else if (list.get(i) > max) {
                max = list.get(i);
                compareNum++;
                continue;
            } else {
                compareNum += 2;
            }
        }
        return compareNum;
    }

    //初始化改list,并执行寻找最大值最小值方法,并返回比较次数
    public int initAListAndRunFind() {
        list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            int temp = random.nextInt(20) + 1;
            list.add(temp);
            System.out.print(temp + "  ");
        }
        System.out.println();
        length = list.size();

        int number = findMaxAndMin();
        System.out.println("最大数为:" + max + "最小数为:" + min);
        System.out.println("比较次数为:" + number);
        return number;
    }

    public static void main(String[] args) {
        Experiment1 experiment1 = new Experiment1();
        //执行十次并求出平均比较次数并输出
        double avNumber = 0;
        for (int i = 0; i < 10; i++) {
            avNumber += experiment1.initAListAndRunFind();
        }
        System.out.println("平均比较次数:" + avNumber / 10);
    }
}

试验结果:

8 16 10 15 10 16 14 17 1 9
最大数为:17最小数为:1
比较次数为:15
10 6 3 10 10 3 4 7 11 17
最大数为:17最小数为:3
比较次数为:14
16 17 19 20 16 10 8 13 7 17
最大数为:20最小数为:7
比较次数为:12
18 19 11 18 20 17 14 15 5 16
最大数为:20最小数为:5
比较次数为:14
18 7 19 16 8 12 10 5 15 14
最大数为:19最小数为:5
比较次数为:15
2 2 14 20 19 3 4 19 10 14
最大数为:20最小数为:2
比较次数为:16
7 13 1 10 15 7 8 4 7 13
最大数为:15最小数为:1
比较次数为:15
17 4 18 7 19 15 18 8 6 15
最大数为:19最小数为:4
比较次数为:15
11 14 7 15 3 2 18 15 16 18
最大数为:18最小数为:2
比较次数为:12
2 16 20 18 15 3 18 11 16 5
最大数为:20最小数为:2
比较次数为:16
平均比较次数:14.4

试验二:逆置单链表

对于不带头结点的单链表L,设计一个递归算法逆置所有节点。编写完整的实验程序,并采用相应数据进行测试。

public class Experiment {
    Link link;
    int linkLength = 1;
    Link preLink=null;
    Link nextLink = null;

    public Experiment() {
        link = new Link();
        link.data = 1;
        Link tempLink = link;
        for (int i = 0; i < 10; i++) {
            Link inLink = new Link();
            inLink.data = i + 2;
            tempLink.next = inLink;
            tempLink = inLink;
            linkLength++;
        }
    }

    public Link reverseLink(Link link){
        if(link.next==null){
            link.next = preLink;
            return link;
        }
        nextLink = link.next;
        link.next = preLink;
        preLink = link;
        return reverseLink(nextLink);
    }

    public static void main(String[] args) {
        Experiment experiment = new Experiment();
        System.out.println(new Link().print(experiment.link));
        System.out.println(experiment.linkLength);
        System.out.println(new Link().print(experiment.reverseLink(experiment.link)));
    }


}

class Link {
    Link next = null;
    int data = 0;

    public String print(Link link) {
        Link temp = link;
        String out = "单链表: ";
        while (temp != null) {
            out = out + String.valueOf(temp.data) + "  ";
            temp = temp.next;
        }
        return out;
    }
}

试验结果:
在这里插入图片描述

试验三:求解查找假币问题

编写一个程序查找假币问题。有n(n>3)个硬币,其中有一个假币,且假币较轻,采用天平称重的方式找到这个假币,并给出操作步骤。

public class Experiment {
    int[] coins;
    int coinNum;

    public Experiment() {
        Random random = new Random();
        coinNum = random.nextInt(17) + 4;//假设硬币数量是4~20个;其中一个为假币;
        int fakeCoinIndex = random.nextInt(coinNum);
        System.out.println("本次有硬币一共" + coinNum + "枚");
        coins = new int[coinNum];
        //真币的质量设置为3,假币的质量设置为2;
        Arrays.fill(coins, 3);
        coins[fakeCoinIndex] = 2;
        for (int item : coins) {
            System.out.print(item + "  ");
        }
        System.out.println();
    }

    public int balance(int begin, int end) {
        if (end - begin <= 3) {
            if (coins[begin] != coins[begin + 1]) {
                return coins[begin] < coins[begin + 1] ? begin : begin + 1;
            } else {
                return end;
            }
        } else {
            int balanceNum = (end + 1 - begin) / 2;
            int totalFront = 0;
            int totalRear = 0;
            for (int i = begin; i < begin + balanceNum; i++) {
                totalFront += coins[i];
            }
            for (int j = begin + balanceNum; j < begin + balanceNum + balanceNum; j++) {
                totalRear += coins[j];
            }
            if (totalFront < totalRear) {
                return balance(begin, begin + balanceNum - 1);
            } else if (totalFront > totalRear) {
                return balance(begin + balanceNum, begin + balanceNum + balanceNum - 1);
            } else {
                return end;
            }
        }
    }

    public static void main(String[] args) {
        Experiment experiment = new Experiment();
        int fateCoin = experiment.balance(0, experiment.coinNum - 1);
        System.out.println(fateCoin);
    }
}

试验结果:
在这里插入图片描述
在这里插入图片描述

试验四:

编写一个程序计算根号n的向下取整(根号n的下界,如2.8的下界是2),其中n是任意正整数,要求除了赋值和比较运算,该算法只能用到基本四则运算,并输出1~20的求解结果。

public class Experiment {

    public Integer compute(int n){
        for(int i=1;i<n+2;i++){
            if(i*i>n){
                return i-1;
            }
        }
        return null;
    }

    public static void main(String[] args) {
        Experiment experiment = new Experiment();
        for (int i= 1;i<=20;i++){
            System.out.println("根号"+i+"的下界为:"+experiment.compute(i));
        }
    }
}

根号1的下界为:1
根号2的下界为:1
根号3的下界为:1
根号4的下界为:2
根号5的下界为:2
根号6的下界为:2
根号7的下界为:2
根号8的下界为:2
根号9的下界为:3
根号10的下界为:3
根号11的下界为:3
根号12的下界为:3
根号13的下界为:3
根号14的下界为:3
根号15的下界为:3
根号16的下界为:4
根号17的下界为:4
根号18的下界为:4
根号19的下界为:4
根号20的下界为:4

试验五:

有12个硬币,分别用A到L表示,其中恰好有一个假币,假币的重量不同于真币,所有真币的重量相同。现在采用天平称重的方式找到这个假币,某人已经给了一种3次称重的方案。编写一个程序找到这个假币。

package unit5;

import java.util.ArrayList;
import java.util.Random;

/**
 * 试验一:
 *
 *   有12个硬币,分别用A到L表示,其中恰好有一个假币,假币的重量不同于真币,所有真币的重量
 *   相同。现在采用天平称重的方式找到这个假币,某人已经给了一种3次称重的方案。编写一个程序
 *   找到这个假币。
 *
 */
public class Experiment {
    ArrayList<Coin> coins = new ArrayList();

    //设置硬币,并随机假币及重量
    public Experiment() {
        Random random = new Random();
        int fakeCoin = random.nextInt(12);
        for (int i = 0; i < 12; i++) {
            Coin coin = new Coin();
            coin.name = String.valueOf((char) (65 + i));// + String.valueOf(i);
            coins.add(i, coin);
        }
        int newWeight = random.nextInt(2) == 0 ? -1 : 1;
        Coin c = coins.get(fakeCoin);
        c.weight += newWeight;
        coins.set(fakeCoin, c);
        for (Coin coin : coins) {
            System.out.print(coin);
        }
        System.out.println();
    }

    private Integer weight(int... index) {
        int total = 0;
        for (int i : index) {
            total += coins.get(i).weight;
        }
        return total;
    }

    /**
     * 用蛮力法及回溯法找出假币;把假币分成四份,能比较三次,只要第二次能确
     * 定某三个或三个以下的硬币中有假币,最后一次必定能找到假币
     *
     * @return Coin (假币对象)
     */
    public Coin FindFakeCoin() {
        //把硬币分成三份,先比较第一份和第二份;
        if (weight(0, 1, 2, 3) == weight(4, 5, 6, 7)) {
            System.out.println("ABCD = EFGH");
            if (weight(0, 1, 2, 8) > weight(4, 5, 9, 10)) {
                System.out.println("ABCI > EFJK");
                if (weight(0, 1, 8, 9) > weight(4, 5, 6, 7)) {
                    System.out.println("ABIJ > EFGH");
                    return coins.get(8);
                } else if (weight(0, 1, 8, 9) < weight(4, 5, 6, 7)) {
                    System.out.println("ABIJ < EFGH");
                    return coins.get(9);
                } else {
                    System.out.println("ABIJ = EFGH");
                    return coins.get(10);
                }
            } else if (weight(0, 1, 2, 8) < weight(4, 5, 9, 10)) {
                System.out.println("ABCI < EFJK");
                if (weight(8, 9) < weight(0, 1)) {
                    System.out.println("IJ < AB");
                    return coins.get(8);
                } else if (weight(8, 9) > weight(0, 1)) {
                    System.out.println("IJ > AB");
                    return coins.get(9);
                } else {
                    System.out.println("IJ = AB");
                    return coins.get(10);
                }
            } else {
                System.out.println("ABCI = EFJK");
                return coins.get(11);
            }
        } else if (weight(0, 1, 2, 3) > weight(4, 5, 6, 7)) {
            System.out.println("ABCD > EFGH");
            if (weight(0, 1, 4) > weight(2, 3, 8)) {
                System.out.println("ABE > CDI");
                if (weight(0) > weight(1)) {
                    System.out.println("A > B");
                    return coins.get(0);
                } else {
                    System.out.println("A < B");
                    return coins.get(1);
                }
            } else if (weight(0, 1, 4) < weight(2, 3, 8)) {
                System.out.println("ABE < CDI");
                if (weight(2) < weight(3)) {
                    System.out.println("C < D");
                    return coins.get(3);
                } else {
                    System.out.println("C > D");
                    return coins.get(2);
                }
            } else {
                System.out.println("ABE = CDI");
                if (weight(5) < weight(6)) {
                    System.out.println("F < G");
                    return coins.get(5);
                } else if (weight(5) > weight(6)) {
                    System.out.println("F > G");
                    return coins.get(6);
                } else {
                    System.out.println("F = G");
                    return coins.get(7);
                }
            }
        } else {
            System.out.println("ABCD < EFGH");
            if (weight(0, 1, 4) > weight(2, 3, 8)) {
                System.out.println("ABE > CDI");
                if (weight(2, 4) < weight(8, 9)) {
                    System.out.println("CE < IJ");
                    return coins.get(2);
                } else if (weight(2, 4) > weight(8, 9)) {
                    System.out.println("CE > IJ");
                    return coins.get(4);
                } else {
                    System.out.println("CE = IJ");
                    return coins.get(3);
                }
            } else if (weight(0, 1, 4) < weight(2, 3, 8)) {
                System.out.println("ABE < CDI");
                if (weight(0) < weight(1)) {
                    System.out.println("A < B");
                    return coins.get(0);
                } else {
                    System.out.println("A > B");
                    return coins.get(1);
                }
            } else {
                System.out.println("ABE = CDI");
                if (weight(5) < weight(6)) {
                    System.out.println("F < G");
                    return coins.get(6);
                } else if (weight(5) > weight(6)) {
                    System.out.println("F > G");
                    return coins.get(5);
                } else {
                    System.out.println("F = G");
                    return coins.get(7);
                }
            }
        }
    }

    public static void main(String[] args) {
        Experiment experiment = new Experiment();
        System.out.println("假币为:" + experiment.FindFakeCoin());
    }
}

class Coin {
    String name;
    int weight = 2;

    @Override
    public String toString() {
        return '{' + name +
                " , " + weight +
                '}';
    }
}

试验结果:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值