Q. 코드 컨벤션이란?

A. 협업시 코드를 어떤식으로 작성할건지 정하는 '약속' 이다.

개발 업무에서는 협업이 일상이기에 코드 컨벤션 만큼은 잘 지켜야한다.

 

Q. 코드 컨벤션을 쓰는 이유?

A.

1내 코드를 다른 사람이 쉽게 이해 할수 있도록
2.오랜 시간 뒤에 내가 내 코드를 알아보기 위해서
3.(중요) 취직하기 위해서
4.가독성

 

Q. 코드 컨벤션은 어떡해 쓰는건데?

A.

1.함수 중괄호 들여쓰기 방식

1-1.BSD 방식

Function()
{
  //CODE
}


1-2.K&R 방식

Function(){
  //CODE
}

 

2.코드컨벤션 규칙 :: 변수명을 정확히

//코드명을 목적에 맞춰서 이름만봐도 내용이 짐작이 되게 지어야한다.
Calss AScript (x) , Class TimeController (O)
float t (x) , float delayTime(O)
public float Get() (x) , public float GetDelayTime();

 

3.코드컨벤션의 종류
1.camelCase 소문자로 시작, 띄어쓰기 생략, 대문자로 구분
2.PascalCase 대문자로 시작, 띄어쓰기 생략, 대문자로 구분
3.snake_Case 소문자만 사용 ,띄어쓰기 대신 _ 사용
4.kebab-case 소문자만 사용 ,띄어쓰기 대신 - 사용

 

4.유니티에서의 컨벤션

유니티 엔진에서는  PascalCase 를 사용
하이어라키는 스페이스바를 허용하지만 개발자는 주로 사용X 

5.코드내에서의 컨벤션
5-1. [namespace], [class] , [struct] 는 파스칼을 사용
5-2. [함수]는 파스칼을 사용 , 함수 내부는 카멜을 사용
5-3. [Enum]는 파스칼을 사용
5-4. public 변수는 파스칼을 사용 ex) public int Num;
5-5. 나머지 변수는 _ + 카멜을 사용 ex) private int _num;

 

p.s 추가 정보

(현업에서는 언더바 잘 안씀)

(유니티는 _ 권장함) ::  ( _ 사용시 자동완성 기능 차단)

언더바( _ ) 이유는 클래스 안쪽(뒷쪽)에서 사용하는 거라고 명시하는거라고 합니다.

 

Q. 코드 컨벤션을 요약하면?

A.

1.유니티는 파스칼
2.덩치가 크거나(namespace,class,struct) 이거나 public이면 파스칼
3.non public이면 _ + 카멜
4.함수내부에서 쓰는것 카멜
5.(중요)이름 정할때 누가봐도 알 수 있도록
6. 들여쓰기 잘할것 (영역에 나눠서)
예시)for문 , Ctrl + k -> Ctrl + d 누르면 정렬 

 

733.Flood Fill 문제는 해당 좌표에서 길찾기 문제로 BFS/DFS를 이용하여 푸는 문제다.

나는 재귀함수(완벽한 BFS는 아님)를 이용하여 풀었다.

https://01149.tistory.com/71

 

733. Flood Fill (C++)

https://leetcode.com/problems/flood-fill/description/문제 해결 일자 : 2024.09.24난이도 : easy문제 풀이 /  코드 구현 :  직접 구현 / 직접 구현더보기카테고리 : 배열, DFS , BFS , Matrix문제 내용 : 좌표(sr,sc)한곳을

01149.tistory.com

 

300. Longest Increasing Subsequence 문제는 DP(동적 프로그래밍)을 사용하는 문제로

DP를 공부한 뒤 코드 구현하여 문제를 풀어냈다.

https://01149.tistory.com/72

 

300. Longest Increasing Subsequence (C++)

https://leetcode.com/problems/longest-increasing-subsequence/description/문제 해결 일자 : 2024.09.25난이도 : medium문제 풀이 / 코드 구현 :  검색 참조 / 직접 구현더보기카테고리 : 배열 , 이진검색 , 동적프로그래

01149.tistory.com

 

https://leetcode.com/problems/longest-increasing-subsequence/description/

