본문 바로가기
공부/C#

C# 공부(9) 81~90

by 라이티아 2024. 8. 26.

81. 재귀 메소드로 역수의 합 계산

using System;

namespace P81
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("1 - 10 역수 합 = {0}", Sum(10));
        }
        private static double Sum(int n)
        {
            if (n == 1) return 1;
            else return 1.0 / n + Sum(n - 1);
        }
    }
}

 

결과

1 - 10 역수 합 = 2.9289682539682538

( 서로 곱한 결과가 1이 나오는 수를 역수라고 한다. )

간단 메소드 그만!!!

 

82. 하노이의 탑과 메르센 수

using System;

namespace P82
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 50 ; i++)
            {
                double m = Mersenne(i);
                Console.WriteLine($"메르센 수 {i} = {m:N} = {m / 3600 / 24:N} = {m / 3600 / 24 / 365:N}");
            }
            Console.WriteLine($"하노이 : 4, {'A'} - {'B'} - {'C'}");
            Hanoi(4, 'A', 'B', 'C');
        }
        private static double Mersenne(int n)
        {
            return Math.Pow(2, n) - 1;
        }

        private static void Hanoi(int n, char from, char to, char by)
        {
            if (n == 1) Console.WriteLine($"{from} -> {to}");
            else
            {
                Hanoi(n - 1, from, by, to);
                Console.WriteLine($"{from} -> {to}");
                Hanoi(n - 1, by, to, from);
            }
        }
    }
}

 

결과

메르센 수 45 = 35,184,372,088,831.00 = 407,226,528.81 = 1,115,689.12
메르센 수 46 = 70,368,744,177,663.00 = 814,453,057.61 = 2,231,378.24
메르센 수 47 = 140,737,488,355,327.00 = 1,628,906,115.22 = 4,462,756.48
메르센 수 48 = 281,474,976,710,655.00 = 3,257,812,230.45 = 8,925,512.96
메르센 수 49 = 562,949,953,421,311.00 = 6,515,624,460.89 = 17,851,025.92
메르센 수 50 = 1,125,899,906,842,623.00 = 13,031,248,921.79 = 35,702,051.84
하노이 : 4, A - B - C
A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C
A -> B
C -> B
C -> A
B -> A
C -> B
A -> C
A -> B
C -> B

 

재귀 함수로 하노이탑 풀이를 하는 코드.

 

83. 재귀 이진탐색

using System;

namespace P83
{
    class Program
    {
        static void Main(string[] args)
        {
            Random r = new Random();
            int[] v = new int[10];
            for (int i = 0; i < v.Length; i++)
            {
                v[i] = r.Next(1000);
            }
            Print(v);

            Array.Sort(v);
            Print(v);
            
            Console.Write("탐색 숫자 : ");
            int input = int.Parse(Console.ReadLine());

            int index = Search(v, 0, v.Length - 1, input);
            Console.WriteLine($"v [{index}]  = {input}");
        }

        private static int Search(int[] v, int low, int high, int key)
        {
            if (low <= high)
            {
                int mid = (low + high) / 2;
                if (key == v[mid])
                    return mid;
                else if (key > v[mid])
                    return Search(v, mid + 1, high, key);
                else
                    return Search(v, low, mid - 1, key);
            }
            return -1;
        }
        private static void Print<T>(T[] value)
        {
            foreach(T n in value)
            {
                Console.Write(n + " ");
            }
            Console.WriteLine();
        }
    }
}

 

결과

890 493 763 687 169 931 199 457 53 412
53 169 199 412 457 493 687 763 890 931
탐색 숫자 : 412
v [3]  = 412

 

이진 탐색 메소드를 재귀 매소드로 구현한 코드이다.

 

84. Stopwatch로 피보나치 수열의 실행시간 측정

using System;

namespace P84
{
    class Program
    {
        static int[] f = new int[50];
        static void Main(string[] args)
        {
            Console.Write("값 입력 : ");
            int n = int.Parse(Console.ReadLine());

            var watch = System.Diagnostics.Stopwatch.StartNew();

            f[1] = f[2] = 1;
            for(int i = 3; i <=n; i++)
            {
                f[i] = f[i - 1] + f[i - 2];
            }
            for (int i = 1; i <= n; i++)
            {
                Console.Write($"{f[i]} ");
            }
            Console.WriteLine();
            watch.Stop();

            var elapsedMs = watch.ElapsedMilliseconds;
            Console.WriteLine($"실행시간 {elapsedMs}ms\n");

            watch = System.Diagnostics.Stopwatch.StartNew();

            for (int i = 1; i <= n; i++)
                Console.Write($"{Fibo(i)} ");
            Console.WriteLine();

            watch.Stop();
            elapsedMs = watch.ElapsedMilliseconds;
            Console.WriteLine($"실행시간 {elapsedMs}ms\n");
        }
        private static int Fibo(int n)
        {
            if (n == 1 || n == 2)
                return 1;
            else
                return Fibo(n - 1) + Fibo(n - 2);
        }
    }
}

 

