c언어 재귀함수 연습 원인좀 알려주세요.


재귀함수로 반복문 연습해보는중인데 저가 원하는 출력문은

*****

****

***

**

*

이렇게 나오는것인데 저위에 코드대로 해보면

*****

****

***

**

*

*****

출력문이 이런형태로 나오게되는데 원인좀 알려주세요!.

왜  한번더 돌게 되는지 설명좀 해주세요.



   일단 완전 잘못 짰습니다.  
 

○ for_1 함수 중간에 main() 함수를 다시 호출하는 것부터 완전 잘못된 코드입니다. 이것은 재귀함수가 아닙니다. 

○ 코드를 고쳐줄까하고 보다가, 너무 모르는 것이 많은 것 같아서, 완전히 다시 짜서 올립니다. 


1. 코드가 컴파일되서 돌지도 않습니다. 예를 들어, for_1() 함수의 return을 int 형으로 선언하셨는데, 실제로는 end==0 인 케이스에서 return; 만 하고 있습니다. 

2. main() 함수를 다른 함수에서 다시 호출하는 것은 절대 안됩니다. 

3. 함수 이름, 변수 이름을 의미 없게 짓는 것은 피하셔야 합니다. 

4. static 선언도 재귀함수의 원래 의도와 맞지 않습니다.



 

 코드 예제 

 

#include 

void printStar(int n);

int main() {
    printStar(5);	//Print Star

    getchar();		//Just for break

    return 0;
}

void printStar(int n)
{
    int i;

    if (n > 0)
    {
        for (i = 0; i < n; i++)
        {
            printf("*");
        }
        printf("\n");

        printStar(n - 1);	//Recusive Call
    }
    else
    {
        return;
    }
}




   실행 결과  
 








Posted by 지그프리드 지그프리드

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

피보나치 수열 재귀함수 이용하지 않고

비재귀로 하는방법 좀 알려주세요~~


일단 재귀함수 이용하는건 했는데

비재귀는 어떻게 해야되는지 모르겠네요.. 더쉬울줄알았는데..

// 제가 작성한 피보나치 재귀함수 이용 버전입니다.



 

 Stack을 사용하면 됩니다 

 

○ 재귀함수를 없애는 가장 기본적인 방법은 Stack을 사용하는 것입니다. 재귀함수 자체가 실제로는 함수 Stack에 차곡차곡 결과값을 쌓고 있는 것입니다. 실제 Stack을 이용해서 값을 저장하면 그만입니다. 


○ 특히 피보나치수열의 경우는 진짜 Stack을 쓸 필요도 없고, Stack 처럼 동작하는 Array면 됩니다. 제 코드에서도 Pop() 함수는 작성을 했지만, 막상 부르는 곳이 없습니다. 지우기도 귀찮아서 일단 남겨둡니다. 


○ 참고로, 이 피보나치 수열은 0부터 시작하는 피보나치 수열입니다. 즉, 0, 1, 1, 2, 3, 5  순서로 진행됩니다. Wikipedia에 이것이 현대적인 형태라고 하더군요

https://en.wikipedia.org/wiki/Fibonacci_number



   코드 예제  
 

#include 
using namespace std;

/* stack */
int stack[100];
int top = -1;
int loop;
int push(int inputV);
int pop(void);

int fibonacciOne(int x);

int main()
{
    //피보나치 수열 재귀
    int n;
    cout << "몇번째 항의 값을 원합니까?";
    cin >> n;
    cout << "\n" << n << "번째 항은 " << fibonacciOne(n) << "입니다.";
    cin >> n;

    return 0;
}

int push(int inputV)
{
    if (top >= 99) //stack is full
    {
        return -1;	//Error
    }
    else
    {
        stack[++top] = inputV;
    }
}

int pop(void)
{
    if (top < 0)
    {
        return -1;	//Error
    }
    else
        return stack[top--];
}


int fibonacciOne(int x)
{
    /* init stack */
    for (loop = 0; loop < 100; loop++)
    {
        stack[loop] = 0;
    }
    top = -1;

    /* Set first two number of fibonacci array*/
    stack[0] = 0;
    stack[1] = 1;

    /* calculate Nth number */
    if (x <= 0)
    {
        return -1;	//Error
    }
    else if ((x == 1) && (x == 2))
    {
        return stack[x - 1];
    }
    else if (x >= 100) //too big for demo
    {
        cout << "Error\n";
        return -1;
    }
    else   //Normal case
    {
        for (loop = 2; loop < x; loop++)
        {
            stack[loop] = stack[loop - 2] + stack[loop - 1];
        }

        /* show all array */
        for (int loop = 0; loop < x; loop++)
        {
            cout << stack[loop] << " ";
        }

        return stack[x - 1];
    }
}



   실행 결과 
 