문제 해결 일자 : 2024.09.25

난이도 : medium

문제 풀이 / 코드 구현 :  검색 참조 / 직접 구현

더보기

카테고리 : 배열 , 이진검색 , 동적프로그래밍(DP)

알고리즘 : LIS(증가하는 수열 알고리즘)


문제 내용 : 

정수 배열이 주어지는데 해당 배열에서 몇개의 정수를 지웠을때 오름차순 정렬이 되는 배열의 최대 갯수를 구하는 문제

 

문제풀이 :

오름차순 정렬이기에 배열을 순회를 돌려서 다음 숫자의 원소값이 크면 자신의 배열에 추가, 낮으면 다음 숫자를 체크하는 식으로 접근한다.

 

하지만 반복문이 돌다 보면 해당 숫자를 지우고 안지우고 유무로 배열의 가짓수가 너무 많아진다.

이 문제는 최대 갯수를 구하는 배열을 반환하는 것이 아닌 배열의 최대 갯수를 구하는것이다.

 

dp로 해당 원소일때 각 원소와의 크기를 비교하여 숫자가 크면 dp값을 증가, 작으면 다음 원소를 확인하여

진행하면된다. 

 

dp는 간단히 말하면 메모하며 풀어가기이다. 순회를 돌때마다 과거의 data를 계속 저장하고

현재의 data에 적용하는 방식이다.

dp 배열의 index는 주어진 배열의 원소 인덱스를 의미하며

dp 배열의 value는 해당 원소로 정렬 될때의 원소의 최대크기를 나타낸다.

 

접근순서 :

1. 원소에서 비교를 할때 필요한 dp 배열 하나를 선언한다.

2. dp배열의 모든 원소를 1로 초기화 해준다. (자기 자신만 있어도 배열의 크기는 1이기 때문에)

3. 숫자 비교를 하여  해당 원소가 클때마다 dp[해당 원소 인덱스]를 증가 시킨다.

3-1. 증가 시킬때 dp[i](해당 원소 인덱스)가 클지 dp[j]+1(전 원소 인덱스)이 대소 비교를하여 큰 value값을 dp[i]에 저장시키면된다. ( dp[j]+1의 +1은 과거 -> 현재로 오면서 최대 크기가 증가하였기에)

4.주어진 정수 배열을 순회 한뒤 제일 큰 value값을 반환하면된다.

 

코드구현 :

더보기
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) 
    {
        int* dp = new int[nums.size()];

        int resultMax = 1;

        for(int i = 0; i < nums.size();i++) dp[i] = 1;

        for(int i = 0; i < nums.size();i++)
        {
            for(int j =0 ; j < i; j++)
            {
                if(nums[i] > nums[j])
                {
                    dp[i] = max(dp[i],dp[j]+1);
                }

                if(dp[i] > resultMax)
                {
                    resultMax = dp[i];
                }

            }
        }

        delete[] dp;

        return resultMax;
    }
};

 

'코딩테스트 > LeetCode' 카테고리의 다른 글

LeetCode :: 733. Flood Fill (C++)  (0) 2024.09.25

https://leetcode.com/problems/flood-fill/description/

문제 해결 일자 : 2024.09.24

난이도 : easy

문제 풀이 /  코드 구현 :  직접 구현 / 직접 구현

더보기

카테고리 : 배열, DFS , BFS , Matrix


문제 내용 : 

좌표(sr,sc)한곳을 시작하여 인접하고 있는 좌표들의 value값을 바꾸는 문제이다.

이때 인접은 상,하,좌,우만 해당된다.


문제 풀이 : 

시작 좌표가 주어지고 자기 자신과 다른 value값을 가졌으면 이동하지 않으면 되고 방향(상,하,좌,우)가 정해졌기에 재귀함수로 접근하여 문제를 풀었다.

 

접근 순서:

1.시작 좌표의 value값을 변경(1 -> 2)한다.

2.방향 순서로 한칸 이동한다.

3.범위를 벗어났거나 처음Value값(1)이 다르면 돌아온다 같은경우 해당 방향으로 한칸 더 이동한다.

4. 2 - 3을 방향값을 변경하며 다 변경 될때까지 반복한다.

 

