24点游戏-去除重复结果

来源:互联网 发布:网络通信概念股 编辑:程序博客网 时间:2024/05/01 00:21

game.c

/* * game.c * *  Created on: 2011-9-27 *      Author: brunie */#include "game.h"#include "stack.h"Node* standardize_tree(Node* root);int save_unique(Game *game, Node *root);void get_expression(Node *root, char *exp);Node *copy_tree(Node *root);void destroy_tree(Node *root);int operate(Node *left, Node *right, Node *result, int type){    switch (type)    {        case ADD:            result->res = left->res + right->res;            result->op = '+';            result->left = left;            result->right = right;            break;        case SUB:            result->res = left->res - right->res;            result->op = '-';            result->left = left;            result->right = right;            break;        case MUL:            result->res = left->res * right->res;            result->op = '*';            result->left = left;            result->right = right;            break;        case DIV:            if (right->res != 0)            {                result->res = left->res / right->res;                result->op = '/';                result->left = left;                result->right = right;            }            break;        case RSUB:            result->res = right->res - left->res;            result->op = '-';            result->left = right;            result->right = left;            break;        case RDIV:            if (left->res != 0)            {                result->res = right->res / left->res;                result->op = '/';                result->left = right;                result->right = left;            }            break;    }    return 1;}int calculate(Node **node_list, int len, Game *game){    int i, j, k, tmp, type;    if (len == 1)    {        if (fabs(node_list[0]->res - FINAL_RESULT) < PRECISION)        {            save_unique(game, node_list[0]);            game->success = OK;        }    }    else    {        Node **next = (Node **) malloc((len - 1) * sizeof(pNode));        pNode tmp_result = (pNode) malloc(sizeof(Node));        next[0] = tmp_result;        for (i = 0; i < len; i++)        {            for (j = i + 1; j < len; j++)            {                tmp = 1;                for (k = 0; k < len; k++)                {                    if (k != i && k != j)                    {                        next[tmp++] = node_list[k];                    }                }                for (type = 0; type < OPERATOR_TYPES; type++)                {                    operate(node_list[i], node_list[j], tmp_result, type);                    calculate(next, len - 1, game);                }            }        }// for i        free(next);        free(tmp_result);    }//else    return 1;}void Game_execute(Game *game){    calculate(game->node_list, N_FIGURES, game);}int priority(char operator){    if (operator == 0)        return 3;    else if (operator == '+' || operator == '-')        return 1;    else        return 2;}Node* copy_tree(Node *root){    if (0 == root)        return 0;    Node *new_root = (Node *)malloc(sizeof(Node));    *new_root = *root;    new_root->left = copy_tree(root->left);    new_root->right = copy_tree(root->right);    return new_root;}void destroy_tree(Node *root){    if (root->left)        destroy_tree(root->left);    if (root->right)        destroy_tree(root->right);    free(root);}void sort_node(pNode *pnodes, int len){    int i,j;    int flag = 1;    for (i = 0; i < len - 1 && flag; i++)    {        flag = 0;        for (j = 0; j < len - i - 1; j++)        {            if (pnodes[j]->res > pnodes[j + 1]->res)            {                pNode tmp = pnodes[j];                pnodes[j] = pnodes[j + 1];                pnodes[j + 1] = tmp;                flag = 1;            }        }    }    /*for (i = 0; i < len; i++)        printf("%f ", (*pnodes[i])->res);    printf("\n");*/}Node* create_tree(pNode *left_nodes, int left_len,        pNode *right_nodes, int right_len, char op){    sort_node(left_nodes, left_len);    sort_node(right_nodes, right_len);    pNode left_result, right_result;    int type;    int i;    if (op == '+')        type = ADD;    else        type = MUL;    if (left_len >= 2)    {        for (i = 0; i < left_len - 1; i++)        {            left_result = (pNode) malloc(sizeof(Node));            operate(left_nodes[i], left_nodes[i + 1], left_result, type);            left_nodes[i + 1] = left_result;        }    }    else    {        left_result = left_nodes[0];    }    if (right_len >= 1)    {        for (i = 0; i < right_len; i++)        {            right_result = (pNode) malloc(sizeof(Node));            operate(left_result, right_nodes[i], right_result, type + 1);            left_result = right_result;        }    }    return left_result;}Node* standardize_tree(Node* root){    Node   *tmp, *mid_root;    istack *open = (istack*)malloc(sizeof(istack));    pNode left_nodes[N_FIGURES];    pNode right_nodes[N_FIGURES];    int left_len = 0, right_len = 0;    char op_a, op_b, op;    init_stack(open);    tmp = root;    op = tmp->op;    if (op == '+' || op == '-')    {        op = op_a = '+';        op_b = '-';    }    else    {        op = op_a = '*';        op_b = '/';    }    do    {        if (tmp->op == op_a)        {            push(open, tmp);            tmp = tmp->left;        }        else if (tmp->op == op_b)        {            push(open, tmp);            mid_root = tmp->right;            if (tmp->right->op)                mid_root = standardize_tree(tmp->right);            right_nodes[right_len++] = mid_root;            tmp->right = 0;            tmp = tmp->left;        }        else        {            mid_root = tmp;            if (tmp->op)                mid_root = standardize_tree(tmp);            left_nodes[left_len++] = mid_root;            if (!stack_empty(open))            {                pop(open, &tmp);                while (!tmp->right && !stack_empty(open))                {                    free(tmp);                    pop(open, &tmp);                }                mid_root = tmp;                tmp = tmp->right;                if (mid_root->op)                    free(mid_root);            }            else                tmp = 0;        }    } while (tmp || !stack_empty(open));    free(open);    mid_root = create_tree(left_nodes, left_len, right_nodes, right_len, op);    return mid_root;}int save_unique(Game *game, Node* root){    int i;    char *exp = (char*) malloc(EXPRESSION_LEN);    exp[0] = '\0';    Node *tmp_root = copy_tree(root);    tmp_root = standardize_tree(tmp_root);    get_expression(tmp_root, exp);    //printf("%s\n", exp);    destroy_tree(tmp_root);    for (i = 0; i < game->n_solutions; i++)    {        if (strcmp(exp, game->unique_expressions[i]) == 0)        {            break;        }    }    if (i == game->n_solutions)    {        if (game->n_solutions == MAX_N_SOLUTIONS)        {            game->unique_expressions = (char **) realloc(                    game->unique_expressions,                    (game->n_solutions + MAX_N_SOLUTIONS) * sizeof(char*));            if (!game->unique_expressions)                exit(OVERFLOW);        }        game->unique_expressions[game->n_solutions++] = exp;        return TRUE;    }    return FALSE;}void get_expression(Node *root, char *exp){    char left_op, right_op, op;    if (root->left == 0 && root->right == 0)    {        sprintf(exp + strlen(exp),"%d", (int)(root->res));    }    else    {        left_op = root->left->op;        right_op = root->right->op;        op = root->op;        if (priority(op) > priority(left_op))        {            sprintf(exp + strlen(exp),"(");            get_expression(root->left, exp);            sprintf(exp + strlen(exp),")");        }        else            get_expression(root->left, exp);        sprintf(exp + strlen(exp), " %c ", op);        if (priority(op) > priority(right_op)            || (op == '-' && right_op == '-')            || (op == '-' && right_op == '+')            || (op == '/' && right_op == '*')            || (op == '/' && right_op == '/'))        {            sprintf(exp + strlen(exp), "(");            get_expression(root->right, exp);            sprintf(exp + strlen(exp), ")");        }        else            get_expression(root->right, exp);    }}void print_results(Game *game){    printf("\nTotal %d unique results:\n", game->n_solutions);    int i;    for (i = 0; i < game->n_solutions; i++)    {        printf("%s = %d\n", game->unique_expressions[i], FINAL_RESULT);    }}void init_list(Game *game){    int i;    game->success = 0;    game->n_solutions = 0;    for (i = 0; i < N_FIGURES; i++)    {        game->node_list[i]->res = game->figures[i];    }}int init_data(Game *game){    int i;    game->figures = (int *)malloc(N_FIGURES * sizeof (int));    game->node_list = (pNode *)malloc(N_FIGURES * sizeof (pNode));    game->unique_expressions = (char **)malloc(MAX_N_SOLUTIONS * sizeof (char *));    if (!(game->figures && game->node_list && game->unique_expressions))        exit(OVERFLOW);    for (i = 0; i < N_FIGURES; i++)    {        game->node_list[i] = (pNode)malloc(sizeof(Node));        if (!game->node_list[i])            exit(OVERFLOW);        game->node_list[i]->left = 0;        game->node_list[i]->right = 0;        game->node_list[i]->op = 0;    }    return TRUE;}void destory_data(Game *game){    int i;    if (game->figures)    {        free(game->figures);        game->figures = 0;    }    if (game->node_list)    {        for (i = 0; i < N_FIGURES; i++)        {            free(game->node_list[i]);        }        free(game->node_list);        game->node_list = 0;    }    if (game->unique_expressions)    {        for (i = 0; i < game->n_solutions; i++)        {            free(game->unique_expressions[i]);        }        free(game->unique_expressions);        game->unique_expressions = 0;    }}

