아하
검색 이미지
생활꿀팁 이미지
생활꿀팁생활
생활꿀팁 이미지
생활꿀팁생활
어린알파카245
어린알파카24521.04.05

c# 배열을 사용해서 코드를 짰는데 문제가 있는 듯합니다.

아래 코드 중

print(Avg(scores) == 4.5);

print(Max(scores) == 8);

이 두 코드의 논리값이 true여야 하는데 false로 나옵니다....뭐가 문제일까요?ㅠ

using System;


class MainClass {

public static void Main (string[] args) {

Action<object> print = Console.WriteLine;

int[] scores = new int[] {2,4,5,3,6,8,1,7};

print(Avg(scores) == 4.5); <- 이 두 부분의 논리값이 true로 나와야 하는데 false로 나옵니다ㅠ

print(Max(scores) == 8); <-

public static double Avg(int[] list)

{

int s = 0;

foreach(int n in list)

s += n;

double a = s/list.Length;

return a;

}

public static int Max(int[] list)

{

int Max = 0;

for (int i = 0; i<list.Length; i++)

{

if (list[i] < Max )

Max = list[i];

}

return Max;

}




55글자 더 채워주세요.
답변의 개수
8개의 답변이 있어요!
  • 자 일단 Avg 함수부터 설명하겠습니다.

    public static double Avg(int[] list) { int s = 0; foreach(int n in list) s += n; double a = s/list.Length; // <- return a; }


    Avg 함수의 화살표 처리된 부분을 보면 s/list.Length 을 진행합니다.
    여기서 오류가 생깁니다.
    s의 자료형은 int, list.Length 또한 int 라서 double 에 넣었지만 int/int 가 진행되어 소수점 부분이 사라진 4를 반환합니다.
    따라서 s 해당 코드처럼 자료형을 변환하면 4.5를 반환합니다.

    public static double Avg(int[] list) { int s = 0; foreach(int n in list) s += n; double a = (double)s/list.Length; // double 으로 형변환 return a; }

    다음으로 Max 함수를 설명하겠습니다.

    public static int Max(int[] list) { int Max = 0; for (int i = 0; i<list.Length; i++) { if (list[i] < Max) // <- Max = list[i]; } return Max; }

    Max 함수의 화살표 처리된 부분을 보면 list[i] < Max 을 진행합니다.
    여기서 부등호의 방향이 잘못되어 있습니다.
    해당 코드처럼 부등호의 방향을 번경하시면 정상적으로 8을 반환합니다.

    public static int Max(int[] list) { int Max = 0; for (int i = 0; i<list.Length; i++) { if (list[i] > Max) // 부등호를 > 으로 변경 Max = list[i]; } return Max; }

    또한 추가로 위 Max 함수는 들어가는 값이 음수일 경우 정상적인 값을 반환하지 못합니다.
    따라서 int.MinValue 을 이용하여 int의 최소값을 Max의 초기값으로 설정하여야 합니다.

    public static int Max(int[] list) { int Max = int.MinValue; for (int i = 0; i<list.Length; i++) { if (list[i] > Max) // 부등호를 > 으로 변경 Max = list[i]; } return Max; }

    감사합니다.

    https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUBgAgFkBDASygGEAbEgZzoIG88C2DUBmDzANg4AsxclAAUqTAAYA2gF0CJMAHM6ASha52WnugA8AewBGAKwCmAY2AA+AgAcwFYAQC8PAJwBuVtraO5BOnN9MFNGVyhTAHcCP3kmdBgBGABWGE4YXhgADhhMGAB2AF8vXG8fe0dRAEEANyVRQODQ1RdXAQA6ZNUSnzYKqGBRUgAPBqCQtVaCLO6ygkK5ua4efjh9CENqUwJa+tiCajI6YFU5jV6YgYCXAkke3oAzJpJzAAtRRwIoS4Ojk7mLoxEOF7j41hstgobqJwZtTKo6AB6Q7HdoAGVMUCUwFeoO0qHyCjxC1KmnYywk/E+Iw+A38KP+ZLY5161JIwxujnaRAoADUSNQIKY8VonmACLSnGQbncYroGejMdjcTFEIhTkztCyLmQHhKGdIyPIbCMCBqLj5Ta4DUaRewSRcCcJhsS8CS8EA=
    변경된 코드 내용입니다.

    위 링크로 들어가면 코드를 볼 수 있습니다.


  • 안녕하세요~^^

    프로그램이 내가 원하던 결과가 나오지 않을 때가 종종 있죠ㅎ 그럴땐 디버깅을 해보세요.

    일단 문제를 보면 둘 다 true의 결과가 출력되길 원했는데, 둘 다 false로 출력이 됐군요.

    천천히 디버깅해봅시다~

    평균과 가장 큰 수를 구하는 메소드를 만드셨네요

    1. 평균을 구하는 메소드를 살펴봅니다.

    결과를 출력해봅시다. 음... 4가 나오겠네요 .

    계산결과가 4.5가 나오려면 더블형으로 캐스팅을 해주셔야겠네요.

    double a = (double)s/list.Length;

    2. 가장 큰 수 구하는 메소드를 살펴봅니다.

    마찬가지로 출력을 해봅시다. 0이 나오겠네요.

    for문안에서 if문을 확인해 보시면,

    지금 Max변수가 0인데, 0보다 작은 수를 찾고 있네요.

    배열에는 0보다 작은 수가 없군요. 따라서 결과는 0을 항상 출력하겠네요.

    해결방법은,

    if(list[i] > Max)

    이렇게 0보다 큰 수를 찾고, 다음 배열의 수와 for문을 돌며 계속 찾아가서 가장 큰 수인 8을 출력합니다 .

    수정하시고 결과를 확인해보세요~^^


  • 2일전 글이라 문제를 해결하셨을 수도 있지만 일단 답변드립니다.

    Avg 메서드에서의 연산같은 경우

    double a = s / list.Length 라고 하셨죠. s와 list.Length는 모두 int 형태로 연산을 하게되면 4가 됩니다. 그렇기 때문에 false가 된거구요.

    double a = (double)s / list.Length;

    이런식으로 int형태인 s를 형변환을 시켜주시던지

    double s = 0; 이런식으로 애초에 변수생성시 double 형태로 바꿔주시면 됩니다.

    Max 메서드같은 경우

    for (int i = 0; i < list.Length; i++) { if (list[i] < Max) Max = list[i]; }

    이렇게 작성하셨는데 if 조건보시면 Max가 더 커야 Max에 값이 담기는데 그러면 최대값이 안담기겠죠

    for (int i = 0; i < list.Length; i++) { if (list[i] > Max) Max = list[i]; }

    위와 같이 if문 조건에서 부등호 방향을 바꿔주셔야 합니다.


  • 1. Avg 함수에서는 list.length 가 int 이므로,

    s / list.length 가 4가 되었습니다.

    list.length 를 double 형으로 캐스팅 해줘야합니다.

    2. Max 함수에서는 if 문의 비교가 잘못되었습니다.

    list[i] > Max 로 비교해야 원하는 결과를 얻으실겁니다.


  • 탈퇴한 사용자
    탈퇴한 사용자21.04.06

    원하는 값이 true 여야 하는데 결과가 false가 나온다는 것이지요?
    그렇다면 먼저 해당 조건의 값이 각각 4.5와 8 이 아니라는 의심을 해볼 수 있겠습니다.
    (컴퓨터는 거짓말을 안하니까요)

    위와같은 합리적인 의심에서 출발을 한다면,
    다음 단계는 왜 그랬는지 알아보는 절차로 코드 바꾸어보면 원인을 찾는데 도움이 될 수 있습니다.
    일단 참거짓 이전에 어떤 값이라 참거짓이 나왔는지 확인해보는 과정입니다.

    == 로 값을 비교하는 것 대신 Avg와 Max 의 결과를 print 로 넘기면 될 것 입니다.

    Action<object> print = Console.WriteLine; int[] scores = new int[] { 2, 4, 5, 3, 6, 8, 1, 7 }; print(Avg(scores)); // 이전: print(Avg(scores) == 4.5); print(Max(scores)); //이전: print(Max(scores) == 8);

    실행을 해보면 아래와 같이 기대했던 4.5 및 8 이 아닌 4 와 0 이 결과 화면에 찍히는 것을 알 수 있습니다. 위에서 가정한 것처럼 실제 값이 기대했던 것과 다음을 알 수 있습니다.

    다음은 왜 해당 값이 안 나왔는지 찾아봅니다.

    Avg 의 결과가 4.5가 아닌 4가 나온 이유?

    코드는 아래와 같습니다.

    public static double Avg(int[] list) { int s = 0; foreach (int n in list) s += n; double a = s / list.Length; return a; }

    s 라는 int 타입의 변수에 값들을 누적해서 더하고 list.Length로 나누기를 합니다.
    문제는 두 타입이 모두 int 입니다. int 와 int의 연산 결과는 소수가 아닌 정수입니다.
    그래서 4.5가 아닌 4라는 결과가 a에 담기게 됩니다.

    double로 결과를 받기 위해서는 둘 중 하나(혹은 둘다)의 타입을 double로 바꾸어주면 됩니다.
    추가로 변수명 s를 의미를 알 수 있게 합이라는 의미의 sum 으로 바꾸었습니다.
    또한 foreach 의 괄호를 추가하여 코드가 묶여서 보이도록 바꾸었습니다.
    그리고 a 라는 double 타입의 변수는 실제로 하는 역할이 없으므로 인라인으로 제거하였습니다.

    public static double Avg(int[] list) { int sum = 0; foreach (int value in list) { sum += value; } return (double)sum / list.Length; }

    Max 의 결과가 8이 아닌 0이 나온 이유?

    코드는 아래와 같습니다.

    public static int Max(int[] list) { int Max = 0; for (int i = 0; i < list.Length; i++) { if (list[i] < Max) Max = list[i]; } return Max; }

    알고리즘을 분석해보면 최초 0이라는 값을 Max 라는 변수에 가지고 있다가
    각 리스트를 앞에서부터 해당 값이 Max 보다 Max 의 값이 작을 경우 Max 값을 갱신을 합니다.
    그리고 그 값을 반환합니다.

    문제는 값이 작을 경우 갱신을 하게 되면 0보다 작은 값이 다음 큰 값이 되게 될 것 입니다.
    여기서는 가장 큰 값을 구하는 것이므로 부등호 값이 바뀌어야 합니다.

    부등호 값을 바꾸고,
    추가로 변수명을 Max 에서 max 로 바꾸었습니다. 이미 메서드 이름이 Max 이기 때문에 변수명도 대문자로 사용할 경우 헷갈릴 수 있기 때문입니다. C#의 경우 관례상 프로퍼티 이름을 대문자로 하기에 문제가 없을 수 있지만 현재의 경우에는 혼동이 될 여지가 커서 바꾸는 것이 좋을 것으로 보입니다.
    또한 if에 괄호를 치는 것이 블록의 구분 확인 및 추가적인 코드가 추가 될 경우 잠재적인 버그가 생길 가능성을 줄일 수 있습니다.

    public static int Max(int[] list) { int max = 0; for (int i = 0; i < list.Length; i++) { if (list[i] > max) { max = list[i]; } } return max; }

    일단 이렇게 하면 원하는 결과를 얻을 수 있을 것입니다.
    하지만 위의 코드는 잠재적인 버그를 가지고 있습니다.

    그 이유는 scores라는 값이 아래와 같이 음수로만 구성이 되어 있다면 무조건 0이 max로 계산이 될 것이기 때문입니다. 답은 가장 큰 값인 -1이 되어야 합니다.

    int[] scores = new int[] { -2, -4, -5, -3, -6, -8, -1, -7 };


    문제 조건상 score가 양수라는 가정이 있다 하더라도, 순수하게 Max 라는 함수는 입력받은 리스트의 값들 중 최대값을 반환하는 것이 올바르게 동작하는 것이기 때문입니다.

    따라서 max 의 초깃값을 0이 아닌 해당 리스트의 첫 번째 원소로 정하는 방법이 있습니다.

    public static int Max(int[] list) { int max = list[0]; for (int i = 1; i < list.Length; i++) { if (list[i] > max) { max = list[i]; } } return max; }

    다만 이렇게 구현을 할 경우에는 원소가 0개 일 경우에는 IndexOutOfRangeException 이 발생할 수 있습니다.
    이런 비어있는 리스트를 전달 받을 때 적절하게 예외처리를 해야할 필요가 있습니다.

    예외처리는 본 질문과 직접적인 관련이 없으므로 본 답변에서는 생략합니다.

    추가적으로 실무에서는 리스트에서 값을 구할 때 직접 구현을 하기 보다는 이미 구현되어 있는 프레임워크의 기능을 쓰는 것이 편할 것 입니다.
    Linq(Language Integrated Query)라는 기능을 이용하면 아래와 같이 한 줄로 처리가 가능해서 굳이 별도의 메서드를 만들 필요가 없습니다.

    public static double Avg(int[] list) { return list.Average(); } public static int Max(int[] list) { return list.Max(); }


  • 소수연산에 문제가 있어보입니다.

    4.5라는 개념은 인간에게는 4와 절반이라는 명확한 수학의 개념이지만, 컴퓨터는 0과 1로 이루어진 값으로

    적당히 4.5에 비슷한 값을 가지고 있을 뿐입니다. 이것을 부동소수연산에 문제가 있어보입니다.

    4.5라는 개념은 인간에게는 4와 절반이라는 명확한 수학의 개념이지만, 컴퓨터는 0과 1로 이루어진 값으로

    적당히 4.5에 비슷한 값을 가지고 있을 뿐입니다. 이것을 부동소수점이라고 합니다.

    따라서 4.5라는 값을 판단하시려면 0.449999 < b && b < 0.4509999와 같이 오차를 주고 판단해야합니다.

    보통 double alpha = 0.000001;

    4.5 - alpha < b && b < 4.5 + alpha (함수로 만드시면 좋습니다)

    로 사용하면 편합니다.

    그리고 소수가 반드시 필요한 경우가 아니면 사용하지 않는 것이 좋습니다.

    과목수가 5개, 평균이 80이 넘는지 확인하시려면 그냥 모두 더해서 400보다 큰지 작은지를 판단하시는 것이 좋습니다.


  • 안녕하세요? C계열 언어의 묵시적 형변환에 의해서, int와 int와의 계산은 int로 리턴되어 들어가게 됩니다.

    즉, double a = s / list.Length; 에서 s와 list.Length가 모두 int이기 때문에 4.5가 아닌 4가 리턴된 문제로 보입니다.

    이를 double a = (double)s / list.Length; 처럼 바꾸어 줌으로써 double과 int의 연산으로 바꾸게 되면 정상적으로 4.5가 출력될 듯 합니다. 감사합니다.


  • 안녕하세요

    C# 공부중이신가 보네요. 코딩할때 놓치기 쉬운부분들인 문제인것 같습니다.

    평균을 구할때 배열의 합을 구하는 s 변수가 int 로 선언되었기 때문에 소수점을 버림처리하고 있습니다.

    s 와 foreach 문에서 n 을 double 로 변경해보시길 바랍니다

    최대값을 구할 때 부등호의 방향이 틀린 것 같네요. 최대값 Max변수의 값보다 list[i] 가 작으면 으로 코딩하셨는데,

    list[i] >= Max 이렇게 하면 될것 같습니다.