当前位置: 代码迷 >> J2SE >> 关于500人拉成圈满三退1,调试出最后剩下的人为0,求解
  详细解决方案

关于500人拉成圈满三退1,调试出最后剩下的人为0,求解

热度:96   发布时间:2016-04-23 19:40:38.0
关于500人拉成圈满3退1,调试出最后剩下的人为0,求解
class Count3Quit2 {
public static void main(String[] args) {
int num = 500;
Circle c = new Circle(num);
int index = 0;//控制满三退一
Kid k = c.first;//控制从圈圈的第一个开始数

while(c.count > 1) {
index++;
if(index == 3) {
c.delete(k);
index = 0;
}
k = k.right;
}

System.out.println(k.id);
}
}

class Kid {
int id;
Kid right,left;
}

class Circle {
int count = 0;
Kid first,last;

Circle(int n) {
for(int i=0; i<n; i++);
add();
}

void add() {
Kid k = new Kid();
k.id = count;
if(count <= 0) {
first = k;
last = k;
k.right = k; k.left = k;//这行可否省略
} else {
last.right = k;
first.left = k;
k.left = last; k.right = first;//上面两行已经表示了k在第一个和最后一个之间,我觉得这行和上两行表示的意思是一样的,为什么不能省略这行
last = k;
}
count++;
}

void delete(Kid k) {
if(count <= 0) {
return;
} else if(count == 1) {
first = last = null;
} else {
k.right.left = k.left;
k.left.right = k.right;
if(k == first) {
first = k.right;
} else if(k == last) {
last = k.left;
}
}
count--;
}
}

我昨天跟着视频写的得出可以得出是435,今天自己写的不知道哪个地方错了,怎么都只能调试出0(疑惑处想省略的都没省略),大家能不能帮我看看错在哪里,还有两个疑惑就是第41和45行能不能省略的问题,我昨天测的第41行删掉后不会出现问题,可以得出结果:435;第45行删掉后会在14行报空指针异常,有没有大神可以帮我解说下不能去掉45行的原因
------解决思路----------------------
约瑟夫环问题

package com.timeng;

import java.util.ArrayList;  
import java.util.List;  
import java.util.Scanner;  
  
public class Yue {  
    public static void main(String[] args) {  
        Scanner scanner = new Scanner(System.in);  
        System.out.print("请输入总人数:");  
        int totalNum = scanner.nextInt();  
        System.out.print("请输入报数的大小:");  
        int cycleNum = scanner.nextInt();  
        yuesefu(totalNum, cycleNum);  
    }  
  
   public static void yuesefu(int totalNum, int countNum) {  
        // 初始化人数  
        List<Integer> start = new ArrayList<Integer>();  
        for (int i = 1; i <= totalNum; i++) {  
            start.add(i);  
        }  
        //从第K个开始计数  
        int k = 0;  
        while (start.size() >0) {  
            k = k + countNum;  
            //第m人的索引位置  
            k = k % (start.size()) - 1;  
           // 判断是否到队尾  
            if (k < 0) {  
                System.out.println(start.get(start.size()-1));  
                start.remove(start.size() - 1);  
                k = 0;  
            } else {  
                System.out.println(start.get(k));  
                start.remove(k);  
            }  
        }  
    }  
}

疑问解答:
last.right = k;
这句话:
你只是声明了last的rigth属性=k,
            first.left = k;
这句话:
你只是声明了first的left 属性=k,
而此时你的对象k只有一个属性,那就是id
如果没有 k.left = last; k.right = first;这句话,
那么你的对象k的left属性和right属性为null,
因为你一直未为其赋值

------解决思路----------------------

package net.csdn.question;

/*
 * 约瑟夫环:500人拉成圈满3退1
 */
public class Yue {
public static void main(String[] args) {
String[] strs = new String[500];
for (int i = 0; i < strs.length; i++) {
strs[i] = (i + 1) + "";
}

Collection<String> coll = new Collection<String>(strs);

// 由于最后只剩下一个人,所以需要执行499次的报三退出.
//如果多于499次那么最后一个人始终会保留.
//如果少于499次那么将列出剩余的人的列表
for (int i = 0; i < 499; i++) {
// 由于报数3退出.也就是coll.getNext().removeNext();
coll.getNext().removeNext();
// 重新赋值coll.让其等于之前的第四位,也就是现在的第三位.
coll = coll.getNext().getNext();
}

coll.printCollection();

}

}

/*
 * 此类专用于环形数据结构.
 */
class Collection<T> {
public static Collection ROOT = null;// ROOT作为根来处理尾部跳转到头部
/*
 * 这里值得注意的是由于Collection(T[])中能够对ROOT进行初始化,
 * 但是Collection(T)中没有进行初始化,所以后续如果是采用Collection(T)创建并添加对象
 * 需要单独另外初始化Collection.ROOT的值
 */
Collection<T> next;
T content;

public Collection(T contect) {
this.content = contect;
}

public Collection(T[] args) {
// 这里解决对数组进行批量存入
Collection<T> temp = this;
temp.setContent(args[0]);
ROOT = this;
for (int i = 1; i < args.length; i++) {
temp.setNext(new Collection<T>(args[i]));
temp = temp.getNext();
}
}

public boolean hasNext() {
if (next != null) {
return true;
}
return false;
}

public Collection<T> removeNext() {
// 删除下一个节点,并返回被删除的节点.如果到了末端则删除第一个节点并循环链.
Collection<T> result = null;
if (this.hasNext()) {
result = this.getNext();
if (this.getNext().hasNext()) {
// 这里是存在后面至少两个节点的情况
this.setNext(this.getNext().getNext());
} else {
// 这里是存在this后面仅有一个节点的情况
this.setNext(ROOT);
}
} else {
// 这里是this后面没有节点的情况,需要返回列首,并删除首节点,连接第二节点
result = ROOT;
ROOT = ROOT.getNext();
this.setNext(ROOT);
}

return result;
}

//这个方法用于计算出到底Collection中存放了多少个对象
public int countTInCollection(){
Collection<T> temp = this;
int result = 1;
while((temp=temp.getNext()) != this){
result ++;
}
return result;
}

//输出Collection中的所有对象
public void printCollection() {
int count = this.countTInCollection();
Collection<T> temp = this;
for(int i = 0; i< count ; i ++){
System.out.println(temp);
temp = temp.getNext();
}
}

public void setNext(Collection<T> next) {
this.next = next;
}

public Collection<T> getNext() {
if (this.hasNext()) {
return this.next;
} else {
return ROOT;
}
}

public void setContent(T content) {
this.content = content;
}

public T getContent() {
return content;
}

public String toString() {
return content.toString();
}
}

  相关解决方案