공부/C#

[C#] 배열, foreach, 셔플 코드와 이를 이용한 예제 및 로또 생성기

굴러다니다니 2023. 3. 17. 17:44
728x90

배열

 - 동일한 특성을 가지며 일정한 규칙에 따라 n개의 요소가 나열된 데이터의 집합이다.
 - 배열의 번호(index)와 번호에 대응하는 데이터들로 이루어진 자료구조를 의미한다.
 - 다수의 데이터를 효율적으로 처리 가능.

 

배열 선언 형식)
 * 만약 동일한 타입을 가지는 데이터가 n개 만큼 있다면 
type[] 배열이름 = new type[n];

으로 선언해주면 된다.

 

배열 코드 예시

int[] numArr = new int[5];
numArr[0] = 10;
numArr[1] = 30;
numArr[2] = 40;
numArr[3] = 100;
numArr[4] = 200;
Console.WriteLine(numArr[0]);
Console.WriteLine(numArr[1]);
Console.WriteLine(numArr[2]);
Console.WriteLine(numArr[3]);
Console.WriteLine(numArr[4]);

위의 코드를 실행하면 

10 30 40 100 200 이 줄넘김과 같이 나온다.

참고로 numArr[5]를 하면 indexOutOfRangeException : 인덱스가 배열 범위를 벗어났습니다. 

오류가 뜨니 선언된 크기만큼만 접근하도록 유의하자.
 배열의 타입으로 string, char, float ,,, 등등 대부분이 가능하다.

 

배열의 초기화 방법은 크게 3가지가 있다.

1. 배열의 크기를 명시하고 입력을 한다.

2. 배열의 크기를 생략하고 입력을 한다.

3. new 연산자와 크기를 모두 생략하고 입력을 한다.

코드와 함께 예시를 살펴보자.

 

1. 배열의 크기를 명시한다.

string[] strArr = new string[3] { "서울", "대전", "대구" };
for (int i = 0; i < 3; i++)
{
	Console.WriteLine(strArr[i]);
}

for (int i = 0; i < strArr.Length; i++) //따로 값 입력없이 array의 길이만큼 반복됨
{ 
	Console.WriteLine(strArr[i]);
}

위의 코드를 실행하면, 크기를 3으로 선언하고, 내용도 3개를 입력했으며, array의 길이만큼 for문을 돌아 출력하는 for문도 3번 실행되어 서울 대전 대구 가 출력된다.

 2. 배열의 크기를 생략한다.

string[] strArr2 = new string[] { "배열의 ", "크기를 ", "생략"}; //중괄호에 써넣은 만큼 자동으로 됨
for (int i =0; i < strArr2.Length; i++)
{
	Console.WriteLine(strArr2[i]);
}

위의 코드와 같이 중괄호에 내용을 넣어버리면 내용의 크기만큼 배열에 자동으로 크기가 할당된다.

3. new 연산자와 크기를 모두 생략한다.
           

int[] intArr = { 1, 2, 3 };
for (int i = 0; i < intArr.Length; i++)
{
	Console.WriteLine(intArr[i]);
}

편리한건 3의 방법이지만, 이는 좋지 못하다.

협업과 가독성 등을 위해 1의 방법으로 올바르게 코드를 작성하도록 하자.


foreach (포리치 X 포이치)

 - 배열이나 컬렉션에 주로 사용, for문보다 가독성이 좋다
 - 인덱스에 직접적으로 접근하는 방식이 없다. (람다식을 이용하지 않는 한)
 - 각 데이터 요소에 차례대로 접근하도록 해준다.
 - 배열의 끝에 도달하면 자동으로 반복이 종료된다.

형식은 다음과 같다

foreach (int item in Array)

{

}

foreach 사용 예시

int[] arrNum = new int[] { 4, 5, 6, 7 };

foreach (int item in arrNum)
{
	Console.WriteLine(item);
}

int[] scores = new int[5] { 90, 65, 34, 65, 34 };
int sum = 0;
foreach (int item in scores)
{
	Console.WriteLine(item);
}

foreach(int score in scores)
{
	sum += score;
}
int average = sum / scores.Length;

arrNum에 4, 5, 6, 7을 담아 배열을 만들어 주었다.

foreach는 arrNum에 순서대로 접근해 item으로 이를 받아 출력한다.

