java抽象的算法0.1版本

本文介绍了如何通过编程实现寻找1000以内的水仙花数,涉及运算符、取模、除法和循环逻辑,展示了从简单理解到代码实现的过程。
摘要由CSDN通过智能技术生成

前言:算法是考验一个人解决复杂问题的能力之一

0.1版本将使用运算符 + 流程控制基础内容完成

寻找水仙花数

打印九九乘法表

斐波那契数列

计算机中除法是不取小数点后的,运算符为 /

5/2=2

计算机中取模就是我们的取余,运算符为%

5%2=1

第一题:寻找水仙花数

水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(Armstrong number),水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)。

现在甲方大大给了一个需求,寻找1000以内的水仙花数,并将文档说明和一个例子给了我们

1^3 + 5^3+ 3^3 = 153

仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身

ps:个人方法不一定试用任何人,请辩证看待

拿到一个需求后,我们第一步应该做什么?

肯定是TM的啊,不看怎么知道这个需求是什么。。。看的时候快速过一遍,知道大概的内容

看完后,我知道了这个是讲水仙花数的。。。

(还在期待什么!没了...)

(还在期待什么!没了...)

(还在期待什么!没了...)

(选看)扩展:水仙花的启源

貌美青年那喀索斯(narcissus)爱上了自己在水中的倒影,他死后化作水仙花,此花

即因之命名。

看完后,就要了,观察词与词之间的逻辑联系,减去多余的描述

指一个 3 位数,每个位上的数字的 3次幂之和等于它本身

哦,原来,核心只有这两句话,可是还有好多字,再做一次减法,直击本质,将它浓缩成一句话

 每位上的数字的 3次幂之和等于它本身,虽然不规范,但是这已经是最简单的理解了

结合给的例子,1^3 + 5^3+ 3^3 = 153

1的三次幂   = 1 * 1 * 1 = 1

5的三次幂  = 5 * 5 * 5 = 125

3的三次幂  = 3 * 3 * 3 = 27

1 + 125 + 27 = 153 

        int i = 1;
        if (1 * 1 * 1 == i)
        {
            System.out.println("是水仙花数!");
        }

计算器算出来的也是153

抽出最简单的理解进行分析:每位上的数字的 3次幂之和等于它本身    从简单到难

tips:3次幂 a * a * a

最简单的例子:1的3次幂 = 1,这个怎么用代码实现

简单判断一下,三个1的和是否等于1,代码如下。。。

        int i = 1;
        if (1 * 1 * 1 == i)
        {
            System.out.println("是水仙花数!");
        }
        else System.out.println("不是水仙花数");

那么试着打印一下,个位数中的水仙花数

重复if(a * a * a = a)这句,我们是手写10次吗,当然不是,用流程控制中的循环去自动完成

循环的核心是起点,循环体,终点

起点就是开始的点,我们要的是个位数,起点应该是什么——0

重点就是结束的点,个位数,10算个位数吗,很显然不算——9

我们循环的内容是if(a * a * a = a)

现在难点是怎么让他们自动增加和退出循环,用自增符 ++

        long l = System.nanoTime();//时间起点
        int s = 0;//起点
        int e = 9;//终点
        while (s <= e){
            if (s * s * s == s)
            {
                System.out.println(s + "是水仙花数");
            }
            s++;
        }
        long l1 = System.nanoTime();//时间终点
        System.out.println("程序运行时间:" + (l1 - l) + "纳秒");//时间过程

该程序的运行逻辑:分为两部分,第一部分计算代码的耗时,第二步部分计算各位数的水仙花数

在代码运行前,先打上一个标记,代码运行完后,再打上一个标记,两个标记之差就是运行时间,但是不一定准确,仅作参考

第二步部分的运行逻辑:变量进入while循环,当括号的内容为true(真)时,自动运行一次,花括号里的内容,s++,会在每次进入循环时,增加1,有没有看过回到过去的小说或者动漫,这就是无敌的迭代!当括号内的值变为false时,结束循环

这里我们可以知道一个程序一般情况的运行逻辑:从上到下(非特殊情况,无函数,无静态)


各位数可以完了,也能通过验证,0和1确实符号要求,现在两位数

两位数怎么获取单位数,最简单的方法,直接拆

怎么可能,两位数至少也有90个数,难不成写90个判断吗

