java基础八(数组经典题)

数三退一问题:有500个小孩手拉手围成一圈,从1开始数,数3小孩退出圈外,直到最后一位小孩,求最后一位小孩的序号是?

下面给出两个方法,第一种面向过程:

public class Test1
{
	//数3退1;每数到3就退出一个人
	public static void main(String[] args)
	{
		boolean[] child = new boolean[500];
		Arrays.fill(child , true);//初始化
		//数3退1
		int leftNum = child.length;//数组中剩余的小孩数目
		int countNum = 0;//用于记录当前小孩123编号
		int index = 0;//记录小孩原始编号
		while(leftNum > 1)//只要数组中的小孩数目多于一个继续数3退1
		{
			if(child[index])
			{
				countNum ++;
				if(countNum == 3)
				{
					countNum = 0;
					child[index] = false;
					leftNum --;
				}
			}
			index ++;
			if(index == child.length)
				index = 0;
		}
		
		for (int i = 0; i < child.length; i++)
		{
			if(child[i])
				System.out.println("剩余的小孩的编号为:" + i);
		}
		
		/*for (int i = 0; i < child.length; i++)
		{
			System.out.print(child[i] + " ");
			if( (i + 1) % 10 == 0 )
				System.out.println();
		}*/
		
	}
	
}

第二张方式:面向对象:

public class Test2
{
	public static void main(String[] args)
	{
		//数3退1;每数到3就退出一个,面向对象的方法
		//面向对象,考虑问题中出现的名词:小孩类,圈类
		KidCircle kc = new KidCircle(500);
		Kid k = kc.first;//先取出kc的第一个孩子
		int countNum = 0;//用来数数,数到3退出
		
		while(kc.count > 1)
		{
			countNum ++;
			if(countNum == 3)
			{
				countNum = 0;
				kc.delete(k);
			}
			k = k.right;//因为是圆环,所以,每次取k孩子的右孩子
		}
		System.out.println("剩余的小孩的编号为:" + kc.first.id);
		
	}

}

//小孩类
class Kid
{
	int id;//小孩原始编号
	/*
	 * 每个小孩都有左小孩和右相邻小孩
	 */
	Kid left;
	Kid right;
}

//圈类
class KidCircle
{
	int count = 0;//小孩编号
	Kid first;//圈中第一个小孩
	Kid last;//圈中最后一个小孩
	
	/*
	 * 写完成员变量以后首先完成其构造方法
	 */
	public KidCircle(int n)//构造方法一般用来初始化
	{
		//构造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.left = k;
			k.right = k;
		}
		else //当前圈中有小孩情况
		{
			last.right = k;
			k.left = last;
			k.right = first;
			first.left = k;
			last = k;
		}
		count ++;
	}
	
	//向圈中删除小孩
	void delete(Kid k)
	{
		if(count <= 0)
			return;
		else if(count == 1)//这个地方为什么
		{
			first = last = null;
		}
		else 
		{
			k.left.right = k.right;
			k.right.left = k.left;
			if(k == first)//当要删除小孩为第一个小孩时
				first = k.right;
			else if(k == last) {
				last = k.left;
			}
		}
		count --;
	}
}





  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值