JAVA:二进制(原码 反码 补码),位运算,移位运算,约瑟夫问题(5)

来源:互联网 发布:110端口 编辑:程序博客网 时间:2024/05/22 14:19
一.二进制,位运算,移位运算

1.二进制

对于原码, 反码, 补码而言, 需要注意以下几点:

(1).Java中没有无符号数, 换言之, Java中的数都是有符号的;

(2).二进制的最高位是符号位, 0表示正数, 1表示负数;

(3).正数的原码, 反码, 补码都一样;

(4).负数的反码=它的原码符号位不变, 其他位取反;

(5).负数的补码=它的反码+1;

(6).0的反码, 补码都是0;

(7).在计算机运算的时候, 都是以补码的方式来运算的.

2.位运算

Java中有4个位运算, 分别是按位与&, 按位或|, 按位异或^, 按位取反~, 它们的运算规则为:

3.移位运算

Java中有3个移位运算符, 分别是算术右移>>, 算术左移<<, 逻辑右移>>>, 它们的运算规则为:

4.简单的程序实例

复制代码
public class Demo1 {    public static void main(String[] args) {        System.out.println(~2);        System.out.println(2&3);        System.out.println(2|3);        System.out.println(~-5);        System.out.println(13&7);        System.out.println(5|4);        System.out.println(-3^3);    }}
复制代码

运行结果:

-3
2
3
4
5
5
-2

复制代码
public class Demo2 {    public static void main(String[] args) {        System.out.println(1>>2);        System.out.println(-1>>2);        System.out.println(1<<2);        System.out.println(-1<<2);        System.out.println(3>>>2);    }}
复制代码

运行结果:

0
-1
4
-4
0

二.约瑟夫问题

约瑟夫问题: 设编号为1,2,3...n的n个人围坐一圈, 约定编号为k(1<=k<=n)的人从1开始报数, 数到m的那个人出列, 它的下一位又从1开始报数, 数到m的那个人又出列, 依次类推, 直到所有人出列为止, 由此产生一个出队编号的序列.

复制代码
public class Demo3 {    public static void main(String[] args) {        CycleLinkList cycleLinkList=new CycleLinkList();        cycleLinkList.setCycleLinkListLength(10);        cycleLinkList.initCycleLinkList();        cycleLinkList.Josephu(4, 6);    }}/** * 节点结构 */class Node {    //编号    private int number;    //指向下一个节点的引用    private Node nextNode=null;        //构造函数    public Node(int number) {        this.number=number;    }        //设置nextNode节点    public void setNextNode(Node nextNode) {        this.nextNode = nextNode;    }        //得到nextNode节点    public Node getNextNode() {        return nextNode;    }    //得到编号    public int getNumber() {        return number;    }}/** * 循环链表 */class CycleLinkList {    //链表的长度    private int length=0;    //指向链表头结点的引用    private Node firstNode=null;        /**     * 设置链表的长度     * @param len 链表长度     */    public void setCycleLinkListLength(int len) {        this.length=len;    }        /**     * 初始化循环链表      */    public void initCycleLinkList() {        //定义一个临时节点        Node tempNode=null;        for(int i=1;i<=length;i++) {            //头节点            if(1==i) {                Node headNode=new Node(i);                this.firstNode=headNode;                tempNode=headNode;            }else {                //尾节点                if(length==i) {                    Node node=new Node(i);                    tempNode.setNextNode(node);                    tempNode=node;                    //将尾节点的nextNode引用指向链表的头节点firstNode                    tempNode.setNextNode(firstNode);                }else { //其它节                    Node node=new Node(i);                    tempNode.setNextNode(node);                    tempNode=node;                }            }        }    }        /**     * 打印循环链表      */    public void printCycleLinkList() {        Node tempNode=this.firstNode;        do {            System.out.println(tempNode.getNumber());            tempNode=tempNode.getNextNode();        } while (tempNode!=this.firstNode);    }        /**     * 约瑟夫问题     * @param k 从第k个人开始报数     * @param m 数m下     */    public void Josephu(int k, int m) {        //判断k的合法性        if( !(k>=1 && k<=this.length) ) {            System.out.println("传入的k不正确");            System.exit(-1);        }                //定义一个临时节点        Node tempNode=this.firstNode;                //先找到第k个人        for(int i=1;i<k;i++) {            tempNode=tempNode.getNextNode();        }                //数m下,将数到m的节点从循环链表中删除        //有两种情况需要考虑,        //第一种:m=1的情形        //第二种:除了第一种的特殊情况,其他的只要找到数到m节点的的前一个节点即可,即数m-1下                //第一种情形        if(1==m) {            //从当前节点依次输出出队序列            int len=this.length;            while( (len--)>0) {                System.out.println(tempNode.getNumber());                tempNode=tempNode.getNextNode();            }        }         //第二种情形        else {            //记录出队的节点数            int cnt=0;            do {                //数(m-1)下                for(int j=1;j<(m-1);j++) {                    tempNode=tempNode.getNextNode();                }                //出队的节点                System.out.println(tempNode.getNextNode().getNumber());                //记录出队的节点数                cnt++;                //删除数到m的节点                Node tempNode2=tempNode.getNextNode().getNextNode();                tempNode.setNextNode(tempNode2);                //更新tempNode,从数到m的人下一个开始报数                tempNode=tempNode2;            } while (cnt!=this.length);        }    }    }
复制代码

运行结果:

9
5
2
10
8
1
4
3
7
6

阅读全文
0 0
原创粉丝点击