从欧几里得开始(二)

从欧几里得开始(二)

承接上文,找到判定一个自然数约数的算法流程图是以下这幅图,经过几次修改(图中带有颜色的部分都是修改的地方)

img

用java语言采用一一对应的原则,把这幅算法图翻译成了java代码,里面的注释是标志算法图中各个部分的对应。

public class factor {
    public static void main(String[] argv)
    {
        int input_testnumber =2; // 被测试的数a    初值化
        int input_naturalnubmer =28;  //自然数N    初值化
        Boolean result;    // 测试结果, true 或者 false


        int k = 1;

        if( input_testnumber == input_naturalnubmer) result =true;  // 第一个判定过程 a=N?

        if(input_testnumber <= Math.floor(input_naturalnubmer/2)) {          // 第二个判定过程 a<=[N/2]?符号限制原因用[]代替表示取整

            for(;k<=Math.floor(input_naturalnubmer/input_testnumber);k++)   // 迭代过程开始
            {
                if(input_naturalnubmer == k*input_testnumber)              // 第三个判定过程  ak=N?
                {
                    result = true; break;   //迭代出口1,出口向外输出true
                }
            }

            result = false;                // 迭代出口2, 向外输出 false


        }
        else
            result = false;              //第二个判定过程的另外一个出口,false值

        // 到此,算法图中所有的内容都完成了,现在展示一下结果。

        //以下,这是展示结果用的
        if(result == true)
            System.out.println(input_testnumber +" 是 " + input_naturalnubmer + " 的约数 ");
        else
            System.out.println(input_testnumber + " 不是 " + input_naturalnubmer + "的约数");

    }

}

上面是很原生态的翻译,你一眼看上去会发现,这些代码是陌生的,估计只有写这个的人,或者多看几遍的人,才能清楚这个在干什么。这是一件十分糟糕的事情,但是,一些命名和编程语言内在的抽象化功能,能够使这件糟糕的事情变成好一些。

我将整个判定过程合在一起,输入是两个整数,输出是一个Boolean值,这个合起来后的名称叫factorOf

这个过程完成的是这样一个转换:factorOf : (int,int) -> Boolean

public class factor {
    public static void main(String[] argv)
    {
        int input_testnumber =2; // 被测试的数a          初值化
        int input_naturalnubmer =28;  //自然数N         初值化
        Boolean result;    // 测试结果, true 或者 false


        result = factorOf(input_testnumber, input_naturalnubmer); // 整个判定逻辑用factorOf这个过程替代

        // 到此,算法图中所有的内容都完成了,现在展示一下结果。

        //以下,这是展示结果用的
        if(result = true)
            System.out.println(input_testnumber +" 是 " + input_naturalnubmer + " 的约数 ");
        else
            System.out.println(input_testnumber + " 不是 " + input_naturalnubmer + "的约数");

    }


//这是factorOf的具体实现,其实就是将上面的代码原样写出来,把输入和输出修改成合适的变量和返回值    
    public static Boolean factorOf(int a, int N)
    {
        int k = 1;

        if( a== N) return true;  // 第一个判定过程 a=N?

        if(a <= Math.floor(N/2)) {          // 第二个判定过程 a<=[N/2]? 符号限制原因用[]代替表示取整

            for(;k<=Math.floor(N/a);k++)   // 迭代过程开始
            {
                if(N == k*a)              // 第三个判定过程  ak=N?
                {
                    return true;  //迭代出口1,出口向外输出true
                }
            }

            return false;             // 迭代出口2, 向外输出 false


        }
        else
            return false;            //第二个判定过程的另外一个出口,false值
    }
}

同样的思路,我们优化一下展示结果,把展示部分写成命名为show,

show:(Boolean, int,int) -> 对输出流产生影响(详细的说就是在console里面打字出来)

public class factor {
    public static void main(String[] argv)
    {
        int input_testnumber =2; // 被测试的数a          初值化
        int input_naturalnubmer =28;  //自然数N         初值化
        Boolean result;    // 测试结果, true 或者 false


        result = factorOf(input_testnumber, input_naturalnubmer); //

        // 到此,算法图中所有的内容都完成了,现在展示一下结果。

        //以下,这是展示结果用的
        show(result,input_testnumber,input_naturalnubmer);
    }



