#include <stdio.h>
/************************/
/* 演算 */
/************************/
/* 演算関数へのポインタの型 */
typedef int (*Operator)(int, int);
/* 演算子の表示用文字 */
static const char* g_operator_strings[] = { "+", "-", "*", "%", "xor", "and", "or" };
/* 演算子の優先度 */
static const int g_operator_priorities[] = {0,1,2,3,4,5,6};
/********************************/
/* 表示 */
/********************************/
/* 現在の状態を表示 */
#define PRINT_STATUS(N) \
{ \
int i; \
printf(" op = (%d)", operonds[0]); \
for(i = 0; i < N; i++){ \
printf(" %s (%d)", g_operator_strings[operatons[i]], operonds[i+1]); \
} \
printf("\n"); \
}
/**********************************/
/* 課題の関数 */
/**********************************/
int op(int a, int b, int c){
/*
* 演算子 oと、数字nを
* n[0] o[0] n[1] o[1] n[2] ,..., o[5], n[6]
* で記憶する。演算子を適用するときは、
* n[i] = o[i]( n[i], n[i+1] )
* として、i番目の数字を置き換える。
* その後、n[i+1], o[i] 以降の演算子と数字を前に詰める。
*/
/* 演算子の配列 */
int operatons[5];
/* 残りの演算対象の配列 */
int operonds[6] = {a,b,c,a,b,c};
/* 残りの演算子の数 */
int n = 5;
printf("op(%d,%d,%d) is called.\n", a,b,c);
/* まず、演算子を選択 */
{
/* op1=(3*a+5*b)の7による剰余がkの場合、演算kを選択 */
operatons[0] = (3*a+5*b)%7;
printf(" op1 is %s\n", g_operator_strings[operatons[0]]);
/* op2=(5*b+4*c)の7による剰余がkの場合、演算kを選択 */
operatons[1] = (5*b+4*c)%7;
printf(" op2 is %s\n", g_operator_strings[operatons[1]]);
/* op3=(a+3*c)の7による剰余がkの場合、演算kを選択 */
operatons[2] = ( a+3*c)%7;
printf(" op3 is %s\n", g_operator_strings[operatons[2]]);
/* op4=(a+2*b)の7による剰余がkの場合、演算kを選択 */
operatons[3] = ( a+2*b)%7;
printf(" op4 is %s\n", g_operator_strings[operatons[3]]);
/* op5=(3*c+2*b)の7による剰余がkの場合、演算kを選択 */
operatons[4] = (3*c+2*b)%7;
printf(" op5 is %s\n", g_operator_strings[operatons[4]]);
}
/* 演算子がなくなるまで繰り返す */
for(; n > 0; n--){
int i;
int no;
PRINT_STATUS(n);
/* 優先順位の最も高い演算子を探す */
no = 0;
for(i=1; i < n; i++){
if(g_operator_priorities[operatons[i]] < g_operator_priorities[operatons[no]]){
no = i;
}
}
printf(" next operator is %s(op%d, priority = %d)\n",
g_operator_strings[operatons[no]], no+1, g_operator_priorities[operatons[no]]
);
/* 演算子を適用 */
switch(operatons[no]){
case 0: operonds[no] += operonds[no+1]; break; /* 演算0:+ */
case 1: operonds[no] -= operonds[no+1]; break; /* 演算1:- */
case 2: operonds[no] *= operonds[no+1]; break; /* 演算2:* */
case 3: operonds[no] %= operonds[no+1]; break; /* 演算3:%(剰余) */
case 4: operonds[no] ^= operonds[no+1]; break; /* 演算4:xor */
case 5: operonds[no] &= operonds[no+1]; break; /* 演算5:and */
case 6: operonds[no] |= operonds[no+1]; break; /* 演算6:or */
}
/* 後ろの演算対象と演算子を前に移動 */
for(i = no+1; i < n; i++){
operonds[i] = operonds[i+1];
operatons[i-1] = operatons[i];
}
}
PRINT_STATUS(n);
printf("result = %d\n", operonds[0]);
/* 最後に残った数字が結果 */
return operonds[0];
}
int main(void){
op(10,8,4);
getchar();
return 0;
}