利用杨辉三角形计算组合数

这一次我们用杨辉三角来计算组合数

(冥冥之中,杨辉三角和组合数有着神秘的联系)
yanghuisanjiao.jpg

对应关系如下:
组合数C(0,0)对应杨辉三角的第一行
组合数C(1,0)C(1,1)对应杨辉三角形的第二行的两列数字
组合数C(2,0)C(2,1)C(2,2)对应杨辉三角形的第三行的三列数字
........

代码部分如下

    import java.util.Scanner;

public class YanghuiTriangle {

    public static int Anynumber(int m,int n) {
        
        if(n==0||m==n)return 1;
        else
            return Anynumber(m-1,n)+Anynumber(m-1,n-1);    
    }
    
    public static void main(String[] args) {
        // TODO 自动生成的方法存根

        Scanner in=new Scanner(System.in);
        System.out.println("输入m:");
        int m=in.nextInt();
        System.out.println("输入n:");
        int n=in.nextInt();
        System.out.println("组合数为:");
        System.out.println(Anynumber(m,n));
        
    }

}

说明:
输入m,n,程序通过计算杨辉三角对应位置的数字来计算组合数C(m,n)
采用的方法是 递归

Java-产生随机数

这篇文章用来记录一下产生随机数的方法,这在java等编程语言中是经常要用到的。

使用Math.random()生成随机数

java自带的Math类中提供了产生随机数的方法。调用方法如下:
(int)(Math.random()*6)//产生0-5的随机数
Math.random()是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机double 值,通过*来扩大一下倍数来产生你想要的范围的。
注:Math.random() -- 返回0和1之间的伪随机数 可能为0,但总是小于1,[0,1)。
所以你无法通过这样的语句来随机称成一个1-10(包含10)的数字。
(int)(Math.random()*10)
正确的做法为在后面+1;否则只能生成一个0-9之间的数字。

使用Random类生成随机数

JDK提供了一个Random类,可以更方便地生成随机数
Demo:

    import java.util.*;

public class TestRandom
{
    public static void main(String[] args) 
    {
        Random rand = new Random();
        System.out.println("rand.nextBoolean():" + rand.nextBoolean());
        byte[] buffer = new byte[16];
        rand.nextBytes(buffer);
        System.out.println(Arrays.toString(buffer));
        //生成0.0~1.0之间的伪随机double数
        System.out.println("rand.nextDouble():" + rand.nextDouble());
        //生成0.0~1.0之间的伪随机float数
        System.out.println("rand.nextFloat():" + rand.nextFloat());
        //生成平均值是 0.0,标准差是 1.0的伪高斯数
        System.out.println("rand.nextGaussian():" + rand.nextGaussian());
        //生成一个处于long整数取值范围的伪随机整数
        System.out.println("rand.nextInt():" + rand.nextInt());
        //生成0~26之间的伪随机整数
        System.out.println("rand.nextInt(26):" + rand.nextInt(26));
        //生成一个处于long整数取值范围的伪随机整数
        System.out.println("rand.nextLong():" +  rand.nextLong());
    }
}

在这里需要说明一下:计算机产生的所谓的随机数都是通过某种算法来计算出来的,因此,他可能并不是“随机”的。
而这种”算法“模型在java中被称为“种子”,正如刚才所说:相同的“种子”会产生一样的随机数。
这里有一个小测试来证明:

import java.util.Random;

public class TestSeed
{
    public static void main(String[] args)
    {
        Random r1 = new Random(50);
        System.out.println("第一个种子为50的Random对象");
        System.out.println("r1.nextBoolean():\t" + r1.nextBoolean());
        System.out.println("r1.nextInt():\t\t" + r1.nextInt());
        System.out.println("r1.nextDouble():\t" + r1.nextDouble());
        System.out.println("r1.nextGaussian():\t" + r1.nextGaussian());
        System.out.println("---------------------------");
        
        Random r2 = new Random(50);
        System.out.println("第二个种子为50的Random对象");
        System.out.println("r2.nextBoolean():\t" + r2.nextBoolean());
        System.out.println("r2.nextInt():\t\t" + r2.nextInt());
        System.out.println("r2.nextDouble():\t" + r2.nextDouble());
        System.out.println("r2.nextGaussian():\t" + r2.nextGaussian());
        System.out.println("---------------------------");
        
        Random r3 = new Random(100);
        System.out.println("种子为100的Random对象");
        System.out.println("r3.nextBoolean():\t" + r3.nextBoolean());
        System.out.println("r3.nextInt():\t\t" + r3.nextInt());
        System.out.println("r3.nextDouble():\t" + r3.nextDouble());
        System.out.println("r3.nextGaussian():\t" + r3.nextGaussian());
         System.out.println("---------------------------"); 
       
        Random r4 = new Random(System.currentTimeMillis());
        System.out.println("以当前时间为种子的Random对象");
        System.out.println("r3.nextBoolean():\t" + r4.nextBoolean());
        System.out.println("r3.nextInt():\t\t" + r4.nextInt());
        System.out.println("r3.nextDouble():\t" + r4.nextDouble());
        System.out.println("r3.nextGaussian():\t" + r4.nextGaussian()); 
    }
}

由于计算机的这种特性,为了得到“更像随机数”的随机数,我们一般以当前时间为种子。

Random ran = new Random( System.currentTimeMillis() );

手写代码来实现