game.h

/* * game.h * *  Created on: 2011-9-27 *      Author: brunie */#ifndef GAME_H_#define GAME_H_#define MAX_INPUT 13#define MIN_INPUT 1#define N_FIGURES4#define OPERATOR_TYPES6#define FINAL_RESULT24#define EXPRESSION_LEN 30#define MAX_N_SOLUTIONS 100#define PRECISION(1E-6)#define TRUE1#define FALSE0#define OK1#define OVERFLOW(-2)#include  <stdlib.h>#include<stdio.h>#include<math.h>#include <time.h>#include <string.h>typedef struct Node{double res;struct Node *left;struct Node *right;char op;}Node, *pNode;enum Operators {ADD, SUB, MUL, DIV, RSUB, RDIV};typedef struct Game{int *figures;pNode *node_list;int success;int n_solutions;char **unique_expressions;}Game, *pGame;void Game_execute(Game *game);void print_results(Game *game);void init_list(Game *game);int init_data(Game *game);void destory_data(Game *game);#endif /* GAME_H_ */

main.c

/* * main.c * *  Created on: 2011-9-27 *      Author: brunie */#include "twenty_four.h"int main(){setbuf(stdout,0);int status;status = play_game();if (status)printf("Successful!\n");elseprintf("Not exist!\n");return 0;}