很显然,不可能(也不算多,也就是90行而已)

核心问题就是怎么获取个位和十位数

现实中我们怎么将一个数分以10为单位的,个,十,百,千这个以10为单位

那么我们反过来,除以它就好了

例如,现在有一个80,我们名眼人就能看出来,十位是8,各位是0,怎么在80里取8呢,很简单,80除以10我们就取到8了,现在就是个位了,我们怎么取出0这个数,80除以什么等于个位上的0,

这里说到一个运算符,取模,举个例子,8%取模1=0,说简单点,就是取余的特殊版本

取模计算器 — Calculator.iO这里有一个很棒的原理解释,想具体的可以看这个

这样我们就可以先通过除法获取十位的数字,在通过取模,获取各位的数

        int i = 80;
        int shi = i / 10;//除法取十位
        int ge = i % 10;//取模取个位
        System.out.println("个位:" + ge + "," + "十位:" + shi);

        int x = 88;
        int shi1 = x / 10;//除法取十位
        int ge1 = x % 10;//取模取个位
        System.out.println("个位:" + ge1 + "," + "十位:" + shi1);

运行成功结果如下

精准拿到了十位和个位

用判断完成两位数的水仙花数

        long l = System.nanoTime();//时间起点
        int i = 10;
        while (i < 100) {


            int shi = i / 10;
            int ge = i % 10;

            if (shi * shi * shi + ge * ge * ge == i)
            {
                System.out.println("水仙花数:" + i);
            }
            i++;
        }
        System.out.println("没有水仙花数");
        long l1 = System.nanoTime();//时间终点
        System.out.println("程序运行时间:" + (l1 - l) + "纳秒");//时间过程

两位数的没有水仙花数,三位数呢,试试了

现在我们可以通过取模+除法获取十位和个位,现在三位怎么做

怎么取百位,十位,个位

举个例子:这是一个三位数——986

先将它分为三部分:百位的9,十位的8,个位的6

这是一道减法题,减去其他没有用的数字

我们要拿到百位的9,就要减去无用的8和6

模仿我们两位和一位怎么取的,除以10

986除以10=98,98除以10=9,正好我们拿到了百位的9

这里我们发现我们除以10后获得的98可以通过取模,98%10=8,获取十位的8

现在还是一个位的6,直接986%10就可得到6

翻译成代码试试

        int i = 986;
        int bai = 986 / 100;
        int shi = 986 / 10 % 10;
        int ge = 986 % 10;

        System.out.println("百位:" + bai + "," + "十位:" + shi + "," + "个位:" + ge);

正确了,加入循环,不要问为什么不用i,i只是习惯

        for (int i = 100; i < 1000; i++) {

            int bai = i / 100;
            int shi = i /10 % 10;
            int ge = i % 10;
            
            if (bai * bai * bai + shi * shi * shi + ge * ge * ge == i) {
                System.out.println(i + "是水仙花数");
            }
        }

这次用for寻写

有了三位数,我们再试试4位数

拿:4986

在前两次中,发现一个规律,最高位只要一直除以10就能得到,看看对不对

4986/10=498,498/10=49,49/10=4,哟西,这个是对的

个位一直取模也是可以做到,4986%10 = 6

中间的就是除法搭配上取模混合得到

代码如下

        int qian1 = 4986 / 1000;
        int bai1 = 4986 / 100 % 10;
        int shi1 = 4986 /10 % 10;
        int ge1 = 4986 % 10;

        System.out.println("千位:" + qian1 + "," + "百位:" + bai1 + "," + "十位:" + shi1 + "," + "个位:" + ge1);

        for (int i = 999; i < 10000; i++) {

            int qian = i / 1000;
            int bai = i / 100 % 10;
            int shi = i /10 % 10;
            int ge = i % 10;

            if (qian * qian * qian + bai * bai * bai + shi * shi * shi + ge * ge * ge == i) {
                System.out.println(i + "是水仙花数");
            }
        }
        System.out.println("4位数没有水仙花数");

计算机入门必备算法之一,水仙花数

接下来分析一下怎么解决这个问题的:

三个字,简单化,拆解化0.1版本

  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