Posted by 지그프리드 지그프리드

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

코드한건데 이자가 추가가안되네요 ㅜㅜ

/연산자가  /100한걸 정수단위로 짤라서 그런가하고 더블자료형으로 소수로 이자해봣는데도 안되네요...

왜이자가안나올까요



 

 잘못된 이유는 다음과 같습니다.  

 

○ Virtual 함수 선언 / 사용에 대해서 다시 확인하세요. Virtual은 상속 하는 상위 클래스에 선언합니다. 

○ Int형 변수에 10/100을 넣으니 0이 되고, 이 때문에 이자 계산이 0이 됩니다. 



   수정된 코드는 아래와 같습니다. 
 


#include
#include

using namespace std;
const int NAME_LEN = 20;


void ShowMenu(void);//메뉴출력
void MakeAccount(void);//계좌생성
void InsertMoney(void);//입금
void ExtractMoney(void);//출금
void OutputInfo(void);//계좌정보출력

enum
{
    MAKE = 1,
    INSERT = 2,
    EXTRACT = 3,
    OUTPUT = 4,
    EXIT = 5
};

class Account
{
private:

    char*username;
    int userid;
    int usermoney;
public:
    Account(char*name, int id, int money)
        :userid(id), usermoney(money)
    {
        int len = strlen(name) + 1;
        username = new char[len];
        strcpy(username, name);
    }

    int getid() const
    {
        return userid;
    }

    virtual void deposit(int money)
    {
        usermoney += (money);
    }
    void withdraw(int money)
    {
        if (usermoney < money)
            cout << "잔액부족" << endl;
        else
            usermoney -= money;
    }
    void showinfo() const
    {
        cout << "성명: " << username << endl;
        cout << "계좌번호: " << userid << endl;
        cout << "잔액: " << usermoney << endl;
    }
    ~Account()
    {
        delete[]username;
    }
};

class NormalAccount : public Account
{
private:
    float userija;
public:
    NormalAccount(char*name, int id, int money, int ija)
        : Account(name, id, money), userija(ija)
    {
    }
    void deposit(int money)
    {
        Account::deposit(money);
        Account::deposit(money*(userija / 100));
    }
};
class HighCreditAccount : public NormalAccount
{
private:
    int userplusija;
public:
    HighCreditAccount(char*name, int id, int money, int ija, int plusija)
        :NormalAccount(name, id, money, ija)
    {}
    void deposit(int money)
    {
        NormalAccount::deposit(money);
        Account::deposit(money*(userplusija / 100));
    }
};
class Handler
{
private:
    Account*Arr[100];
    int accnum;


public:
    Handler() : accnum(0)
    {}
    void showMenu(void)
    {
        cout << "---------Menu----------" << endl;
        cout << "1.계좌개설" << endl;
        cout << "2.입 금" << endl;
        cout << "3.출금" << endl;
        cout << "4.계좌정보 전체 출력" << endl;
        cout << "5.프로그램 종료" << endl;
    }
    void MakeAccount()
    {
        int choice;
        cout << '[' << "계좌종류선택" << ']' << endl;
        cout << "1.보통계좌선택 2.신용계좌선택" << endl;
        cout << "입력:";
        cin >> choice;

        if (choice == 1)
            MakeNormalAccount();
        else
            MakeHighCreditAccount();

    }
    void MakeNormalAccount()
    {
        int id;
        char name[NAME_LEN];
        int money;
        int ija;

        cout << "[보통계좌개설]" << endl;
        cout << "이름을 입력하시오: "; cin >> name;
        cout << "계좌번호를 입력하시오: "; cin >> id;
        cout << "입금액을 입력하시오: "; cin >> money;
        cout << "기본 이자율:"; cin >> ija;
        cout << endl;
        Arr[accnum++] = new NormalAccount(name, id, money, ija);
    }

