C++/Report

4장 연습문제.

gandus 2010. 4. 5. 23:21

1. 두 점사이의 거리를 계산하는 함수를 작성하여 보자. 2차원 공간에서 두점(x1,y2) , (x2,y2)사이의 거리를 계산하는 dist_2d()를 작성할. 다음과 같은 두 점 사이의 거리를 계산하는 공식을 사용하여라.

 

d =

 

#include<iostream>

#include<cmath>

using namespace std;

 

struct point{

int x;

int y;

double dist;

};

 

void dist_2d ( point p[] );

 

void main()

{

point p[4]={0};

 

cout<<"(x1,y2) (x2,y2) 4개의정수를입력하시오. : "

cin>>p[0].x >> p[0].y >> p[1].x >> p[1].y; cout<<endl;

 

dist_2d(p);

 

cout<<"("<<p[0].x<<" , "<<p[0].y<<") "<<"("<<p[1].x<<" , "<<p[1].y<<")"

cout<<"두좌표의길이는"<<p[0].dist <<" 입니다."<<endl;

 

}

 

void dist_2d( point p[])

{

double temp_x=0, temp_y=0;

 

temp_x = ( pow ( (p[0].x - p[1].x) , 2.0 ) ) ;

temp_y = ( pow ( (p[0].y - p[1].y) , 2.0 ) ) ;

 

p[0].dist = sqrt(temp_x + temp_y);

}

2. 제곱근을 구하는 방법 중에 Newton-Raphson 기법이 있다. 이 알고리즘은 n의 제곱근을 구하기 위해 근사치 r0를 초기값으로 하고 아래와 같은 공식을 적용해 나가면서 점점 더 정확한 제곱근을 계산하는 프로그램입니다.

 

만약 허용 오차보다 작은 오차를 보이게 되면 알고리즘을 중단한다. 다음과 같은 알고리즘을 구현하는 함수를 작성하라.

 

1. 제곱근의 추정치 r을 1로 설정

2. 만약 | | < €이면 4단계로 간다.

3. r의 값을 ( n / r + r ) / 2 설정한다. 단계 2로 간다.

4. r이 의 추정치가 된다.

 

#include<iostream>

#include<cmath>

using namespace std;

 

struct root // 제곱근의값들을저장하는구조체

{

double num, A_value, width; // 숫자, 근사치, 오차범위입니다.

};

 

void SQRT_check(root r[]); // 구조체변수를함수로넘겨준다

void reset(root r[]);

 

void main ()

{

root r[1]={0};

r[0].A_value = 1;

 

cout<<"제곱근을구할숫자와, 오차범위를설정하세요. : "

cin>> r[0].num >> r[0].width; cout<<endl;

 

SQRT_check(r); // 제곱근을구하는함수호출

 

cout<<endl<< "완료!! "<<endl;

cout<< r[0].num <<"의제곱근에가까운근사치는"<<r[0].A_value <<"입니다."<<endl<<endl;

}

 

void SQRT_check(root r[]) // 제곱근을구하는함수몸체

{

double temp;

 

temp = abs( ((r[0].A_value * r[0].A_value ) - r[0].num) );

 

if( temp >= r[0].width ) // 오차범위보다높으면

{

cout<<"구하는중: "<< r[0].A_value <<endl;

reset(r); // 근사치를재설정하는함수호출

}

else if( temp < r[0].width)

exit;

}

 

void reset(root r[])// 근사치를재설정하는함수몸체

{

r[0].A_value = ( r[0].num / r[0].A_value + r[0].A_value ) / 2;

 

SQRT_check(r);// 근사치재설정후다시제곱근을구하는함수호출

}

 

 

3. 난수(random number)는 컴퓨터를 이용한 문제 해결에서 많이 사용된다. 특히 확률적인 모델을 만들어서 실제 상황을 흉내내는 시뮬레이션에서 널리 이용된다. 수학적인 분석이 너무 복잡한 경우에 시뮬레이션을 사용하면 실제로 제품을 제작하지 않고서도 많은 실험을 할 수 있다. 난수는 표준 라이브러리 함수 rand()를 호출하면 생성할수 있다. rand()가 한번 호출 될 때마다 0에서 n까지 구간에 정수를 같은 확률로 선택하여 반환한다. 여기서 n은 시스템에 따라 달라진다. 보통 비쥬얼 c++ 의 경우, 0 ~ 32767까지의 정수를 반환한다.

 

1. 지정된 범위 안에 있는 정수를 임으로 선택하여 변환하는 함수 rand_range()를 작성하시오. 함수 매개 변수는 지정된 범위의 하한값과 상한값이 된다. 예를 들어서 1 과 6이라면 rand_range()은 1,2,3,4,5,6 중의 하나를 무작위로 변환한다.

 

2. rand_range()함수를 이용하여 주사위를 600번 던졌을 때 나오는 값을 통계 처리하여 1부터 6까지의 값이 근사적으로 같은 확률을 가지고 나타남을 보여라.

 

 

 

#include <iostream>

#include <cstdlib>

#include <ctime>

using namespace std;

 

int rand_range(int min, int max); // 최소값, 최대값을받아서난수를리턴

 

int main()