遗传算法是一种优化算法,可以用来求函数的最大值。下面是使用遗传算法求函数最大值的Java代码示例: ```java import java.util.Random; public class GeneticAlgorithm { private static final int POPULATION_SIZE = 100; private static final double MUTATION_RATE = 0.1; private static final int NUM_GENERATIONS = 100; private static final int CHROMOSOME_LENGTH = 10; private static final double MIN_VALUE = -10.0; private static final double MAX_VALUE = 10.0; private static Random random = new Random(); private static double fitnessFunction(double[] chromosome) { double x = decodeChromosome(chromosome); return Math.sin(5.0 * Math.PI * x) / (5.0 * x * x) + Math.pow(x - 1.0, 4.0); } private static double decodeChromosome(double[] chromosome) { double value = 0.0; for (int i = 0; i < CHROMOSOME_LENGTH; i++) { value += chromosome[i] * Math.pow(2.0, CHROMOSOME_LENGTH - i - 1); } return MIN_VALUE + (MAX_VALUE - MIN_VALUE) * value / (Math.pow(2.0, CHROMOSOME_LENGTH) - 1.0); } private static double[] generateChromosome() { double[] chromosome = new double[CHROMOSOME_LENGTH]; for (int i = 0; i < CHROMOSOME_LENGTH; i++) { chromosome[i] = random.nextDouble(); } return chromosome; } private static double[][] generatePopulation() { double[][] population = new double[POPULATION_SIZE][CHROMOSOME_LENGTH]; for (int i = 0; i < POPULATION_SIZE; i++) { population[i] = generateChromosome(); } return population; } private static double[][] selectParents(double[][] population) { double[][] parents = new double[2][CHROMOSOME_LENGTH]; int index1 = random.nextInt(POPULATION_SIZE); int index2 = random.nextInt(POPULATION_SIZE); parents[0] = population[index1]; parents[1] = population[index2]; return parents; } private static double[] crossover(double[] parent1, double[] parent2) { double[] offspring = new double[CHROMOSOME_LENGTH]; int crossoverPoint = random.nextInt(CHROMOSOME_LENGTH); for (int i = 0; i < crossoverPoint; i++) { offspring[i] = parent1[i]; } for (int i = crossoverPoint; i < CHROMOSOME_LENGTH; i++) { offspring[i] = parent2[i]; } return offspring; } private static void mutate(double[] chromosome) { for (int i = 0; i < CHROMOSOME_LENGTH; i++) { if (random.nextDouble() < MUTATION_RATE) { chromosome[i] = 1.0 - chromosome[i]; } } } private static double[][] evolvePopulation(double[][] population) { double[][] newPopulation = new double[POPULATION_SIZE][CHROMOSOME_LENGTH]; for (int i = 0; i < POPULATION_SIZE; i++) { double[][] parents = selectParents(population); double[] offspring = crossover(parents[0], parents[1]); mutate(offspring); newPopulation[i] = offspring; } return newPopulation; } private static int getBestSolutionIndex(double[][] population) { int bestIndex = 0; double bestFitness = fitnessFunction(decodeChromosome(population[0])); for (int i = 1; i < POPULATION_SIZE; i++) { double fitness = fitnessFunction(decodeChromosome(population[i])); if (fitness > bestFitness) { bestIndex = i; bestFitness = fitness; } } return bestIndex; } public static void main(String[] args) { double[][] population = generatePopulation(); for (int i = 0; i < NUM_GENERATIONS; i++) { population = evolvePopulation(population); int bestIndex = getBestSolutionIndex(population); double bestFitness = fitnessFunction(decodeChromosome(population[bestIndex])); System.out.println("Generation " + (i + 1) + ": Best fitness = " + bestFitness); } } } ``` 这个示例代码使用遗传算法求解下面这个函数的最大值: f(x) = sin(5πx) / (5x^2) + (x - 1)^4 其中 x 的取值范围是 [-10, 10]。 代码中的遗传算法包括以下步骤: 1. 初始化种群,其中每个个体是一个由 0 和 1 组成的二进制串,长度为 CHROMOSOME_LENGTH。 2. 计算每个个体的适应度,也就是对应的函数值。 3. 重复以下步骤直到达到指定的迭代次数: a. 选择两个个体作为父母。 b. 使用交叉算子和变异算子生成一个新的个体。 c. 将新的个体加入新的种群中。 d. 计算新的种群中每个个体的适应度。 4. 输出最终种群中适应度最高的个体对应的函数值。 如果你想求其他函数的最大值,可以修改 fitnessFunction 方法的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值