前边的方法都是通过或者间接通过jdk来实现随机数的生成,这种方法则是手动来写一个随机数的数学公式。
随机数.jpg

X0就相当于“种子”,当然,尽管这是我们手写的公式,但是依旧会重复。
但是当显示过2^31-2个数之后,才可能重复。

    import java.util.Scanner;

public class AnyNumbs {
    static int  count=0,num;
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Scanner in=new Scanner(System.in);
        System.out.print("");
        System.out.println("输入num:");
        num=in.nextInt();    
            System.out.println(Creat(1));
    }
    public static int Creat(int seed) {
        if(count==num)
        {
            return  seed;
        }
        else
            {
            count ++;
            return Creat((12*seed)%(int)(Math.pow(2, 27)-1)) ;
            }
    }
    
}

在这个例子里我们简化了c为0,通过输入一个数字来决定你想要第几个随机数。
通过简单的改造就可以生成任意数量的随机数。
一般我们不会使用这种方法。前两种就够用了。

Java小游戏-猜数字

程序设计思路

随机产生一个1-100的随机数字。
用户输入一个数字,然后做判断并输出判断结果。
用户根据判断结果再次决定要输入的数字。
重复上面两步,直到用户输入正确或者用户放弃输入。

程序流程图

5.jpg

程序源代码

    import java.util.Random;

    import javax.swing.JOptionPane;

    public class GuessNmberGames {

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        int question=new Random().nextInt(100) +1;
        System.out.println(question);
        while(true) {
            String answer=JOptionPane.showInputDialog("请输入你的猜想:");
            if(answer==null)System.exit(0);
            if(answer.equals(""))System.exit(0);
            int e=Integer.parseInt(answer);
            if(e!=question)
            {
                if(e>question)
                    JOptionPane.showMessageDialog(null, "大了");
                else 
                    JOptionPane.showMessageDialog(null, "小了");
            }
            else
                {
                JOptionPane.showMessageDialog(null, "老铁666");
                System.exit(0);
                
                }
                }
        }        
    }

程序结果截图

5.1.jpg

5.2.jpg

5.3.jpg

Java简单登陆(验证码问题)

程序设计思路

随机产生一个6位的字符串
读取用户输入的信息,包括账号密码。
验证用户输入的验证码是不是和产生的随机字符串一样。
如果不是一样的话就提示并且回到重新输入的界面。
如果一样的话就提示登陆成功,并且刷新验证码,以方便下一个用户的使用。

程序流程图

4.jpg

程序源代码

import java.awt.Color;
import java.awt.Component;


public static void main(String[] args) {
    // TODO 自动生成的方法存根
JFrame frame=new JFrame("登陆测试");
frame.setBounds(500, 300, 350, 200);
frame.setSize(350,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
Panel panel=new Panel();
frame.add(panel);
placeCompoents(panel);
panel.setBackground(Color.LIGHT_GRAY);
frame.setVisible(true);
}
private static void placeCompoents(Panel panel) {
    // TODO 自动生成的方法存根
panel.setLayout(null);
//姓名信息
JLabel userLabel=new JLabel("User");
userLabel.setBounds(10, 20, 80, 25);
panel.add(userLabel);
JTextField userText=new JTextField(20);
userText.setBounds(100, 20, 165, 25);
panel.add(userText);
//密码信息
JLabel passwordLabel=new JLabel("password");
passwordLabel.setBounds(10, 50, 80, 25);
panel.add(passwordLabel);
JPasswordField passwordText=new JPasswordField(20);
passwordText.setBounds(100, 50, 165, 25);
panel.add(passwordText);
//验证码信息
String code="";
for(int i=0;i<6;i++) {        
    int intVal=(int)(Math.random()*26+97);
    code=code+(char)intVal;    
}
String codex=code;
JLabel ident=new JLabel(code);
ident.setBounds(200, 80, 80, 25);
panel.add(ident);
// 验证码文本域
JLabel codes=new JLabel("codes");
codes.setBounds(10, 80, 80, 25);
panel.add(codes);
JTextField codeText=new JTextField(6);
codeText.setBounds(100, 80, 80, 25);
panel.add(codeText);
//按钮
JButton loginButton=new JButton("login");
loginButton.setBounds(100, 100, 80, 25);
panel.add(loginButton);
loginButton.addActionListener(new ActionListener() {    
public void actionPerformed(ActionEvent e) {
    String c=codeText.getText();
    String u=userText.getText();
    char[] p1=passwordText.getPassword();
    String p="";
    p=p.valueOf(p1);
    if(c.equals(codex))
         {
         JOptionPane.showMessageDialog(null,"hello "+u+",欢迎使用!祝您一天愉快");    
//             userText.setText("你妈妈喊你回家吃饭");
         passwordText.setText("");
         codeText.setText("");
         String code="";
            for(int i=0;i<6;i++) {        
                int intVal=(int)(Math.random()*26+97);
                code=code+(char)intVal;    
            }
            String codex=code;
            ident.setText(codex);
         }
     else 
         {
         JOptionPane.showMessageDialog(null,"验证码错误");         
        }     
     }         
}   );
JButton exit=new JButton("exit");
exit.addActionListener(
new ActionListener() {    
public void actionPerformed(ActionEvent e) {
    
 System.exit(0);  
}
}     );
exit.setBounds(200, 100, 80, 25);
panel.add(exit);

}

}

程序运行截图

4.1.jpg

4.2.jpg

4.3.jpg