ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 230828-temp
    C#/C# 알고리즘 2023. 8. 28. 23:54

    I. 알고리즘 - 프로그래머스

    1. 두 정수 사이의 합

    두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴하는 함수, solution을 완성하세요.

     

    예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다.

    제한 조건
    a와 b가 같은 경우는 둘 중 아무 수나 리턴하세요.
    a와 b는 -10,000,000 이상 10,000,000 이하인 정수입니다.
    a와 b의 대소관계는 정해져있지 않습니다.

     

    !! 나의 풀이

    public class Solution {
        public long solution(int a, int b) {
            long answer = 0;
            long a_temp = (long)a;
            long b_temp = (long)b;
            long c = (long)a;
            if (a_temp > b_temp)
            {
                a_temp = b_temp;
                b_temp = c;
            }
            for (long i = a_temp; i < b_temp + 1; i++)
            {
                answer+=i;
            }
            return answer;
        }
    }

     

    !! 모범 풀이

    public class Solution {
        public long solution(int a, int b) {
            long answer = 0;
    
            while (a != b)
            {
                answer += a;
                a = (a > b) ? a - 1 : a + 1;
            }
    
            return answer + b;

     

    깨달은 점.

     

     1. 자료형에서 a와 b를 굳이 long으로 바꾸지 않아도 됐었다.

       => a와 b 사이의 합만 int 자료형의 범위를 넘어설 가능성이 있고, a와 b 사이의 수는 무조건 int 자료형을 지니고 있기 때문이다.

     

    2. a와 b의 대소비교를 위해 굳이 새로운 변수를 선언하지 않아도 됐었다.

      => while문을 사용하여 a를 b가 될 때까지 대소비교에 따라 더하고 빼는 것을 반복해서 구현하였다.

     

     

    2. 콜라즈 추측

    1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될 때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다.

    1-1. 입력된 수가 짝수라면 2로 나눕니다. 
    1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다. 
    2. 결과로 나온 수에 같은 작업을 1이 될 때까지 반복합니다. 
    예를 들어, 주어진 수가 6이라면 6 → 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 이 되어 총 8번 만에 1이 됩니다. 위 작업을 몇 번이나 반복해야 하는지 반환하는 함수, solution을 완성해 주세요. 단, 주어진 수가 1인 경우에는 0을, 작업을 500번 반복할 때까지 1이 되지 않는다면 –1을 반환해 주세요.

     

    제한 사항
    입력된 수, num은 1 이상 8,000,000 미만인 정수입니다.

     


    입출력 예

     

    !! 나의 풀이

    public class Solution {
        public int solution(int num) {
            int answer = 0;
            long longNum = (long)num;
            
            // 최초에는 int num을 그대로 아래의 반복문에 집어넣었었음....
            while (answer < 500)
            {
                if (longNum == 1)
                {
                    return answer;
                    break;
                }
                if (longNum % 2 == 0)
                {
                    answer += 1;
                    longNum /= 2;
                }
                else
                {
                    answer += 1;
                    longNum *= 3;
                    longNum += 1;
                }  
            }
            answer = -1;
            return answer;
        }
    }

     

    !! 모범풀이

    public class Solution {
        public int solution(int num) {
            long lNum = num;
            for (int i = 0; i < 500; i++)
            {
                if (lNum == 1) return i;
                lNum = lNum % 2 == 0 ? lNum / 2 : lNum * 3 + 1;                        
            }
            return -1;        
        }
    }

     

    깨달은 점

     

    1. 코드를 짤 때, 자료형에 대한 고찰이 필요하다.

    => 주어진 조건에서 num은 800만 이하의 양수인 정수로, 정수형이였다.

         최초에 626331을 주어진 자료형인 정수형으로 반복문을 돌렸을 때, 500회 이상이 아닌, 488회가 나왔었다.

         알고보니 연산의 중간에서, int 자료형의 범위인 21억을 넘는 값이 나와, 올바르게 계산되지 않아서 그런 것이였다.

     

    2. 반복횟수를 알아야 할 때에는 굳이, while문을 사용하여 변수를 늘리기 보다는 for문을 사용하여 반환하는 것이 더 깔끔하다.

     => 어차피 500회라는 조건은, for문에서도 가능하다.

     

    3. 서울에서 김서방 찾기

    String형 배열 seoul의 element중 "Kim"의 위치 x를 찾아, "김서방은 x에 있다"는 String을 반환하는 함수, solution을 완성하세요. seoul에 "Kim"은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니다.

     

    제한 사항
    seoul은 길이 1 이상, 1000 이하인 배열입니다.
    seoul의 원소는 길이 1 이상, 20 이하인 문자열입니다.
    "Kim"은 반드시 seoul 안에 포함되어 있습니다.

     

    !! 나의 풀이

    public class Solution {
        public string solution(string[] seoul) {
            string answer = "";
            for (int i = 0; i < seoul.Length; i++)
            {
                if (seoul[i] == "Kim")
                {
                    answer =  $"김서방은 {i}에 있다";
                }
            }
            return answer;
        }
    }

     

    !! 모범 풀이

    using System;
    
    public class Solution {
        public string solution(string[] seoul) {
            int answer = 0;
    
    
            answer = Array.FindIndex(seoul, i => i == "Kim");
    
    
            return string.Format("김서방은 {0}에 있다",answer);
        }
    }

     

    깨달은 점

     

     1. Array 클래스의 메서드를 사용하면, 문자열이나 기타 배열을 조작하는데 더 용이할 것 같다.

     =>

       A. Sort()

        : 배열을 오름차순으로 정렬 

     

    Array.Sort("Array 이름");

     

    static void Main(string[] args)
    {
        int[] sampleArray = { 4, 3, 6, 1, 5, 4, 2 };
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
    
        Array.Sort(sampleArray);
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
    }

    >

     

       B. Reverse()

        : 배열을 내림차순으로 정렬

    static void Main(string[] args)
    {
        int[] sampleArray = { 4, 3, 6, 1, 5, 4, 2 };
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
    
        Array.Sort(sampleArray);
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
        
        Array.Reverse(sampleArray);
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
    }

    >

     

       C. Linq를 활용한 정렬

          : Linq를 활용하여 쿼리 혹은 제공하는 메서드를 통해 정렬

     

    static void Main(string[] args)
    {
        int[] sampleArray = { 4, 3, 6, 1, 5, 4, 2 };
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
    
        // 쿼리 활용
        var sampleVarArray = from intEle in sampleArray
                             orderby intEle
                             select intEle;
    
        Console.WriteLine($"{String.Join(" , ", sampleVarArray)}");
    
        // 기존 배열 출력
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
    
        // OrderBy() 메서드 활용
        int[] sortedArray = sampleArray.OrderBy(n => n).ToArray();
        Console.WriteLine($"{String.Join(" , ", sortedArray)}");
    }

    >

     

       D. IndexOf()

         : 요소를 검색하여, 검색값과 일치하는 첫번째 요소의 인덱스를 반환한다.

     

    Array.IndexOf("검색할 배열 이름", "검색할 요소");

     

    static void Main(string[] args)
    {
        int[] sampleArray = { 4, 3, 6, 1, 5, 4, 2 };
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
    
        // 6 의 인덱스 검색
        int numberSix = Array.IndexOf(sampleArray, 6);
        Console.WriteLine(numberSix);
    }

    >

     

       E. FindInex()

          : 요소를 검색하여, 조건과 일치하는 첫번째 요소의 인덱스를 반환한다.

          : 조건을 람다식으로 표현 가능함.

     

    Array.FindIndex("검색할 배열 이름", "검색할 조건");

     

    static void Main(string[] args)
    {
        int[] sampleArray = { 4, 3, 6, 1, 5, 4, 2 };
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
    
        // 가장 처음으로 3을 넘는 값의 인덱스 검색
        int overThree = Array.FindIndex(sampleArray, num => num > 3);
        Console.WriteLine(overThree);
    }

    >

     

       F. String.Join()

          : 배열 요소들과 지정한 구분자를 사이에 합쳐 문자열로 만듦.

     

    string.Join("배열 요소 사이의 구분자", "문자열로 만들 배열 이름");

     

    static void Main(string[] args)
    {
        int[] sampleArray = { 4, 3, 6, 1, 5, 4, 2 };
        Console.WriteLine($"{String.Join(" , ", sampleArray)}");
    }

    >

     

    4. 음양 더하기

    어떤 정수들이 있습니다. 이 정수들의 절댓값을 차례대로 담은 정수 배열 absolutes와 이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어집니다. 실제 정수들의 합을 구하여 return 하도록 solution 함수를 완성해주세요.

     

    제한사항
    absolutes의 길이는 1 이상 1,000 이하입니다.
    absolutes의 모든 수는 각각 1 이상 1,000 이하입니다.
    signs의 길이는 absolutes의 길이와 같습니다.
    signs[i] 가 참이면 absolutes[i] 의 실제 정수가 양수임을, 그렇지 않으면 음수임을 의미합니다.

     

     

    !! 나의 풀이

    using System;
    
    public class Solution {
        public int solution(int[] absolutes, bool[] signs) {
            int answer = 0;
            for (int ele = 0; ele < absolutes.Length; ele++)
            {
                int times = (signs[ele] == true) ? 1 : -1;
                answer += (times * absolutes[ele]);
            }
            return answer;
        }
    }

     

    !! 모범 풀이

    using System;
    using System.Linq;
    
    public class Solution {
        public int solution(int[] absolutes, bool[] signs) {
            return absolutes.Select((t, idx) => signs[idx]? t : -t).Sum();
        }
    }

     

    깨달은 점

     

    1. 파라미터러 주어진 두 배열의 길이가 같다는 점과 Linq를 활용하여 Sum() 메서드로 한번에 결과값을 반환함.

    => 비슷한 상황이 많을 지는 모르겠지만, 배열을 다룰 때, Linq를 적절히 활용하면 코드를 편하게 작성할 수 있는 것 같다.

    'C# > C# 알고리즘' 카테고리의 다른 글

    20231005  (1) 2023.10.05
    20230905  (0) 2023.09.05
    20230904  (0) 2023.09.04
    20230829 - temp  (0) 2023.08.29
Designed by Tistory.