결과

값 입력 : 45
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170
실행시간 4ms

1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170
실행시간 23065ms

 

피보나치 수열을 반복문, 재귀로 구현해서 시간을 확인하는 코드 입니다.

재귀가 반복에 비해서 최적화율이 낮은것을 확인할 수 있습니다.

 

85. DateTime 구조체

using System;

namespace P85
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime date1 = new DateTime(1992, 7, 4, 8, 43, 0);
            DateTime date2 = new DateTime(1990, 1, 27, 12, 6, 0);

            Console.WriteLine(date1);
            Console.WriteLine(date2);

            Console.WriteLine($"{date1.ToString("yyyy년 M월 d일")}과 {date2.ToString("yyyy년 M월 d일")}차이는 {date1.Subtract(date2).Days}입니다.");

            Console.WriteLine($"오늘 {DateTime.Today}");
            Console.WriteLine($"어제 {DateTime.Today.AddDays(-1)}");
            Console.WriteLine($"내일 {DateTime.Today.AddDays(1)}");

            DateTime d = DateTime.UtcNow;

            Console.WriteLine(d);
        }
    }
}

 

결과

1992-07-04 오전 8:43:00
1990-01-27 오후 12:06:00
1992년 7월 4일과 1990년 1월 27일차이는 888입니다.
오늘 2024-08-26 오전 12:00:00
어제 2024-08-25 오전 12:00:00
내일 2024-08-27 오전 12:00:00
2024-08-26 오전 6:34:30

 

DateTime 클래스에 관한 코드이다.

게임 내에서 일자, 혹은 실제 시간을 표시할때 유용할 것 같다.

 

86. TimeSpan 구조체의 사용 방법

using System;

namespace P86
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime d1 = DateTime.Now;
            DateTime d2 = DateTime.Today.AddDays(1);

            TimeSpan span = d2 - d1;
            Console.WriteLine($"{span, 12}");
            Console.WriteLine($"{span.Days,12}");
            Console.WriteLine($"{span.Hours,12}");
            Console.WriteLine($"{span.Minutes,12}");
            Console.WriteLine($"{span.Seconds,12}");
            Console.WriteLine($"{span.Milliseconds,12}");

            Console.WriteLine();

            Console.WriteLine($"{span,12}");
            Console.WriteLine($"{span.TotalDays,12}");
            Console.WriteLine($"{span.TotalHours,12}");
            Console.WriteLine($"{span.TotalMinutes,12}");
            Console.WriteLine($"{span.TotalSeconds,12}");
            Console.WriteLine($"{span.TotalMilliseconds,12}");
        }
    }
}

 

결과

08:18:50.6490661
           0
           8
          18
          50
         649

08:18:50.6490661
0.34641954937615743
8.314069185027778
498.8441511016667
29930.6490661
29930649.0661

 

TimeSpan을 사용하면 TimeDate의 연산을 저장할 수 있음을 보여준다.

유니티 내에서 제한시간 등을 표현할 때 좋을 것 같다.

 

87. TimeSpan을 이용한 생애 계산기

using System;

namespace P87
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("생애 계산기");
            DateTime date = DateTime.Parse(Console.ReadLine());
            DateTime dateN = DateTime.Now;

            TimeSpan span = dateN - date;
            Console.WriteLine($"생존 시간 {span.ToString()}");
            Console.WriteLine($"{span.Days} {span.Hours} {span.Minutes}");
        }
    }
}

 

결과

생애 계산기
2000-1-1
생존 시간 9004.15:49:00.8845289
9004 15 49

 

88. DateTime Format

using System;
using System.Globalization;