{

int min, max, i, j, count[601]={0};

 

srand( (int)time(NULL) ); // 난수를초기화함

 

cout<<"최소, 최대값을입력하시오. : ; // 최소, 최대값을입력받는다

cin>> min >> max; cout<<endl;

 

for( i=0; i<600; i++) // 600번을돌린다.

{

for( j=min; j<=max; j++)

// 최소값에서최대값까지돌리면서난수발생

{

if(rand_range(min , max) == j)

count[j]++; // 난수와j값이같으면카운트함.

}

}

 

for( i=min; i<=max; i++) // 결과값을출력하는for문

cout << i <<"가나올확률은 : " << (count[i] / 600.0 ) * 100 << "\%" << endl;

 

return 0;

}

 

int rand_range(int min, int max) // 난수생성함수

{

int result;

 

result = rand()%max +min; // 난수발생

 

if( result > max) // 범위밖의난수가발생하면재귀호출

return rand_range(min, max);

else

return result;

}

 

4. 돈만 생기면 저금하는 사람을 가정하라. 이 사람을 위한 함수는 save(int amount)를 작성하여 보자. 이 함수는 저금할 금액을 나타내는 하나의 인수 amount만을 받으며 save(100)과 같이 호출된다. save()는 현재까지 저축된 총액을 기억하고 있으며 한번 호출될 때마다 총 저축액을 화면에 출력한다.

 

/* 전역변수나정적지역변수를사용시에는함수를사용하지않고서도저축, 인출의

연산수행이가능하다.

-> 모든곳에서재선언이가능해서

 

굳이함수를만들자면입력받는것을함수

로만들수있다.

save(), draw() 매개변수필요없이가능

*/

 

/* 그래서함수내에지역변수만을사용해서문제를풀었습니다. */

 

#include<iostream>

using namespace std;

 

// int amount=0; // 전역변수사용시선언위치.

 

void save(int get_amount, int *amount); // 저축함수

void draw(int get_amount, int *amount); // 인출함수

 

void main ()

{

// static int amount= 0; // 정적지역변수선언시방법.

int select=0;

int amount=0, get_amount=0; // amount-매개변수, get_amount 입력값

 

cout<<"통장관리프로그램입니다."<<endl;

cout<<"현재잔고는"<<amount<<"원입니다."<<endl;

while(1)

{

cout<<"입금(1), 인출(2), 종료(3) 입니다. 선택하시오. : "

cin>>select;cout<< endl;

 

if(select == 3) break // 종료.

 

else if(select == 1) // 입금구역

{

cout<<"입금하실금액을적으세요. ex)700(원) : "

cin>> get_amount;

 

save(get_amount, &amount); // 저축함수호출

 

cout<<"현재까지의총금액은"<<amount <<" 입니다."<<endl<<endl;

continue

}

else if(select == 2) // 인출구역

{

cout<<"인출하실금액을적으세요. ex)700(원) : "

cin>> get_amount;

 

draw(get_amount, &amount);

 

cout<<"현재까지의총금액은"<<amount <<" 입니다."<<endl<<endl;

}

}

}

 

void save(int get_amount, int *amount)

{

*amount += get_amount;

}

 

void draw(int get_amount, int *amount)

{

*amount -= get_amount;

}

 

5. 재귀 호출을 이용하여 정수의 각 자리수를 출력하는 함수 show_digit(int x)를 작성하고 테스트하라. 즉 정수가 1234이면 화면에 1 2 3 4와 같이 출력한다. 함수는 일의 자리를 출력하고 나머지 부분을 대상으로 다시 같은 함수를 재귀 호출한다. 예를 들어서 1234의 4를 출력하고 나머지 123을 가지고 다시 같은 함수를 재귀호출.

 

#include<iostream>

using namespace std;

 

void show_digit(int num, int arr[], int *count);

 

void main()

{

int num, i=0, arr[255]={0}; // 정수들을나열

int count=0; // 정수수를셈

 

cout<<"원하는정수를입력하시오. : "

cin>> num; cout<<endl;

 

show_digit(num, arr, &count);

 

for(i = count-1; i >= 0; i--)

{

cout<< arr[i] << " "

}

cout<<endl;

}

 

void show_digit(int num, int arr[], int *count)

{

arr[*count] = num % 10; // 1의자리부터들어감

num = num / 10;

*count += 1;

 

if ( num )

show_digit(num, arr, count);

else

exit;

}

6. 다음을 계산하는 재귀적인 프로그램을 작성하라.

  

#include<iostream>

#include<cmath>

using namespace std;

 

int square( int num, int sum );

int overflow(int out);

 

void main()

{

int num, sum=0;

int out=0;

 

cout<<"1 ~ n 까지각정수의3제곱한합을구하는프로그램입니다."

cout<<endl <<"정수를입력하시오. : "

cin>>num; cout<<endl;

 

out = square(num, sum); // 출력변수

 

cout<<"1 ~ "<<num<<"까지의3제곱총합은:" <<out<<endl;

}

 

int square( int num, int sum )

{

int a= 1;

sum += (int) pow( num, 3.0 );

num--;

 

if(sum*a/a != sum)

{

cout <<"오버플로우발생"<< endl;

return 0;

}

else if ( num )

return square(num, sum);

else

return sum;

}