본문 바로가기

Programming/Java

실생활에서 쓸수있을만한 객체기반 반복문, 조건문 예제.

때는 한시간전이었다. 




이 대화에서부터 이 뻘짓은 시작이 되었다. 


대화에서 문제를 도출해내면. (뒤에도 대화내용이 있긴 함.) 


1. 사원은50명이 있다. 


2. 화장실에 있는 대변기는 총 5개. 


3. 하루에 한번씩 무조건적으로 대변기를 이용을 한다.


4. A가 쓴 대변기를 이후에 B라는사람이 이어서 바로쓰게될 확률은 ? 


확률을 계산할 자신이 없는 본인은 그냥 1000번의 테스트를 해주기로 함. (실제로는 좀 더 정확한 값을 얻고싶어서 후에 100,000회의 테스트를 함.)


일단 본인은 사원정보를 가질 사원클래스, 대변기의 정보 ( 몇사로 대변기인지, 누가누가 왔다갔는지 정보를 저장할수있기위해), 그리고 종합적으로 계산을 수행할 main클래스 총 3개의 클래스로 구성해 보았다. 


먼저 사원정보를 가지는 클래스이다.

 public class Salaryman {
	private String name;
	public Salaryman() {
		this.name = "그외인물";
	}
	public Salaryman(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public String toString() {
		return name;
	}

	public boolean equals(Salaryman s) {
		if(this.name.equals("그외인물")||s.getName().equals("그외인물"))
			return false;
		
		if(this.name.equals(s.getName())) {
			return true;
		}
		
		return false;
	}
}


생성자를 두개를 받았는데 원하는 사원정보, 위에서는 A와 B 말고는 따로 설정을 해줄 필요가 없기때문에 그냥 기본생성자로해서 그외인물이라고 초기화를 해 줄수 있다. 


equals는 Object객체에 있는 메소드를 오버라이딩한 것인데, 그외인물일경우에는 볼필요가 없기 때문에, 바로 false, 아니면 확인해보고 true리턴, 그것도 아니라면 false리턴. toString은 디버깅할때 보기 편하고 코딩하기 편하게 하기 위해서 그냥 name을 리턴해준 모습.


화장실(변기)클래스


import java.util.ArrayList;
import java.util.List;

public class Toilet {
	private int toiletNum = -1;
	private List<Salaryman> toiletUserList = new ArrayList<>();
	public Toilet(int toiletNum) {
			this.toiletNum = toiletNum;
	}
	public void addUser(Salaryman sMan) {
		toiletUserList.add(sMan);
	}
	public boolean checkAnswer(Salaryman sManBefore, Salaryman sManAfter) {
		for(int i = 0; i < toiletUserList.size()-1; i++) {
			Salaryman toiletUserBefore = toiletUserList.get(i);
			Salaryman toiletUserAfter = toiletUserList.get(i+1);
			
			if(toiletUserBefore.equals(sManBefore)&&
					toiletUserAfter.equals(sManAfter)
					) {
				showToiletData();
				return true;
			}
		}
		return false;
	}
	private void showToiletData() {
		System.out.println(toiletNum+"번째 똥간 이용현황 보기 : "+toiletUserList.toString());
	}
	public void clearList() {
		toiletUserList = new ArrayList<>();
	}
}

누가누가 왔다갔는지 알아야 하기때문에 ArrayList를 사용했다. 순차적으로 자료가 들어오기때문에 ArrayList가 가장 적절해보여서 이것으로 채택. 

toiletNum은 고유한 사로 번호이다. -_-;;

checkAnswer를 통해서 두명이 인접했는지 아닌지를 확인해 볼 수 있으며, showToiletData()를 통해서, 맞을경우 ArrayList가 어떻게 구성이 되어있는지 볼 수 있게 하였다. 그리고 한번한번 반복할 때 마다 (즉, 하루가 지난다고 생각하면) 화장실순서는 필요가 없어지니 clearList로 초기화 해 주는 모습.


main클래스이다.

public class Main {
	public static void main(String[] args) {
		final int TIMES_REPLAY = 100000;
		Salaryman[] salArr = new Salaryman[50];
		Toilet[] toiletArr = new Toilet[5];
		int counter = 0;
		
		for(int i = 0; i < toiletArr.length; i++) {
			toiletArr[i] = new Toilet(i+1);
		}
		
		for(int i = 0; i < TIMES_REPLAY; i++) {
			for(int j = 0; j < salArr.length; j++) {
				salArr[j] = new Salaryman();
			}
			int randNo1 = (int)(Math.random()*salArr.length);
			int randNo2 = randNo1;
			while(true) {
				randNo2 = (int)(Math.random()*salArr.length);
				if(randNo1!=randNo2) {
					break;
				}
			}
			
			salArr[randNo1] = new Salaryman("A");
			salArr[randNo2] = new Salaryman("B");
			
			for(int j = 0; j < salArr.length; j++) {
				int toiletNum = (int)(Math.random()*5);
				toiletArr[toiletNum].addUser(salArr[j]);	
			}
			for(int j = 0; j < toiletArr.length; j++) {
				if(toiletArr[j].checkAnswer(salArr[randNo1], salArr[randNo2])) {
					counter++;
				}
				toiletArr[j].clearList();
			}
		}
		System.out.println(TIMES_REPLAY+ "회 실행결과 만족하는 결과는 " + counter + "회 입니다");
	}
}

randNo1, 2, 를 통해서 몇번째 배열에 구하는 사람(a, b)가 들어가는지 세팅을 해준다. 원래는 저 반복문 박에 있었는데, 그렇게 되면 매일매일 화장실 가는 순서가 똑같은 순서가 되기에 말이 안됨으로(사실은 자료값이 너무 들쑥날쑥하게 변해서 원인을 분석하니 저기에 있었음.), 반복문안에 넣어준 모습니다. 



대충 100000회 실행결과 1800에서 왔다갔다 하는듯.