구현코드

더보기
#include <iostream>
#include <vector>

using namespace std;

class Solution
{
public:

    enum dir { UP = 1, DOWN = -1, LEFT = -1, RIGHT = 1 };

    void FindPixel(vector<vector<int>>& image, int sr, int sc, int pos,int color)
    {
        if((sr < 0 || sr >= image.size()) || (sc < 0 || sc >= image[0].size()))
        {
            return;
        }

        if (image[sr][sc] != pos)
        {
            return;
        }

        image[sr][sc] = color;

        FindPixel(image, sr + UP, sc, pos, color);
        FindPixel(image, sr + DOWN, sc, pos, color);
        FindPixel(image, sr, sc + LEFT, pos, color);
        FindPixel(image, sr, sc + RIGHT, pos, color);
    }

    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc,int color)
    {
        if (image[sr][sc] == color)
       {
           return image;
       }

        FindPixel(image, sr, sc, image[sr][sc], color);

        return image;
    }
};

 

 

'코딩테스트 > LeetCode' 카테고리의 다른 글

LeetCode :: 300. Longest Increasing Subsequence (C++)  (0) 2024.09.25

SSC_Unity 6기 C# 문법 기초 인강 수강중에 정렬 알고리즘에 대해 수강하였고 기본 정렬 알고리즘은 직접 구현하는 일은 별로 없어도 어떡해 구현 되는지는 알고 있어야하며 특징 및 시간 복잡도는 나중에도 참고할것 같아 알고리즘 게시판을 만들어 따로 작성하였다.

 

https://01149.tistory.com/69

 