scores 같은 경우, 똑같이 출력한 뒤 sum에 이를 더해 총 과목의 합을 나타내었고, 마치막은 평균을 구해주는 average까지 응용을 한 경우이다.


위의 내용을 응용하여 예제를 풀어보자.

 

예제 1.

몬스터 10마리의 공격력을 입력하고 입력한 값을 배열에 저장한다
            총 공격력과 평균 공격력을 구하라.

int[] arrAtk = new int[10];
int sumAtk = 0;
int avrAtk = 0;
for (int i = 0; i < arrAtk.Length; i++)
{
	Console.Write("몬스터{0}의 공격력을 입력해주세요: ", i+1);
	arrAtk[i] = int.Parse(Console.ReadLine());
	sumAtk += arrAtk[i];
}
avrAtk = sumAtk / arrAtk.Length;
Console.WriteLine("몬스터들의 총 공격력은 {0}이며, 평균 공격력은 {1}입니다.", sumAtk, avrAtk);

 

예제 2. 

배열을 이용해 입력받은 값의 구구단을 출력하라.

int[] guguArr = new int[9];
int inputNum = int.Parse(Console.ReadLine());
for (int i = 0; i < guguArr.Length; i++)
{
	guguArr[i] = inputNum * (i + 1);
}
for (int i = 0; i < guguArr.Length; i++)
{
	Console.WriteLine("{0} * {1} = {2}", inputNum, i + 1, guguArr[i]);
}

특이점으로 0~9까지 for문을 돌면서 array에 바로바로 계산을 해주며 값을 넣어줬다.


이전의 random 함수와 오늘의 배열 함수를 적용해 셔플 알고리즘을 배워보자.
           

int[] numberArr = new int[10];
int dest;
int sour;
int temp;
Random random = new Random();

for (int i = 0; i < numberArr.Length; i++)   //numberArr 0번째 : 0 1번째 : 1 값 할당
{
	numberArr[i] = i;
}
Console.WriteLine("셔플 전 numberArr의 데이터 : ");
for (int i = 0; i < numberArr.Length; i++)
{
	Console.Write("{0}  ", numberArr[i]);
}
Console.WriteLine();

Console.WriteLine("셔플 후 numberArr의 데이터 : ");
for (int i = 0; i < 1000; i++)
{
	dest = random.Next(10); //0~9
	sour = random.Next(10);
	temp = numberArr[dest];
	numberArr[dest] = numberArr[sour];
	numberArr[sour] = temp;
}
for (int i = 0; i < numberArr.Length; i++)
{
	Console.Write("{0}  ", numberArr[i]);
}
Console.WriteLine();

//numberArr의 array에 있는 dest번째 숫자랑 sour번째 숫자 자리 바꿈 (dest도 0~9 랜덤, sour도 0~9 랜덤)

 

첫번째 for문을 통해 numberArr의 값을 해당 i값으로 초기화를 시ㅕ주었다.

셔플하기 전 데이터를 출력해보면 모든 값이 순서대로 나온다.

셔플을 하기 위해 for문을 1000번 반복하게 만들었다.

0~9까지의 숫자중 랜덤하게 값을 가지는 dest 와 sour이라는 변수를 선언 및 초기화를 시켰다.

temp를 사용해 numberArr의 dest번째에 존재하는 값과 numberArr의 sour번째에 존재하는 값을 교환해주었고, 이를 1000번 반복하면 결국 0~9가 랜덤한 순서로 배열에 들어있다.

실제로 이를 실행해보면 다음과 같은 출력결과가 나온다.

 

이를 응용해 다음 예제를 풀어보자.

 

 

예제 3. 로또번호 생성기

1~45를 담은 배열을 섞은 다음 6개의 번호만 출력해보아라

 

int[] lot = new int[45];
for (int i = 0; i < lot.Length; i++)
{
	lot[i] = i + 1;
}
int first;
int second;

for (int i = 0; i < 1000; i++)
{
	first = random.Next(45);
	second = random.Next(45);
	temp = lot[first];
	lot[first] = lot[second];
	lot[second] = temp;
}
Console.Write("\n오늘의 로또 번호는 : ");
for (int i = 0; i < 6; i++)
{
	Console.Write("{0}  ",lot[i]);
}
Console.WriteLine();
728x90