namespace P88
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime today = DateTime.Now;

            Console.WriteLine("yyyy MM dd");
            Console.WriteLine("MMMM dd, yyyy ddd",
                CultureInfo.CreateSpecificCulture("en-US"));

            Console.WriteLine("d : " + today.ToString("d"));
            Console.WriteLine("D : " + string.Format($"{today:D}"));
            Console.WriteLine("t : " + string.Format($"{today:t}"));
            Console.WriteLine("T : " + string.Format($"{today:T}"));
            Console.WriteLine("g : " + string.Format($"{today:g}"));
            Console.WriteLine("G : " + string.Format($"{today:G}"));
            Console.WriteLine("f : " + string.Format($"{today:f}"));
            Console.WriteLine("F : " + string.Format($"{today:F}"));
            Console.WriteLine("s : " + string.Format($"{today:s}"));
            Console.WriteLine("o : " + string.Format($"{today:o}"));
            Console.WriteLine("r : " + string.Format($"{today:r}"));
            Console.WriteLine("u : " + string.Format($"{today:u}"));


        }
    }
}

 

결과

yyyy MM dd
MMMM dd, yyyy ddd
d : 2024-08-26
D : 2024년 8월 26일 월요일
t : 오후 4:05
T : 오후 4:05:09
g : 2024-08-26 오후 4:05
G : 2024-08-26 오후 4:05:09
f : 2024년 8월 26일 월요일 오후 4:05
F : 2024년 8월 26일 월요일 오후 4:05:09
s : 2024-08-26T16:05:09
o : 2024-08-26T16:05:09.7630303+09:00
r : Mon, 26 Aug 2024 16:05:09 GMT
u : 2024-08-26 16:05:09Z

 

DateTime 클래스가 가진 포멧을 확인하는 코드이다. 주로 t, d를 사용할 것 같다.

 

89. 메소드에 인수를 전달하는 세 가지 방법

using System;

namespace P89
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 3;
            Sqr(a);
            Console.WriteLine(a);

            int b = 3;
            Sqr(ref b);
            Console.WriteLine(b);

            string name;
            int id;
            GetName(out name, out id);
            Console.WriteLine(name + id);
        }

        static void Sqr(int x)
        {
            x = x * x;
        }

        static void Sqr(ref int x)
        {
            x = x * x;
        }

        static void GetName(out string name, out int id)
        {
            Console.Write("이름 : ");
            name = Console.ReadLine();
            Console.Write("아이디 : ");
            id = int.Parse(Console.ReadLine());
        }
    }
}

 

결과

3
9
이름 : ss
아이디 : 12
ss12

 

out이라는 키워드가 나왔다. return과 비슷하게 사용되지만, return은 1개의 값만 가능한 반면, out키워드의 경우 원하는 만큼 매소드에서 값을 계산해서 가져올 수 있다.

 

90. 가변길이 매개변수 params의 사용 방법

using System;

namespace P90
{
    class Program
    {
        public static void PrintInt(params int[] arr)
        {
            for (int i = 0; i < arr.Length; i++) Console.Write(arr[i] + " ");
            Console.WriteLine();
        }
        public static void PrintObj(params object[] arr)
        {
            for (int i = 0; i < arr.Length; i++) Console.Write(arr[i] + " ");
            Console.WriteLine();
        }
        static void Main(string[] args)
        {
            PrintInt(1, 2, 3, 4);
            PrintObj(1, 1.2, "a", 'b');
            PrintObj();

            int[] arr = { 5, 6, 7, 8 };
            PrintInt(arr);

            object[] arr2 = { 1, 1.5, "abc", 'd' };
            PrintObj(arr2);

            PrintObj(arr);
        }
    }
}

 

결과

1 2 3 4
1 1.2 a b

5 6 7 8
1 1.5 abc d
System.Int32[]

 

params 키워드에 대한 코드이다.

params 키워드가 있으면 매소드를 호출할 배열을 명시하지 않아도 된다고 한다

public static void PrintText(object[] arr)
{
    for (int i = 0; i < arr.Length; i++) Console.Write(arr[i] + " ");
    Console.WriteLine();
}
이런게 있다면

PrintText(new object[] { 1, "test", 3.14 });
이렇게 이용해야 하는데, 위의 params의 경우

PrintObj(1, "test", 3.14);
만 해도 된다고 한다

'공부 > C#' 카테고리의 다른 글

C# 공부(10) 93~100  (0) 2024.08.27
C# 공부(10) 91~92(Part2 End)  (0) 2024.08.26
C# 공부(8) 71~80  (0) 2024.08.26
C# 공부(7) 61~70  (0) 2024.08.26
C# 공부(6) 57~60  (0) 2024.08.25