老师给孩子留的题。除了C语言,啥也不会,就用C写了一个。
【题目】
6 5 4 3 2 1 = 24 数字之间加入加,减,乘运算符,使等式成立。
【第三方资源】
表达式字符串解析来自网友田野麦子,万分感谢。
https://blog.csdn.net/weixin_38679924/article/details/88192241
【代码说明】
由三个文件构成,VS2019 测试通过。
【使用方法】
xxx.exe 24
参数1为和的值。
输出到result.txt
【代码】
文件1
/****************************************************************************************************/
/* 问题: */
/* 6 5 4 3 2 1 = 24 数字之间加入加,减,乘运算符 */
/* */
/* */
/* Auther; Shi Guangxin */
/* */
/* Date; 2020/03/21 */
/* */
/****************************************************************************************************/
#include <iostream>
#include <stdio.h>
#include "ExpressAnalyze.h"
/****************************************************************************************************/
/* */
/* 宏定义 */
/* */
/****************************************************************************************************/
#define MAX_NUMBER_ITEM_NUM ( 6 ) /* 公式中数字的个数 */
//#define EXPERT_RSLT ( 5 ) /* 公式中数字的个数 */
/* MAX_ANSWER_NUM = 2^( (MAX_NUMBER_ITEM_NUM - 2) * 2 ) - 1 */
#define MAX_ANSWER_NUM ( 1023 ) /* 求解的最大个数 */
#define MAX_SAVE_LOG_NUM ( 50 ) /* 求解的最大个数 */
/****************************************************************************************************/
/* 调试开关 */
/****************************************************************************************************/
#ifdef _DEBUG
#define __DEBUG__
#endif
/****************************************************************************************************/
/* LOG输出控制 */
/****************************************************************************************************/
#ifdef __DEBUG__
#define DBG_LOG1 printf_s
#else
#define DBG_LOG1
#endif
#define ERR_PRT printf_s
#define UI_PRT printf_s
/****************************************************************************************************/
/* LOG输出控制 */
/****************************************************************************************************/
#define GET_STR_OPERATOR(idx) ( cpOPER_STR[idx] )
/****************************************************************************************************/
/* LOG输出控制 */
/****************************************************************************************************/
#define GET_STR_ERR(idx) ( cpERR_STR[idx] )
/****************************************************************************************************/
/* operator MASK CODE (同运算符的个数有关系) */
/****************************************************************************************************/
#define MASK_OPERATOR (0x03)
/****************************************************************************************************/
/* 错误码 */
/****************************************************************************************************/
typedef enum
{
ERR_OK = 0,
ERR_NOTOK,
ERR_PTR_NULL,
ERR_ARRAY_OUTBOUND,
ERR_MAIN_ARG_ERR,
ERR_EXPRESS_STR_ERR,
ERR_HELP_ONLY,
ERR_RESERVED
}eERROR;
/****************************************************************************************************/
/* */
/* 结构体定义 */
/* */
/****************************************************************************************************/
/****************************************************************************************************/
/* 运算符 */
/****************************************************************************************************/
typedef enum
{
PLUS = 0, /* + */
MINUS, /* - */
MUL, /* * */
DIV, /* / */
OPERATOR_MAX
} OPERATOR;
/****************************************************************************************************/
/* 输入参数 */
/****************************************************************************************************/
typedef struct
{
unsigned long ulFormNum[ MAX_NUMBER_ITEM_NUM ]; /* 竖式中的各项数字 */
unsigned long ulAnswer; /* 预期结果 */
}FORMULA;
/****************************************************************************************************/
/* 竖式运算结果结构体 */
/****************************************************************************************************/
typedef struct
{
char ucFormExpress[ MAX_EXPRESS_LEN ]; /* 竖式中的字符串化 */
double answer; /* 竖式中的计算结果 */
eERROR rslt; /* 是否同预期值一致 */
}FORMULA_RSLT_SUB;
/****************************************************************************************************/
/* 竖式运算结果管理体 */
/****************************************************************************************************/
typedef struct
{
FORMULA_RSLT_SUB stExpressRslt[MAX_SAVE_LOG_NUM]; /* 计算结果竖式 */
int ok_num; /* 计算结果的OK总数 */
int sum; /* 计算结果的总数 */
}FORMULA_RSLT;
/****************************************************************************************************/
/* 常量 */
/****************************************************************************************************/
const char *cpOPER_STR[OPERATOR_MAX] =
{
"+",
"-",
"*",
"/"
};
const char *cpERR_STR[ERR_RESERVED] =
{
"ERR_OK = 0",
"ERR_NOTOK",
"ERR_PTR_NULL",
"ERR_ARRAY_OUTBOUND",
"ERR_MAIN_ARG_ERR",
"ERR_HELP_ONLY",
"ERR_EXPRESS_STR_ERR"
};
/****************************************************************************************************/
/* 全局变量 */
/****************************************************************************************************/
FORMULA_RSLT stEXPRESS_RSLT;
int unRESPECT_VAL;
/****************************************************************************************************/
/* */
/* 函数声明 */
/* */
/****************************************************************************************************/
static eERROR Initilaze( void );
static eERROR Close( void );
static eERROR Output( FORMULA_RSLT* p_rslt );
static eERROR InputProcess( int argc, char* argv[], FORMULA* inputData);
static eERROR SearchProcess( FORMULA* inputData, FORMULA_RSLT *rslt);
static eERROR OPERFUNC_TRY( unsigned long ulFormNum[], OPERATOR arrOpe[],
const int maxnum, const unsigned int asnwer,
FORMULA_RSLT_SUB *p_rslt );
/****************************************************************************************************/
/* 主函数 */
/****************************************************************************************************/
void main( int argc, char* argv[] )
{
eERROR e_ret;
FORMULA st_input_data;
e_ret = Initilaze();
if ( ERR_OK != e_ret )
{
ERR_PRT("\n Initilaze Error(%s)", GET_STR_ERR(e_ret) );
goto ERR_PROC;
}
e_ret = InputProcess( argc, argv ,&st_input_data );
if ( ERR_OK != e_ret )
{
ERR_PRT("\n InputProcess Error(%s)", GET_STR_ERR(e_ret) );
goto ERR_PROC;
}
e_ret = SearchProcess(&st_input_data, &stEXPRESS_RSLT);
if ( ERR_OK != e_ret )
{
ERR_PRT("\n SearchProcess Error(%s)", GET_STR_ERR(e_ret) );
goto ERR_PROC;
}
e_ret = Output(&stEXPRESS_RSLT);
if ( ERR_OK != e_ret )
{
ERR_PRT("\n Output Error(%s)", GET_STR_ERR(e_ret) );
goto ERR_PROC;
}
e_ret = Close();
if ( ERR_OK != e_ret )
{
ERR_PRT("\n Close Error(%s)", GET_STR_ERR(e_ret) );
goto ERR_PROC;
}
ERR_PROC:
return;
}
/****************************************************************************************************/
/* 系统初始化函数 */
/****************************************************************************************************/
static eERROR Initilaze( void )
{
UI_PRT( "\nLadys and gentleman, I miss you." );
memset(&stEXPRESS_RSLT, 0x00, sizeof(stEXPRESS_RSLT));
return( ERR_OK );
}
/****************************************************************************************************/
/* 系统关闭函数 */
/****************************************************************************************************/
static eERROR Close( void )
{
/* Nothing To Do */
return( ERR_OK );
}
/****************************************************************************************************/
/* 输入数据处理 */
/****************************************************************************************************/
static eERROR InputProcess( int argc, char* argv[], FORMULA* inputData )
{
int cnt;
if ( ( argc != 2 ) || ( atoi( argv[1] ) <=0 ) )
{
UI_PRT("\nInput Argument is error!" );
UI_PRT( "\nArg0 must be digial." );
return(ERR_MAIN_ARG_ERR);
}
for ( cnt = 0; cnt < MAX_NUMBER_ITEM_NUM; cnt++ )
{
/* 数字是倒着的 6 5 4 3 2 1 = 24 */
inputData->ulFormNum[cnt] = MAX_NUMBER_ITEM_NUM - cnt;
}
inputData->ulAnswer = atoi( argv[1] );
unRESPECT_VAL = inputData->ulAnswer;
return ( ERR_OK );
}
/****************************************************************************************************/
/* 遍历搜索 */
/****************************************************************************************************/
static eERROR SearchProcess(FORMULA* inputData, FORMULA_RSLT *p_rslt)
{
int rslt_pos;
eERROR e_ret;
OPERATOR e_oper[ MAX_NUMBER_ITEM_NUM - 1 ];
unsigned long int cnt, cnt2;
FORMULA_RSLT_SUB st_express_rslt, *stp_rslt;
/* 变量初始化 */
rslt_pos = 0;
stp_rslt = &st_express_rslt;
p_rslt->ok_num = 0;
p_rslt->sum = 0;
for ( cnt = 0; cnt < MAX_ANSWER_NUM; cnt++ )
{
DBG_LOG1("\n CNT = %d",cnt );
memset( stp_rslt, 0x00, sizeof( FORMULA_RSLT_SUB ) );
/*
The kind of operator is four , so use 2 bit.
Attention:
When you change the number of the operator,
you must change it.
op4 op3 op2 op1 op0
bit 98 76 54 32 10
*/
for ( cnt2 = 0; cnt2 < MAX_NUMBER_ITEM_NUM - 1; cnt2++ )
{
e_oper[ cnt2 ] = (OPERATOR)( ( cnt >> ( cnt2 * 2) ) & MASK_OPERATOR);
// DBG_LOG1( "\n e_oper[ %d ] = %s", cnt2, GET_STR_OPERATOR( e_oper[cnt2] ) );
}
/* 根据输入的数字和运算符,求出竖式的结果 */
e_ret = OPERFUNC_TRY(inputData->ulFormNum, e_oper, MAX_NUMBER_ITEM_NUM, inputData->ulAnswer, stp_rslt );
if ( e_ret != ERR_OK)
{
ERR_PRT( "\nSearchProcess[%d]-->OPERFUNC_TRY() Error (%s)", cnt, GET_STR_ERR(e_ret) );
return( ERR_NOTOK );
}
else if ( p_rslt->ok_num >= sizeof( p_rslt->stExpressRslt ) / sizeof( p_rslt->stExpressRslt[0] ) )
{
/* When buff is full, terminated the next search and finished. */
e_ret = ERR_ARRAY_OUTBOUND;
ERR_PRT( "\nSearchProcessr[%d] Error(%s), BuffSize = %d / %d ", cnt, GET_STR_ERR(e_ret), p_rslt->ok_num, sizeof( p_rslt->stExpressRslt ) / sizeof( p_rslt->stExpressRslt[0] ) );
break;
}
else if ( inputData->ulAnswer == stp_rslt->answer)
{ /* Find the answer */
DBG_LOG1( " --->>> OK" );
memcpy( &p_rslt->stExpressRslt[p_rslt->ok_num], stp_rslt, sizeof(FORMULA_RSLT_SUB) ) ;
UI_PRT( "\n [%02d] %s = %1.0lf", p_rslt->ok_num +1, stp_rslt->ucFormExpress, stp_rslt->answer );
p_rslt->ok_num++;
}
else
{
/* Nothing to do. */
}
p_rslt->sum++;
}
return(e_ret);
}
/****************************************************************************************************/
/* 将计算式转换为字符串,计算表达式的值 */
/****************************************************************************************************/
static eERROR OPERFUNC_TRY(unsigned long ulFormNum[], OPERATOR arrOpe[], const int maxnum, const unsigned int answer, FORMULA_RSLT_SUB* p_rslt )
{
unsigned long sum = 0;
char *express_buff;
int cnt, len = 0, pos = 0;
eERROR e_ret = ERR_OK;
express_buff = &p_rslt->ucFormExpress[0];
memset( express_buff, 0x00, sizeof(MAX_EXPRESS_LEN) );
for ( cnt = 0; cnt < maxnum - 1; cnt++ )
{
p_rslt->rslt = ERR_NOTOK;
len = snprintf( express_buff + pos,
MAX_EXPRESS_LEN - pos,
"%d%s",
ulFormNum[cnt],
GET_STR_OPERATOR(arrOpe[cnt])
);
pos += len;
if ( pos > MAX_EXPRESS_LEN )
{
e_ret = ERR_ARRAY_OUTBOUND;
ERR_PRT( "\n OPERFUNC_TRY express_buff out of bound error(%d), cnt = %d", e_ret, cnt );
break;
}
}
if ( e_ret == ERR_OK )
{
len = snprintf( express_buff + pos, MAX_EXPRESS_LEN - pos,
"%d",
ulFormNum[maxnum - 1]);
if ( len <= 0 )
{
e_ret = ERR_ARRAY_OUTBOUND;
ERR_PRT( "\n OPERFUNC_TRY express_buff out of bound error(%s).", GET_STR_ERR(e_ret) );
}
}
else
{
goto ERR_PROC;
}
#if 0
if ( cnt <= 0 ) {
p_rslt->rslt = ERR_NOTOK;
return ( ERR_NOTOK);
}
#endif
if ( 0 == calc_express_val( express_buff, &p_rslt->answer ) )
{
if ( p_rslt->answer == answer)
{
p_rslt->rslt = ERR_OK;
}
}
else
{
e_ret = ERR_EXPRESS_STR_ERR;
ERR_PRT( "\nOPERFUNC_TRY calc_express_val() Error[%s].", express_buff );
goto ERR_PROC;
}
DBG_LOG1("\n %s = %lf\n", express_buff, p_rslt->answer);
return( ERR_OK );
ERR_PROC:
ERR_PRT( "\nOPERFUNC_TRY Error[%d].", e_ret );
return ( e_ret );
}
/****************************************************************************************************/
/* 主函数 */
/****************************************************************************************************/
static unsigned long OPERFUNC(unsigned long N1, unsigned long N2, OPERATOR arrOpe)
{
unsigned long rslt;
switch (arrOpe)
{
case PLUS:
rslt = N1 + N2;
break;
case MINUS:
rslt = N1 - N2;
break;
case MUL:
rslt = N1 * N2;
break;
case DIV:
rslt = N1 / N2;
break;
default:
rslt = 0;
break;
}
return (rslt);
}
/****************************************************************************************************/
/* 主函数 */
/****************************************************************************************************/
static eERROR Output( FORMULA_RSLT* p_rslt )
{
FILE* outputfile;
char *filename = "result.txt";
int cnt, cnt1 = 0;
fopen_s( &outputfile, filename, "a" );
if ( outputfile == NULL ) {
ERR_PRT( "\nCannot open File %s.\n", filename );
exit( 1 );
}
#if 1
fprintf( outputfile, "\n\nI am looking for the formula that the sum is = %d.", unRESPECT_VAL );
fprintf( outputfile, "\n\nThe number is %d.", p_rslt->ok_num );
for ( cnt = 0; cnt < p_rslt->ok_num; cnt++ )
{
if ( p_rslt->stExpressRslt[cnt].answer == unRESPECT_VAL )
{
fprintf( outputfile, "\n[%02d] %s = %.0lf",
cnt1 + 1, /* Log count is from 1 and not zero*/
p_rslt->stExpressRslt[cnt].ucFormExpress,
p_rslt->stExpressRslt[cnt].answer );
cnt1++;
}
}
#else
fprintf( outputfile, "\n\nThe sum = %d.\n", p_rslt->sum );
for ( cnt = 0; cnt < MAX_SAVE_LOG_NUM; cnt++ )
{
fprintf( outputfile, "\n[%02d] %s = %lf.",
cnt,
p_rslt->stExpressRslt[cnt].ucFormExpress,
p_rslt->stExpressRslt[cnt].answer );
}
#endif
fclose( outputfile ); // ファイルをクローズ(閉じる)
UI_PRT( "\nThe result had add to the file %s.\n", filename );
return (ERR_OK);
}
文件2
/*-------------------------------------------------------------------------------------
功能:实现表达式的计算,其中可包括+ - * / () 浮点数
输入示例:
3
1+2+3+4+5+10
2.2/3+100
(56-40)/(4+2)
输出示例:
res = 25.0
res = 100.7
res = 2.7
Author: Zhang Kaizhou
Date: 2019-3-5 16:58:59
From https://blog.csdn.net/weixin_38679924/article/details/88192241
------------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ExpressAnalyze.h"
typedef struct node { // 定义一个Node数据类型,用于存放后缀表达式以及最终结果
char post_str[ MAX_EXPRESS_LEN ]; /* 表达式 */
double res; /* 计算结果 */
struct node* pnext;
} Node;
typedef struct { // 定义一个字符栈数据类型
char oper[ MAX_EXPRESS_LEN ];
int top_oper;
} SqStack;
typedef struct { // 数据栈数据类型
double data[ MAX_EXPRESS_LEN ];
int top_data;
} DataStack;
void in_to_post(char* in_str, Node* p);
void compute_value(Node* p);
void push_oper(SqStack* p_oper, char ch);
void pop_oper(SqStack* p_oper, char* ch);
void get_top_oper(SqStack* p_oper, char* ch);
void push_data(DataStack* p_data, double num);
void pop_data(DataStack* p_data, double* num);
void get_top_data(DataStack* p_data, double* num);
void list_tail_insert(Node** pphead, Node** pptail, Node* p);
void list_print(Node* phead);
int TestMain( void )
{
Node* phead = NULL, * ptail = NULL;
int n;
#if 0
int i;
char in_str[ MAX_EXPRESS_LEN ];
scanf_s("%d", &n);
for (i = 0; i < n; i++) {
while (scanf_s("%s", in_str), getchar() != '\n'); // 每次从键盘读取一行字符串,以回车结束
Node* pnew = (Node*)calloc(1, sizeof(Node));
in_to_post(in_str, pnew);
compute_value(pnew);
list_tail_insert(&phead, &ptail, pnew);
}
#else
char* in_str = "1+2-3*4*5";
n = 1;
Node* pnew = (Node*)calloc(1, sizeof(Node));
in_to_post(in_str, pnew);
compute_value(pnew);
list_tail_insert(&phead, &ptail, pnew);
#endif
list_print(phead);
free(phead);
free(ptail);
return 0;
}
int calc_express_val(char* in_str, double *rslt)
{
Node stNode;
if ( ( in_str == NULL) || (in_str[0] == NULL) || ( rslt == NULL))
{
return( 1 );
}
in_to_post(in_str, &stNode);
compute_value( &stNode );
*rslt = stNode.res;
return( 0 );
}
void in_to_post(char* in_str, Node* p) { // 将中缀表达式转换成后缀表达式
SqStack* p_oper = (SqStack*)calloc(1, sizeof(SqStack)); // 定义一个栈指针,并初始化
p_oper->top_oper = -1;
int i = 0;
char temp;
while (*in_str != '\0') {
switch (*in_str) {
case '(':
push_oper(p_oper, '('); in_str++; break;
case ')':
pop_oper(p_oper, &temp);
while (temp != '(') {
p->post_str[i++] = temp;
pop_oper(p_oper, &temp);
}
in_str++; break;
case '+':
case '-':
while (p_oper->top_oper >= 0) {
get_top_oper(p_oper, &temp);
if (temp != '(') {
p->post_str[i++] = temp;
pop_oper(p_oper, &temp);
}
else {
break;
}
}
push_oper(p_oper, *in_str);
in_str++; break;
case '*':
case '/':
while (p_oper->top_oper >= 0) {
get_top_oper(p_oper, &temp);
if (temp == '*' || temp == '/') {
p->post_str[i++] = temp;
pop_oper(p_oper, &temp);
}
else {
break;
}
}
push_oper(p_oper, *in_str);
in_str++; break;
default:
while ((*in_str >= '0' && *in_str <= '9') || *in_str == '.') {
p->post_str[i++] = *in_str;
in_str++;
}
p->post_str[i++] = '#'; // 用#表示一个数字串结束
}
}
while (p_oper->top_oper >= 0) {
pop_oper(p_oper, &temp);
p->post_str[i++] = temp;
}
p->post_str[i] = '\0';
free(p_oper); // 释放符号栈
}
void compute_value(Node* p) {
DataStack* p_data = (DataStack*)calloc(1, sizeof(DataStack)); // 定义一个操作数栈,并初始化
p_data->top_data = -1;
double temp1, temp2, num, res;
int i = 0;
char temp3[ MAX_EXPRESS_LEN ];
char* pcur = p->post_str;
while (*pcur != '\0') {
switch (*pcur) {
case '+':
pop_data(p_data, &temp1);
pop_data(p_data, &temp2);
res = temp2 + temp1;
push_data(p_data, res);
break;
case '-':
pop_data(p_data, &temp1);
pop_data(p_data, &temp2);
res = temp2 - temp1;
push_data(p_data, res);
break;
case '*':
pop_data(p_data, &temp1);
pop_data(p_data, &temp2);
res = temp2 * temp1;
push_data(p_data, res);
break;
case '/':
pop_data(p_data, &temp1);
pop_data(p_data, &temp2);
if (temp1 != 0) {
res = temp2 / temp1;
push_data(p_data, res);
break;
}
else {
printf("\n除零错误!\n");
exit(0);
}
break;
default:
num = 0;
while ((*pcur >= '0' && *pcur <= '9') || *pcur == '.') {
temp3[i++] = *pcur;
pcur++;
}
temp3[i] = '\0';
num = atof(temp3); // 将数字串转换成浮点数
i = 0;
push_data(p_data, num);
break;
}
pcur++;
}
get_top_data(p_data, &(p->res));
return;
}
void push_oper(SqStack* p_oper, char ch) {
if (p_oper->top_oper == MAX_EXPRESS_LEN - 1) {
printf("The operator stack is full!\n");
}
else {
p_oper->top_oper++;
p_oper->oper[p_oper->top_oper] = ch;
}
return;
}
void pop_oper(SqStack* p_oper, char* ch) {
if (p_oper->top_oper < 0) {
printf("The operator stack is empty!\n");
}
else {
*ch = p_oper->oper[p_oper->top_oper];
p_oper->top_oper--;
}
return;
}
void get_top_oper(SqStack* p_oper, char* ch) { // 取栈顶元素,但不移动栈顶指针
if (p_oper->top_oper < 0) {
printf("The operator stack is empty!\n");
}
else {
*ch = p_oper->oper[p_oper->top_oper];
}
return;
}
void push_data(DataStack* p_data, double num) {
if (p_data->top_data == MAX_EXPRESS_LEN - 1) {
printf("The data stack is full!\n");
}
else {
p_data->top_data++;
p_data->data[p_data->top_data] = num;
}
return;
}
void pop_data(DataStack* p_data, double* num) {
if (p_data->top_data < 0) {
printf("The data stack is empty!\n");
}
else {
*num = p_data->data[p_data->top_data];
p_data->top_data--;
}
return;
}
void get_top_data(DataStack* p_data, double* num) {
if (p_data->top_data < 0) {
printf("The data stack is empty!\n");
}
else {
*num = p_data->data[p_data->top_data];
}
return;
}
void list_tail_insert(Node** pphead, Node** pptail, Node* p) {
if (*pphead == NULL) {
*pphead = p;
*pptail = p;
}
else {
(*pptail)->pnext = p;
*pptail = p;
}
return;
}
void list_print(Node* phead)
{
while (phead != NULL)
{
printf("\nres = %.1lf", phead->res);
phead = phead->pnext;
}
return;
}
文件2的头文件
#ifndef __EXPRESSANALYZE__
#define __EXPRESSANALYZE__
#define MAX_EXPRESS_LEN ( 60 )
int TestMain(void);
int calc_express_val(char* in_str, double* rslt);
#endif