TIL - 4

Chu_uhC·2023년 8월 28일
0

TIL

목록 보기
4/16
post-thumbnail

📄 23.08.28 ✍ 최장 증가 부분 수열

✨ 최장 증가 부분 수열 - 동적 프로그래밍의 대표적인 문제

public int LengthOfLIS(int[] nums)
{
    int[] maxLength = new int[nums.Length]; // nums의 인덱스에 맞게 최장 길이를 저장할 배열
    maxLength[0] = 1; //[0]은 항상 자기 자신 하나뿐이다.
    for (int currnetNum = 1; currnetNum < nums.Length; currnetNum++) // 그래서 [1]부터 세기 시작함
    {
        for (int i = 0; i < currnetNum; i++) // 자기 자신보다 작은 값들중에서
        {
            if (nums[currnetNum] > nums[i]) // 자기보다 작은 값일 경우
            {
                maxLength[currnetNum] = Math.Max(maxLength[currnetNum], maxLength[i]); 
                // 나의 길이와 작은 값의 길이를 비교해서 큰 값을 사용 
            }
        }
        maxLength[currnetNum]++; 
        // 비교가 끝났다면 나까지 세어서 대입한다.
    }
    return maxLength.Max(); // 마지막으로 배열 중 가장 큰 값 반환
}

// 최장 증가 부분 수열은 
// {1, 3, 5, 7, 4, 2, 6}
//  1  2  3  4  3  2  4
// 이전 숫자보다 작은 4를 계산할 땐 그전에 작은 값들중 가장 큰 수열을 들고 온다.
// 3이 가장 작으므로 '2' 그리고 자기 자신까지 세서 `3`이 된다.
// 다음 2도 마찬가지로 가장 작은값 1과 자기 자신을 세서 '2'가 된다.
// 그 결과 4가 가장 큰 값이 된다.

📌 동적 프로그래밍이란, 복잡한 문제를 풀 때 작은 문제들로 나누어서 푸는 방법
     95% 이해 완료했음 진짜

⛔ 현재까지 프로그래밍 문제 중에서 유일하게 풀지 못하고 풀이를 봤던 문제이다... 분하다🤬

⛔ 코딩 배운지 일주일이면 사용 가능한 함수들로만 이뤄져있는데 못 했다는 건 응용이 부족하다는 것!
     그리고 선배님들의 알고리즘을 더 배워야 한다는 것!

🎉 한 장 요약



📄 23.08.29 ✍ vs 델리게이트, 99패 1승 "쉽네^^"

✨ 델리게이트에 대하여 가진 최대의 의문, 이거 왜 씀?

public delegate void AttackTypeDele(StringBuilder txt, ref int damage);
// ref는 'action', `func`에서 지원 안하는 거 같길래 직접 만듦!
public AttackTypeDele physicalDmg; // 물리 공격용 대미지 계산 델리
public AttackTypeDele magicalDmg; // 마법 공격용 대미지 계산 델리

void AttackUnit(Unit target, AttackTypeDele atkTypeDelegate )
{
    StringBuilder txt = new StringBuilder($"{Name}의 공격");
    int damage = this.Atk /*target.def 개발 예정*/;
    atkTypeDelegate(txt, ref damage); 
    target.hp -= damage;
    Console.Write(txt);
    // txt는 콘솔에 함수들의 결과를 조합해서 출력하기 위한 용도
}

void SettingDele()
{
    // #1 두 가지 델리들의 차이점은 마법은 'DodgeEvent'가 없다는 것!
    physicalDmg += DodgeEvent;
    physicalDmg += DmgRange;
    physicalDmg += DmgCriticalEvent;
    magicalDmg += DmgRange;
    magicalDmg += DmgCriticalEvent;
}

void DodgeEvent(StringBuilder txt, ref int damage)
{
    int dodgePercent = 20;
    int randomNum = new Random().Next(0, 100);
    if (randomNum < dodgePercent)
    {
        damage = 0; // 회피시 대미지는 0
        txt.Append("을 회피하였습니다.");
    }
}

void DmgRange(StringBuilder txt, ref int damage)
{
	// 대미지는 90~110% 랜덤
    float dmgRange = ((float)new Random().Next(90, 111)) / 100;
    float temp = damage * dmgRange;
    damage = (int)Math.Round(temp, 0);
}

void DmgCriticalEvent(StringBuilder txt, ref int damage)
{
    if (damage == 0) // 회피 유무 체크
        return;

    int criticalPercent = 20;
    int randomNum = new Random().Next(0, 100);

    if (randomNum < criticalPercent)
    {
        damage = (int)(damage * 1.2f);
        txt.Replace("공격", "치명적인 공격"); 
    }
    txt.Append($"으로 {damage}의 피해를 입었습니다!");
}

🎊 C#을 배우며 처음 만난 고비! Delegate 돌파 성공!!

📌 나는 왜 이 때 델리게이트를 사용하였는가? 왜 함수안에 함수를 넣지 않았는가?