stack.c

/* * stack.c * *  Created on: 2011-10-5 *      Author: brunie */#include "stack.h"int init_stack(istack *stack){stack->base = (pNode *)malloc(STACK_INIT_SIZE * sizeof(pNode));if (!stack->base)exit (-1);stack->top = stack->base;stack->stack_size = STACK_INIT_SIZE;return 1;}void destory_stack(istack *stack){if(!stack->base)free(stack->base);stack->base = 0;}int stack_empty(istack *stack){if (stack->top == stack->base)return TRUE;elsereturn FALSE;}int stack_length(istack *stack){return stack->top - stack->base;}int get_top(istack *stack, pNode *pnode){if (stack->top == stack->base)return 0;*pnode = *(stack->top - 1);return 1;}int push(istack *stack, pNode pnode){if (stack->top - stack->base >= stack->stack_size){stack->base = (pNode *) realloc(stack->base,(stack->stack_size + STACK_INCREMENT) * sizeof(pNode));if (!stack->base)exit(-1);stack->top = stack->base + stack->stack_size;stack->stack_size += STACK_INCREMENT;}*stack->top++ = pnode;return 1;}int pop(istack *stack, pNode *pnode){if (stack->top == stack->base)return 0;*pnode = * --stack->top;return 1;}

stack.h

/* * stack.h * *  Created on: 2011-10-5 *      Author: brunie */#ifndef STACK_H_#define STACK_H_#include "game.h"#defineSTACK_INIT_SIZE50#defineSTACK_INCREMENT10typedef struct{pNode*base;pNode*top;intstack_size;}istack;int init_stack(istack *stack);void destory_stack(istack *stack);int stack_empty(istack *stack);int stack_length(istack *stack);int get_top(istack *stack, pNode *pnode);int pop(istack *stack, pNode *pnode);int push(istack *stack, pNode pnode);#endif /* STACK_H_ */

twenty_four.c

/* * twenty_four.c * *  Created on: 2011-10-5 *      Author: brunie */#include "twenty_four.h"void input(Game *game){int digit;int c;int i;while(1){printf("Please input %d figures, each figure in the range of [%d,%d]:\n",N_FIGURES, MIN_INPUT, MAX_INPUT);digit = 0;i = 0;while ((c = getchar()) == ' ');do{if (c <= '9' && c >= '0')digit = digit * 10 + c - '0';else if (c == ' '){if (digit > MAX_INPUT || digit < MIN_INPUT)break;game->figures[i++] = digit;//printf("%d ",digit);if (i == N_FIGURES)break;while((c = getchar()) == ' ');if(c > '9' || c < '0')break;digit = c - '0';}else{if (c == '\n'){game->figures[i++] = digit;//printf("%d ",digit);}break;}}while ((c = getchar()) != EOF);if (c != '\n')while ((c = getchar()) != '\n');if (i == N_FIGURES)break;printf("Illegal input!\n");}}int play_game(){int c;int flag;Game game;init_data(&game);do{input(&game);init_list(&game);Game_execute(&game);print_results(&game);printf("Do you want to play again(y/n):");flag = getchar();while ((c = getchar()) != '\n' && c != EOF);} while (flag == 'y' || flag == 'Y');destory_data(&game);return game.success;}

tweny_four.h

/* * twenty_four.h * *  Created on: 2011-10-5 *      Author: brunie */#ifndef TWENTY_FOUR_H_#define TWENTY_FOUR_H_#include "game.h"void input(Game *game);int play_game();#endif /* TWENTY_FOUR_H_ */



原创粉丝点击