    public static Boolean factorOf(int a, int N)
    {
        int k = 1;

        if( a== N) return true;  // 第一个判定过程 a=N?

        if(a <= Math.floor(N/2)) {          // 第二个判定过程 a<=[N/2]?符号限制原因用[]代替表示取整

            for(;k<=Math.floor(N/a);k++)   // 迭代过程开始
            {
                if(N == k*a)              // 第三个判定过程  ak=N?
                {
                    return true;  //迭代出口1,出口向外输出true
                }
            }

            return false;             // 迭代出口2, 向外输出 false


        }
        else
            return false;            //第二个判定过程的另外一个出口,false值
    }

    public static void show(Boolean result,int a, int N)
    {
        if(result == true)
            System.out.println(a +" 是 " + N + " 的约数 ");
        else
            System.out.println(a + " 不是 " + N + "的约数");
    }
    
}

到这里,我们的主要业务代码变成:

public static void main(String[] argv)
    {
        int input_testnumber =2; // 被测试的数a          初值化
        int input_naturalnubmer =28;  //自然数N         初值化
        Boolean result;    // 测试结果, true 或者 false


        result = factorOf(input_testnumber, input_naturalnubmer); //

        // 到此,算法图中所有的内容都完成了,现在展示一下结果。

        //以下,这是展示结果用的
        show(result,input_testnumber,input_naturalnubmer);
    }

比之前短了许多,需要事先设置三个变量来保存,两个输入的整数值,一个输出结果的Boolean值;

整个流程就是,先手动设置一下要进行测试的整数,再点击一下程序运行,这个主程序自动打出判决结果,这样的流程显然不具备效率,所以输入端还需要改一下,程序至少是半自动的,循环的。

我们修改一下输入:

import java.util.Scanner;

public class factor {
    public static void main(String[] argv)
    {


            while(true) {
                Scanner input = new Scanner(System.in);

                int input_testnumber = input.nextInt(); // 被测试的数a          初值化
                int input_naturalnubmer = input.nextInt();  //自然数N         初值化
                Boolean result;    // 测试结果, true 或者 false


                result = factorOf(input_testnumber, input_naturalnubmer); //

                // 到此,算法图中所有的内容都完成了,现在展示一下结果。

                //以下,这是展示结果用的
                show(result, input_testnumber, input_naturalnubmer);
            }
    }



    public static Boolean factorOf(int a, int N)
    {
        int k = 1;

        if( a== N) return true;  // 第一个判定过程 a=N?

        if(a <= Math.floor(N/2)) {          // 第二个判定过程 a<=[N/2]?

            for(;k<=Math.floor(N/a);k++)   // 迭代过程开始
            {
                if(N == k*a)              // 第三个判定过程  ak=N?
                {
                    return true;  //迭代出口1,出口向外输出true
                }
            }

            return false;             // 迭代出口2, 向外输出 false


        }
        else
            return false;            //第二个判定过程的另外一个出口,false值
    }

    public static void show(Boolean result,int a, int N)
    {
        if(result == true)
            System.out.println(a +" is a factor of " + N);
        else
            System.out.println(a + " is not a factor of "+ N );
    }

}

主要修改地方是在业务逻辑里面,即main()函数里面,加了一层循环,每次循环里面,用Scanner类从键盘等输入里面读取整数。

23 2
23 is not a factor of 2
23 24
23 is not a factor of 24
23 46
23 is a factor of 46
1 90
1 is a factor of 90
4 60
4 is a factor of 60
2 28
2 is a factor of 28

这是运行结果,可是,这个程序没法自己终结,因为加了一层永真循环,只能强制手动结束,而且每次输入都是手动交互输入。

但是值得注意的是,这一层是输入,可以随时修改,无论修改成系统的标准输入,或者做成文件输入(从txt文件读取,从二进制文件读取..),或者修改成随机过程生成,输入这段只要保证最后的两个量被转化成int值,就能接着进行接下来正确的判断。

整个程序被分成三段:

输入---> 判断---> 展示结果

任何一段都能够单独修改,

输入这一段要求产出2个int值;

判断这一段消费2个int值,产生一个Boolean值;

展示结果这一段消费一个Boolean值,来影响标准输出。

如果这一段程序被一个循环包着,就能半自动实现输入2个整数,判断这第一个是否是第二个的约数这一件事情。

posted @ 2021-01-14 14:36  Rivenbar  阅读(91)  评论(0)    收藏  举报