void AttackUnit(Unit target, attckTypeEnum Type )
{
    ~~~
    if (Type == enum.Magic)
	{
        DmgRange(txt, damage);
        DmgCriticalEvent(txt, damage);
    }
    else if (Type == enum.Physics)
	{
    	DodgeEvent(txt, damage);
    	DmgRange(txt, damage);
        DmgCriticalEvent(txt, damage);
    }
    ~~~
}

      먼저, 위아래로 생략했지만 코드가 거의 두 배가 늘어난다. 만약 공격 타입이 2개가
      아니었다면 코드도 비례하여 늘어난다!

      1. 추후 대미지 계산식에 새로운 함수가 추가되거나 제거됐을 때 분명 계산식은
         여기 뿐만 아니라 이템, 함정 등 다양하게 사용될 것인데 하나하나 수정하는 것은
         비효율적이고 위험하다.

      2. 원본의 코드처럼 파라미터로 함수를 줄 수 있다.
         거기에 더해 델리는 함수가 아닌 타입이라 같은 타입의 델리를 새로 만들어서
         인자로 줄 수 있다. 실례로 물리와 마법을 AttackTypeDele를 사용하여 만들었고,
         파라미터도 이걸로 쓴다.

      이게 끝이 아니겠지만 Delegate를 사용하다 보면 더욱 늘어날 것이다!!
      참고로 고수들의 공통 증언 "많이 씀"


📌 `StringBuilder`는 참조형이기에 `ref`를 사용하지 않아도 된다.

🔨 아쉽게도 Lambda식을 사용해보지 못 했는데 기회를 엿 볼 것!!

🔨 delegate + delegate = ? 해보자
     물리와 마법 그 하위 개념들도 생긴다면, 분명 쓸모가 있을 것이다.

🎉 한 장 요약



📄 23.08.30 ✍ 탐색 알고리즘

<// 선형 탐색 - 정렬되지 않은 배열에서 사용, O(n)
public int LinearSearch(int[] arr, int target) 
{
    for (int i = 0; i < arr.Length; i++)
    {
        if (arr[i] == target)
        {
            return i;
        }
    }
    return -1;
}
// 이진 탐색 - 정렬 된 배열에서 효율적, O(log n)
public int BinarySearch(int[] arr, int target)
{
    int left = 0;
    int right = arr.Length-1;
    while (left <=right)
    {
        int mid = (left + right) / 2;

        if (arr[mid] == target)
        {
            return mid;
        }
        else if (arr[mid] < target)
        {
            left = mid + 1;
        }
        else if (arr[mid] > target)
        {
            right = mid - 1;
        }
    }
    return -1;
}

📌 기초적인 두 가지의 탐색 알고리즘이다.

📌 선형 탐색은 말그대로 선을 쭉 따라가면서 탐색, 이진 탐색은 업다운 게임으로 생각하면 된다.

🔨 이진 탐색을 enum순으로 정리 된 배열에 사용 해보자

🎉 한 장 요약



📄 23.08.31 ✍ 공격 기능

📌 방어력 공식은 능력치 값,자료형에 따라 신중하게 선택해야한다.
    너무 수치가 작다면 10%의 감소가 반올림으로 33% 50%가 될 수도 있다.

📌 복잡한 기능일수록 호출하는 위치도 중요하다.
    잘못하다간 파라미터값만 한 줄 적을 수 있을 것 같다.

📌 스킬의 경우 각자의 개성이 강한데 오버라이드를 통하여 접근은 편하게 개성은 강하게
    해줄 수 있었던 것 같다.

⛔ 오버로딩을 단순한 곳에선 사용할 수 있지만, 복잡해질 때 구현에 실패했다.

🔨 스킬 공격의 마나 체크를 함수 내부에서하면 외부에서는 실패, 성공 상관 없이
    게임이 진행된다.
    만약 bool값을 리턴하거나 out, ret을 쓰면 진행을 되돌릴 수 있지 않을까?

🔨 유닛들의 데이터 입력, 방어력 공식을 같이 델리게이트에서 쓸 수도 있지 않았을까?
    

🎉 한 장 요약




📄 23.09.01 ✍ 협업과 팀 프로젝트

https://github.com/yjun8629/team4_assignment

📌 이전 개인 프로젝트와 거의 동일하게 진행된 팀 작업이다.
    깃 사용법, 협업에 대한 실습이 목적이 아니었나 생각한다.

📌 협업은 소통하지 않으면 혼자 하는 것보다 못하다.

📌 같은 기간에 동일한 기능을 구현한다면 협업은 좀 더 전문적이고 퀼리티 높은
    결과를 얻을 수 있다.

🔨 다음엔 사전 계획을 오랫동안 이야기해보자.

🎉 한 장 요약



📔 주간 결산

  1. 팀의 리-다 그리고 발표

사다리 타기였지만 리-다발표는 7년 만에 했다.
초등학생이 술집 가서 술 먹을 수 있을 정도의 시간이 흘렀다.
피부가 탱글탱글했던 대학교 때 추억이 떠오르는데 오늘 WIL 작성이 끝나면 맥주나 따야겠다.
예전엔 자신감 있게 발표 잘했는데 자택 근무 기간이 길었던 걸까 사교 활동을 너무 안 할 걸까?
팀원분들도 다들 열심히 하시니깐 못 먹어도 고! 발표는 하고 싶었는데 하게 되어서 다행이다.
어쨌든 최선을 다했고 남들에게 우리 팀의 결과물도 자랑했고 재밌었다.

  1. 코~드 캇!타 그리고 new 문법();

지금까지 새로운 문법들을 배워왔지만 직접 사용해보기에는 조건이 맞지 않았다.
나의 담당이 아니거나 필요없는 프로젝트거나...
하지만 코~드 캇!타에서 적극적으로 사용하기에 좋은 거 같다.
예시로 이진 탐색을 정리된 배열에 써먹거나, 출력 방식에 따라 queue, stack같은
자료 구조를 사용하기도 했다.

📌 기억해야 할 이번 주 키워드

1./* 정렬된 배열 -> 이진 탐색 */

2./* 배열 복사 */
Array.Clone()
3./* list -> arr */
List.ToArray();
profile
ChuNyan

0개의 댓글