기본 정렬 알고리즘 4가지 :: 선택정렬, 삽입정렬, 퀵정렬, 병합정렬 (C# 구현) 간단 요약

1.선택정렬시간 복잡도 : Best : n^2Avg : n^2Worst : n^2정수 6만개 기준 Run-time (단위: sec) : 10.842 코드구현더보기 int[] arr; arr = new int[6] { 5, 2, 4, 6, 1, 3 }; for (int i = 0; i arr[j]) { int tmp = arr[j]; arr[j] = arr[i]; arr

01149.tistory.com

 

직접 코드 구현한거라 가독성 및 최적화는 안좋을수 있습니다. 참고하시고 봐주시면 감사하겠습니다.


1.선택정렬

시간 복잡도 :

Best : n^2

Avg : n^2

Worst : n^2

정수 6만개 기준 Run-time (단위: sec) : 10.842

 

코드구현

더보기
  int[] arr;
 
 arr = new int[6] { 5, 2, 4, 6, 1, 3 };

 for (int i = 0; i < arr.Length; i++)
 {
     for(int j = i+1; j< arr.Length;j++)
     {
         //오름차순 정렬
         if (arr[i] > arr[j])
         {
             int tmp = arr[j];
             arr[j] = arr[i];
             arr[i] = tmp;
         }
     }
 }

 foreach (int num in arr)
 {
     Console.Write(num + " ");
 };
 Console.WriteLine();

2.삽입정렬

시간 복잡도 :

Best : n (데이터들이 정렬이 되있다는 가정하에)

Avg : n^2

Worst : n^2

정수 6만개 기준 Run-time (단위: sec) : 7.438

 

코드구현

더보기
  int[] arr;

arr = new int[6] { 5, 2, 4, 6, 1, 3 };

 for (int i = 1 ; i < arr.Length; i++)
 {
     int key = arr[i];
     int keyIndex = i;

     for(int j = i-1; j >= 0; j--)
     {
         if(key < arr[j])
         {
             int tmp = arr[j];
             arr[j] = key;
             arr[keyIndex] = tmp;
         }
         keyIndex--;
     }
     
 }

 foreach (int num in arr)
 {
     Console.Write(num + " ");
 };
 Console.WriteLine();

3.퀵정렬

시간 복잡도 :

Best : n log n

Avg : n log n

Worst : n^2

정수 6만개 기준 Run-time (단위: sec) : 0.014

 

코드구현

더보기
        public static int[] Swap(int[] arr,int index1,int index2)
        {
            int tmp = arr[index1];
            arr[index1] = arr[index2];
            arr[index2] = tmp;

            return arr;
        }

        public static int[] QuickSort(int[] arr, int left, int right)
        {
            if(left >= right)
            {
                return arr;
            }

            int pivot = left;
            int low = pivot + 1;
            int high = right;
            
            bool isLow = false;
            bool isHigh = false;

            while (low <= high)
            {
                if (arr[pivot] < arr[low])
                {
                    isLow = true;
                }
                else
                {
                    low++;
                }

                if (arr[pivot] > arr[high])
                {
                    isHigh = true;
                }
                else
                {
                    high--;
                }


                if (isLow && isHigh)
                {
                    arr = Swap(arr, low, high);
                    isLow = false;
                    isHigh = false;
                }

            }

            arr = Swap(arr, pivot, high);
            pivot = high; // pivot 기준으로 좌 우로 나눳기에 pivot 인덱스를 high으로 변경해줘야 정상적으로 동작함 

            arr = QuickSort(arr, left, pivot-1);
            arr = QuickSort(arr, pivot+1, right);
            return arr;
        }

        public static int[] Partition(int[] arr,int pivot, int left , int right)//분할
        {
            return arr = QuickSort(arr, left, right);
        }
 
 static void Main(string[] args)
 {
 
 int[] arr;
 //퀵정렬은 분할 정복 방법을 사용 / 과정은 분할 -> 정복 -> 결합 이다.
 //분할 : pivot을 기준으로 작은건 왼쪽 큰건 오른쪽으로 배치
 //정복 : pivot 기준으로 나눠진 배열을 정렬, 더 분할 할수 있으면 분할
 //결합 : 더이상 분할 할수가 없으면 정렬된 부분배열들 하나으 배열로 결합
 //arr = new int[6] { 5, 2, 4, 6, 1, 3 };
 arr = new int[9] { 5, 3, 8, 4, 9, 1, 6, 2, 7 };
 arr = Partition(arr,0, 0, arr.Length -1);

 foreach (int num in arr)
 {
     Console.Write(num + " ");
 };
 Console.WriteLine();
 }

4.병합정렬

시간 복잡도 :

Best : n log n

Avg : n log n

Worst : n log n

정수 6만개 기준 Run-time (단위: sec) : 0.026

 

코드구현

더보기
public static int[] Swap(int[] arr,int index1,int index2)
{
    int tmp = arr[index1];
    arr[index1] = arr[index2];
    arr[index2] = tmp;

    return arr;
}

 public static int[] Merge(int[]arr , int left, int mid ,int right)
 {
     int[] temp = new int [arr.Length]; // Merge할 새 배열 만들기

     //실제로 배열을 분할한건 아니고 index로 범위를 만들어 분할하게 가정
     int Index1 = left; //분할한 arr1의 인덱스
     int Index1Max = mid; //분할한 arr1의 범위

     int Index2 = mid+1; //분할한 arr2의 인덱스
     int Index2Max = right; //분할한 arr2의 범위

     int tempIndex = left; //위치할 arr index 위치

     while (Index1 <= Index1Max && Index2 <= Index2Max)
     {
         if (arr[Index1] > arr[Index2])
         {
             temp[tempIndex] = arr[Index2];
             tempIndex++;
             Index2++;
         }
         else
         {
             temp[tempIndex] = arr[Index1];
             tempIndex++;
             Index1++;
         }
     }
     
     for(int i = Index1; i<= Index1Max ; i++)
     {
         temp[tempIndex] = arr[i];
         tempIndex++;
     }

     for (int i = Index2; i <= Index2Max; i++)
     {
         temp[tempIndex] = arr[i];
         tempIndex++;
     }

     for (int i = left; i <= right ; i++)
     {
         arr[i] = temp[i];
     }

     return arr;
 }

 public static int[] MergeSort(int[]arr, int left ,int right)
 {
     if(left >= right)
     {
         return arr;
     }
     

     int mid = (left + right) / 2;

     arr = MergeSort(arr, left, mid);
     arr = MergeSort(arr, mid + 1, right);
     arr = Merge(arr, left,mid, right); 
     return arr;
 }

 public static int[] PartitionMerge(int[] arr, int left ,int right)
 {
     int mid = (left+right)/2;

     arr = MergeSort(arr, left, mid);
     arr = MergeSort(arr, mid+1, right);
     arr = Merge(arr, left, mid, right);
     return arr;
 }
 
  static void Main(string[] args)
 {
     int[] arr;
     
  //병합 정렬도 퀵정렬과 마찬가지로 분할 정복 방법을 이용한 정렬이다.
  arr = new int[8] { 21, 10, 12, 20, 25, 13, 15, 22 };
  arr = PartitionMerge(arr,0,arr.Length-1);
  foreach (int num in arr)
  {
      Console.Write(num + " ");
  };
  Console.WriteLine();
  }

 

Q1.C#에서 외부파일 경로 설정?

A1.

using System.IO; //파일 입출력시 해당 네임스페이스 필요함

 //빌드하는 폴더 안에 "SaveFolder"라는 명칭의 폴더 생성
  Directory.CreateDirectory("SaveFolder");
  
//경로 설정하기
//Path.Combine(string path1,string path2) 은 .NET 프레임워크에서 제공하는 메서드이다
//path1 폴더 경로를 , path2는 파일 이름을 작성하면 해당 경로를 문자열로 반환해준다.
//직접 경로를 작성 할 수 있지만 지금처럼 작성하면 ,다른 유저의 컴퓨터에서도 원활하게 접속이 가능해진다
 string filePaths = Path.Combine("SaveFolder","playerSave.txt");

 

Q2.C#에서 .txt파일 읽기?

A2.

  
  //보통 외부 파일을 읽거나 쓸때 파일을 열고 작업을 다한 뒤 닫아줘야한다.
  //하지만 c#에서는 using 메서드를 사용하면 해당 작업 중에 열려있고
  //작업을 완료하면 자동으로 닫히게 된다.
  using (StreamReader reader = new StreamReader(filePaths))
  {
  	 //filePaths에 있는 .txt 파일을 읽는 코드 작성
     List<string> loadItemData = new List<string>(); //.txt 파일을 읽은 데이터를 저장

	 //스트림의 끝(End of Stream)**에 도달했는지를 확인하는 조건
     //즉, 읽는 .txt파일의 끝이 도달할때까지 반복문이 돌아간다.
     while (reader.EndOfStream == false) 
     {
	//.txt 파일의 문자열을 한줄을 가져오는 메서드
         string readData = reader.ReadLine();
         
         //Split을 이용한 데이터 분리 후
         string[] readDatas = readData.Split(',');
         
         //Item변수에 관련된 데이터 초기화 
         ItemID id = (ItemID)int.Parse(readDatas[0]);
         bool equip = readDatas[1] == "true" ? true : false ;
         string name = readDatas[2];
         string valueLabel = readDatas[3];
         float value = float.Parse(readDatas[4]);
         string info = readDatas[5];
         int count = int.Parse(readDatas[6]);
         int countMax = int.Parse(readDatas[7]);
         int buyGold = int.Parse(readDatas[8]);
     }
  }

 

Q3.C#에서 .txt파일 쓰기?

A3.

  
  //쓰기 스트림을 호출 후 없으면 해당경로(filePaths)에 파일을 생성
  using (StreamWriter writer = File.CreateText(filePaths))
  {
  	 //문자열을 하치기 위해 StringBuilder를 호출 (미리 만들어둔 클래스에서 호출된것)
      StringBuilder builder = StrBuild.strBuilder;
	  
      //Player class의 Item List를 가져와서 초기화 하는 코드내용
      foreach (KeyValuePair<ItemID,Item> itemData in player.Items)
      {
          builder.Clear();
          builder.Append($"{(int)itemData.Key},");
          builder.Append($"{itemData.Value.Equip},");
          builder.Append($"{itemData.Value.Name},");
          builder.Append($"{itemData.Value.ValueLabel},");
          builder.Append($"{itemData.Value.Value},");
          builder.Append($"{itemData.Value.Info},");
          builder.Append($"{itemData.Value.Count},");
          builder.Append($"{itemData.Value.CountMax},");
          builder.Append($"{itemData.Value.BuyGold},");
          
          //.txt파일에 해당 문자열을 저장하는 메서드
          writer.WriteLine(builder.ToString());
      } 
  }

Q1.배열이란?

A1.<동일한 데이터 유형>을 가지는 데이터 요소들을 한번에 모아서 다룰 수 있는 구조
선언된 크기 만큼 공간을 메모리에 할당받음 -> new int[10] ; //10개 int 변수(공간)을 할당받음

 

p.s

C/C++ 에서 2차원 배열 선언시 방식이 너무 달라서 적응이 힘들었음
C/C++ : int arr[2][3];

C# : int[,] arr = new int [2,3];

Q2.컬렉션이란?

A2.C#의 자료구조를 보관하고 있는 공간이며, C/C++로 치면 STL(Standard Template Library)와 유사함

using System.Collections.Generic

네임스페이스 안에 선언하고 사용함

 

p.s 컬렉션 안에 있는 자료구조 

1)List -> C++의 vector 생각하면됨(비슷함)
2)Dictionary -> C++의 unorderedamp 생각하면됨
key와 value값으로 나눠짐 , 중복된 키값을 가질수 없음 
3)Stack -> 선입후출(LIFO)
4)Queue -> 선인선출(FIFO)
5)HashSet -> C++의 Set 생각하면됨 ,중복되지 않음

 