    void MakeHighCreditAccount()
    {
        int id;
        char name[NAME_LEN];
        int money;
        int ija;
        int choice;
        int plusija;

        cout << "[보통계좌개설]" << endl;
        cout << "이름을 입력하시오: "; cin >> name;
        cout << "계좌번호를 입력하시오: "; cin >> id;
        cout << "입금액을 입력하시오: "; cin >> money;
        cout << "기본 이자율:"; cin >> ija;
        cout << "신용등급[A(1),B(2),C(3)]"; cin >> choice;
        cout << endl;
        switch (choice)
        {
        case 1:
            plusija = 107;
            Arr[accnum++] = new HighCreditAccount(name, id, money, ija, plusija);
            break;
        case 2:
            plusija = 104;
            Arr[accnum++] = new HighCreditAccount(name, id, money, ija, plusija);
            break;
        case 3:
            plusija = 102;
            Arr[accnum++] = new HighCreditAccount(name, id, money, ija, plusija);
            break;
        default:
            cout << "잘못입력하셨습니다" << endl;
        }

    }
    void InsertMoney(void)
    {
        int id;
        int money;
        cout << "[입금]" << endl;
        cout << "계좌번호: "; cin >> id;
        cout << "입금액 : "; cin >> money;
        cout << endl;
        for (int i = 0; i < accnum; i++)
        {
            if (Arr[i]->getid() == id)
            {
                Arr[i]->deposit(money);
                cout << "입금완료" << endl;
                return;

            }
            else
                cout << "잘못입력" << endl;
        }
    }
    void ExtractMoney(void)
    {
        int id;
        int money;
        cout << "[출금]" << endl;
        cout << "계좌번호: "; cin >> id;
        cout << "출금액: "; cin >> money;
        for (int i = 0; i < accnum; i++)
        {
            if (Arr[i]->getid() == id)
            {
                Arr[i]->withdraw(money);
                cout << "출금완료" << endl;
                return;
            }
            else
                cout << "잘못입력" << endl;
        }
    }
    void OutputInfo(void)
    {
        int id;
        cout << "[계좌정보출력]" << endl;
        cout << "계좌번호입력 : "; cin >> id;
        for (int i = 0; i < accnum; i++)
        {
            if (Arr[i]->getid() == id)
            {
                Arr[i]->showinfo();
            }
        }
    }
};
int main(void)
{
    Handler bank;
    int choice;
    while (1)
    {

        bank.showMenu();
        cout << "선택: ";
        cin >> choice;

        switch (choice)
        {
        case MAKE:
            bank.MakeAccount();
            break;

        case INSERT:
            bank.InsertMoney();
            break;

        case EXTRACT:
            bank.ExtractMoney();
            break;

        case OUTPUT:
            bank.OutputInfo();
            break;
        case EXIT:
            return 0;

        default:
            cout << "잘못입력하셨습니다. ";
        }
    }

    return 0;

};



Posted by 지그프리드 지그프리드

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절


블로그로 꿈을 이루는 법
국내도서
저자 : 이종범
출판 : 토야네북스 2013.02.27
상세보기



 

 블로그에 대한 다양한 관찰. 그러나, 아쉬운 편집과 책으로써의 일관성 결여

 


○  오늘 안 사실이지만, 블로그를 중심으로 돈을 벌거나 마케팅을 하는 것과 관련된 책이 엄청나게 많이 나와있다. 이 책은 알라딘 중고서점에서 찾은 책  중 가장 신간이어서 고른 책으로, 다행히 다음 View가 문들 닫은 것을 제외하고는 2015년에 현실에도 크게 벗어나지는 않는다. 블로그 글의 퍼블리싱 방법이 메타 블로그에서 빙글이나 플립보드 같은 좀 더 진보한 매체로 변경되었을 뿐.


○  전반적으로 풍부한 내용을 다루고 있으나, 아쉬움도 많다. 2015년에 책을 평가해서 그럴지도 모르겠지만, 책 내용중에 동어반복이 많다. 편집이 엉성하달까... 페이지 단위로 글을 쓰는 것에 익숙한 분이 책을 쓰다보니 발생한 실수라고 생각한다.  와이프 (또한 블로거)의 사례를 굳이 주부 블로거로 바꿔서 적은 점 등 이상한 문체, 편집은 거슬린다. 또한, 고급 블로거가 되기 위한 디테일은 없다. 그보다는, 블로그를 왜 운영해야 하고, 블로그를 통해 얻는 "작가로써의 이익" 측면에 집중하고 있다. 마치, 초등학생에게 일기 쓰기를 권하는 것과 같은 느낌도 있다. 실용서라고는 하지만, 역시 좀 엉성한 느낌이다. 


○  그럼에도 불구하고, 다양한 사례를 다루려고 노력한 점은 높이 살만하다. 오늘날에야 더 새로운 시간이 많이 있으니, 굳이 이 책을 골라서 읽어볼 필요는 없을 것 같다. 

Posted by 지그프리드 지그프리드

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절


BLOG main image
일상, 프로그래밍, IT 그리고 직장생활, Dive, 여행 by 지그프리드

카테고리

Class List (402)
Studies (30)
Exercise & Quizz (10)
Term Project (0)
ECIM list (Help!) (10)
Issues & News (0)
Gossip about IT & Job (22)
Tools (2)
Think about the Justice (23)
Book Review (170)
조엘 온 소프트웨어(번역) (28)
Diary (87)
Vacations (9)
Clash of clans 클래시 오브.. (11)

글 보관함

달력

«   2015/08   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Total : 314,680
Today : 20 Yesterday : 15