階乗値を求めるプログラム factorial.c
#include <stdio.h>
int factorial(int n)
{
if (n > 0)
return n * factorial(n - 1);
else
return 1;
}
int main(void)
{
int x;
printf("整数を入力せよ:");
scanf_s("%d", &x);
printf("%dの階乗は%dです。\n", x, factorial(x));
return 0;
}
最大公約数を求めるプログラム euclid.c
#include <stdio.h>
int gcd(int x, int y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
int main(void)
{
int x, y;
puts("二つの整数の最大公約数を求めます。");
printf("整数を入力せよ:");
scanf_s("%d", &x);
printf("整数を入力せよ:");
scanf_s("%d", &y);
printf("最大公約数は%dです。\n", gcd(x, y));
return 0;
}
ひとつのプロジェクト内に複数のmain関数を作るとエラーになる。
複数の機能を扱いたい場合は、前にリストやハッシュで作ったものと同様に、メニューを作って呼び分けるようにする。
RecursiveTest.c
#include <stdio.h>
#include "recursive.h"
typedef enum {
TERMINATE, FACTORIAL, EUCLID
} Menu;
Menu SelectMenu(void)
{
int ch;
do {
printf("(1)階乗 (2)最大公約数 (0)終了");
scanf_s("%d", &ch);
} while (ch < TERMINATE || ch > EUCLID);
return (Menu)ch;
}
int main(void)
{
Menu menu;
do {
switch (menu = SelectMenu()) {
case FACTORIAL:
fmain();
break;
case EUCLID:
emain();
break;
}
} while (menu != TERMINATE);
return 0;
}
recursive.h
#ifndef __RECURSIVE #define __RECURSIVE int fmain(void); int emain(void); #endif
factorial.c の main() を fmain() に変更し、euclid.c の main() を emain() に変更する。
テキストの演習問題をやってみよう!
ネットで検索してもOK!
ただし、動作をきちんと自分で理解すること。
演習5-1
再帰関数呼び出しを用いずに、関数factorialを実現せよ。演習5-2
再帰関数呼び出しを用いずに、関数euclidを実現せよ。
作成済みの再帰呼び出し関数は、関数名の最後に _r をつけてエラー回避する。
factorial() → factorial_r()
euclid() → euclid_r()
演習5-1解答例
int factorial(int n)
{
int i;
int result = 1;
for (i = 1; i <= n; i++) {
result = result * i;
}
return result;
}
演習5-2解答例
int gcd(int x, int y)
{
int v = (x < y) ? x : y;
int i;
for (i = v; i > 0; i--) {
//printf("x=%d y=%d v=%d xv=%d yv=%d\n", x, y, i, x % i, y % i);
if ((x % i == 0) && (y % i == 0)) {
return i;
}
}
return 1;
}
再帰アルゴリズムの解析
RecursiveTest.cに追加
#include <stdio.h>
#include "recursive.h"
typedef enum {
TERMINATE, FACTORIAL, EUCLID, ANALYZE
} Menu;
Menu SelectMenu(void)
{
int ch;
do {
printf("(1)階乗 (2)最大公約数 (3)解析 (0)終了 : ");
scanf_s("%d", &ch);
} while (ch < TERMINATE || ch > ANALYZE);
return (Menu)ch;
}
int main(void)
{
Menu menu;
do {
switch (menu = SelectMenu()) {
case FACTORIAL:
fmain();
break;
case EUCLID:
emain();
break;
case ANALYZE:
amain();
break;
}
} while (menu != TERMINATE);
return 0;
}
recur.c
#include <stdio.h>
void recur(int n)
{
if (n > 0) {
recur(n - 1);
printf("%d\n", n);
recur(n - 2);
}
}
int amain(void)
{
int x;
printf("整数を入力せよ: ");
scanf("%d", &x);
recur(x);
return 0;
}
recursive.h
#ifndef __RECURSIVE #define __RECURSIVE int fmain(void); int emain(void); int amain(void); #endif
ハノイの塔
hanoi.c
#include <stdio.h>
void move(int no, int x, int y)
{
if (no > 1)
move(no - 1, x, 6 - x - y);
printf("円盤[%d]を%d軸から%d軸へ移動\n", no, x, y);
if (no > 1)
move(no - 1, 6 - x - y, y);
}
int hmain(void)
{
int n;
printf("ハノイの塔\n円盤の枚数: ");
scanf("%d", &n);
move(n, 1, 3);
return 0;
}
RecursiveTest.c
#include <stdio.h>
#include "recursive.h"
typedef enum {
TERMINATE, FACTORIAL, EUCLID, ANALYZE, HANOI
} Menu;
Menu SelectMenu(void)
{
int ch;
do {
printf("(1)階乗 (2)最大公約数 (3)解析 (4)ハノイの塔 (0)終了 : ");
scanf_s("%d", &ch);
} while (ch < TERMINATE || ch > HANOI);
return (Menu)ch;
}
int main(void)
{
Menu menu;
do {
switch (menu = SelectMenu()) {
case FACTORIAL:
fmain();
break;
case EUCLID:
emain();
break;
case ANALYZE:
amain();
break;
case HANOI:
hmain();
break;
}
} while (menu != TERMINATE);
return 0;
}
recursive.h
#ifndef __RECURSIVE #define __RECURSIVE int fmain(void); int emain(void); int amain(void); int hmain(void); #endif