배열 vs List (중요)

더보기

List는 삽입,삭제과 가능하여 매우 유용하지만 남발할경우 최적화에 좋지 않다.

 

1.메모리 사용량 증가 : 리스트는 동적배열이기에 크기 조정이 가능해짐
C# List가 제너릭으로 구성되어있고 내부가 동적배열 기반으로 되어있음
add도 메서드로 호출해서 추가하는 것,  

add의 방식을 간단히 설명하면 처음 초기화시 배열[4] 만들었다고 가정했을때

배열을 초과하는 숫자로 추가되는경우 배열[4]짜리를 지우고 배열크기를 2배로 늘려서 만듬


즉, 이러한 과정때문에 실제로 List를 사용시 처리비용이 매우큼
초기화시 .Capacity를 만들어 크기를 미리 선언 하면 최적화에 도움이 됨 

 

Q3.재귀호출이란?

A3.간단히 말하면 함수 자기자신을 호출하는 것
1.자기 자신 메서드를 호출하는 것을 의미
2.재귀 호출은 문제를 작은 부분으로 분할하여 해결하는 방법 중 하나
3.작은 부분의 해결 방법이 큰문제의 해결방법과 동일한 구조를 갖고 있는 경우 적합 -> 피보나치 수열
4.재귀 호출은 호출 스택에 호출된 메서드의 정보를 순차적으로 쌓고, 메서드가 반환되면서 스택에서
순차적으로 제거되는 방식으로 동작

 

