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();
}
}