(중요)

재귀 호출 활용과 주의점
1.복잡한 문제를 단순한 방식으로 해결하는 장점
2.종료조건을 명확하게 선언 , 무한 반복으로 인해 스택 오버플로우 발생 가능성
3.메모리사용량이 더크고 실행속도가 느림, 필요한 경우에만 적절히 사용 필요

 

Q4.구조체란?

A4.여러개의 데이터를 묶어서 하나의 사용자 정의 형식으로 만들기 위한 방법
구조제는 값 형식(Value Type)으로 분류되며, 데이터를 저장하고 필요한 기능을 제공 함

 

구조체 vs 클래스 (중요)

더보기

공통점

1)모두 사용자 정의 형식을 만드는데 사용

차이점
2)구조체는 값(value)형식, 스택에 할당되고 복사될 때 값이 복사
3)클래스는 참조 형식힙에 할당되고 참조로 전달되므로 성능 측면에서 다소 차이가 있음.
4)구조체는 상속을 받을 수 없지만 , 클래스는 단일 상속 및 다중 상속이 가능하다.
5)구조체는 작은 크기의 데이터 저장이나 단순한 데이터 구조에 적합
6)클래스는 더 복잡한 객체를 표현하고 다양한 기능을 제공하기 위해 사용

+ Recent posts