用链表解决if语句过多的问题(C/C++实现)
起因
http://www.cnblogs.com/code-style/p/3499408.html
设计模式的解决方案(基于python语言)
http://www.cnblogs.com/code-style/p/3501713.html
http://www.cnblogs.com/code-style/p/3502105.html
用设计模式实现完以后我突然发现,所谓的设计模式其实在C语言里不就是链表吗?当前节点能处理就处理不能处理让下一个节点处理,不多说,上代码
消息类的设计
message.h
#ifndef MESSAGE_H
#define MESSAGE_H #define TRUE 1
#define FALSE 0 typedef struct {
int sender;
int isSend;
int isCharge;
char date[];
}Message; Message * makeMessage(const int sender, const char *date);
void setSendFlag(Message * const message);
void setChargeFlag(Message * const message);
int isSameDate(const Message * const message, const char * const date);
char * format(const Message * const message);
const char * boolStr(const int value); #endif
message.c
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "message.h" Message * makeMessage(const int sender, const char *date)
{
Message *message = (Message*)malloc(sizeof(Message));
assert(message != NULL);
message->sender = sender;
message->isSend = FALSE;
message->isCharge = FALSE;
strncpy(message->date, date, );
return message;
} const char * boolStr(const int value)
{
return value == TRUE ? "TRUE" : "FALSE";
} char * format(const Message * const message)
{
#define BUF_SIZE 1024
static char buffer[BUF_SIZE];
memset(&buffer, , BUF_SIZE);
snprintf((char*)&buffer, BUF_SIZE, "Message <%d isSend:%s isCharge:%s>\n", \
message->sender, boolStr(message->isSend), boolStr(message->isCharge));
return (char*)buffer;
} void setSendFlag(Message * const message)
{
message->isSend = TRUE;
} void setChargeFlag(Message * const message)
{
message->isCharge = TRUE;
} int isSameDate(const Message * const message, const char * const date)
{
if (strncmp(message->date, date, ) == )
{
return TRUE;
}
else
{
return FALSE;
}
}
testMessage.c
#include <stdio.h>
#include "message.h"
#include "gtest/gtest.h" TEST(MESSAGE,makeMessage){
Message *message = makeMessage(,"");
EXPECT_EQ(, message->sender);
EXPECT_STREQ("Message <1 isSend:FALSE isCharge:FALSE>\n", format(message));
}
链表类的实现
node.h
#ifndef NOTE_H
#define NOTE_H typedef struct Node{
void *ptr;
struct Node *next;
}Node; Node *makeListWithArray(void *array[], int length);
void foreach(Node *list, void (*process) (Node *));
#endif
node.c
#include <stdlib.h>
#include <assert.h>
#include "node.h" Node *makeListWithArray(void *array[], int length)
{
int i;
Node *last = NULL; assert(array != NULL && length > );
for(i = length - ; i >= ; i--)
{
Node *node = (Node*)malloc(sizeof(Node));
node->ptr = array[i];
node->next = last;
last = node;
} return last;
} void foreach(Node *list, void (*process) (Node *))
{
Node *current = NULL; assert(list != NULL && process != NULL);
for(current = list; current != NULL; current = current->next)
{
process(current);
}
}
testNode.c
#include <stdio.h>
#include "node.h"
#include "gtest/gtest.h" void printNode(Node *node)
{
static int i = ;
int data[] = {,,};
EXPECT_EQ(data[i], *(int*)node->ptr);
i++;
} TEST(NODE,makeListWithArray){
int i;
int data[] = {,,};
void *aSet[] = {&data[], &data[], &data[]};
Node *list = makeListWithArray(aSet, );
foreach(list, printNode);
}
程序入口实现(main.c)
#include <stdio.h>
#include <string.h>
#include "message.h"
#include "node.h" # define FALSE
# define TRUE typedef int BOOL;
typedef BOOL (*FuncIsAllowSend)(Message *, Node*); BOOL isAllowSendCheckDate(Message *message, Node *node)
{
FuncIsAllowSend isAllowSend = NULL; if(strcmp(message->date, "") == )
{
return FALSE;
} isAllowSend = (FuncIsAllowSend) node->next->ptr;
return isAllowSend(message, node->next);
} BOOL isAllowSendCheckWhiteList(Message *message, Node *node)
{
FuncIsAllowSend isAllowSend = NULL; if(message->sender == )
{
return TRUE;
} isAllowSend = (FuncIsAllowSend) node->next->ptr;
return isAllowSend(message, node->next);
} BOOL isAllowSendWithDefault(Message *message, Node *node)
{
setChargeFlag(message);
return TRUE;
} int main()
{
Message *message = makeMessage(,"");
void *actionList[] = {(void*)&isAllowSendCheckDate,
(void*)&isAllowSendCheckWhiteList,
(void*)&isAllowSendWithDefault};
Node *theList = makeListWithArray(actionList, sizeof(actionList)/);
FuncIsAllowSend isAllowSend = (FuncIsAllowSend)theList->ptr;
if(isAllowSend(message, theList) == TRUE)
{
setSendFlag(message);
}
printf("%s\n",format(message));
}
代码风格其实是C风格,但是因为要使用gtest不得不使用了g++对程序进行编译调试,命令如下:
# 前提:我已经把gtest编译成库放在了系统目录下 g++ -c message.c
g++ -c testMessage.c
g++ message.o testMessage.o -lgtest -lpthread
./a.out g++ -c node.c
g++ -c testNode.c
g++ node.o testNode.o -lgtest -lpthread
./a.out g++ -c main.c
g++ message.o node.o main.o
./a.out
用链表解决if语句过多的问题(C/C++实现)的更多相关文章
- php实现单,双向链表,环形链表解决约瑟夫问题
传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季 http://php.itcast.cn 聊天篇: 数学对我们编程来说,重不重要? 看你站在什么样的层次来说. 如果你应用程序开发,对数学要求 ...
- PHP算法学习(8) 环形链表 解决约瑟夫问题
2019年2月25日17:29:17 Josephus有过的故事:39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓.于是决定了自杀方式,41个人排成一个圆圈 ...
- mysql 线程等待时间,解决sleep进程过多的办法
如果你没有修改过MySQL的配置,缺省情况下,wait_timeout的初始值是28800. wait_timeout 过大有弊端,其体现就是MySQL里大量的SLEEP进程无法及时释放,拖累系统 ...
- TCP之再谈解决服务器TIMEWAIT过多的问题
原则 TIMEWAIT并不是多余的.在TCP协议被创造,经历了大量的实际场景实践之后,TIMEWAIT出现了,因为TCP主动关闭连接的一方需要TIMEWAIT状态,它是我们的朋友.这是<UNIX ...
- VS2017一步一步断点调试解决Dapper语句出现的Bug
最近再做一个项目,出现一个小bug,bug虽小,但是却要命啊.下面我show下我解决问题的方法. View层代码: @model List<mhq.Blog.Model.Blog> < ...
- 解决insert语句插入时,需要写列值的问题
今天发现解决这个问题其实很简单,闲话不多谈,我直接附上语句 ) select @s = isnull(@s+',', '') + [name] from syscolumns where id = o ...
- 使用java的循环单向链表解决约瑟夫问题
什么是约瑟夫问题 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定 ...
- 单向环形链表解决约瑟夫环(Josephus)问题
一.约瑟夫环问题 Josephu 问题为:设编号为1,2,- n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那 ...
- PHP+Redis链表解决高并发下商品超卖问题
目录 实现原理 实现步骤 上一篇文章聊了一下使用Redis事务来解决高并发商品超卖问题,今天我们来聊一下使用Redis链表来解决高并发商品超卖问题. 实现原理 使用redis链表来做,因为pop操作是 ...
随机推荐
- jQuery支持mobile的全屏水平横向翻页效果
这是一款支持移动手机mobile设备的jQuery全屏水平横向翻页效果插件. 该翻页插件能够使页面在水平方向上左右全屏翻动,它支持手机触摸屏,支持使用鼠标滚动页面. 整个页面过渡平滑,效果很不错. 在 ...
- Qt 发送 https 请求
1.环境 ubuntu 12.04 Qt库版本 4.8.1(安装包是Nokia时期的sdk,现在已经不好找了) 2.网上一查都说 Qt 默认不支持Openssl,心想那https也肯定用不了啊,然后屁 ...
- UVA 10465 Homer Simpson(dp + 完全背包)
Problem C: Homer Simpson Time Limit: 3 seconds Memory Limit: 32 MB Homer Simpson, a very smart guy, ...
- Spark1.0.0 监测方法
Spark1.0.0能够通过下面几种方式来对Spark应用程序进行监控: Spark应用程序的WebUI或者Spark Standalone的集群监控 指标,然后通过支持指标收集的集群监控 ...
- lucene 抛出的异常(分享)
1) too many boolean clauses异常 例如: String keyword=".......";//(keyword的长度太长) Query indexQue ...
- DOM - nodeType 的取值
DOM 中,共有 12 中不同类型的节点,nodeType 的取值以数值表示. 节点类型 描述 子节点 1 Element 表示元素. Element, Text, Comment, Proce ...
- Shell - 文件运算符
文件运算符 文件运算符 描述 -b file 检测 file 是否为块设备文件 -c file 检测 file 是否为字符设备文件 -d file 检测 file 是否为目录 -e fil ...
- (转)PHP下编码转换函数mb_convert_encoding与iconv的使用说明
之--http://www.jb51.net/article/21451.htm mb_convert_encoding这个函数是用来转换编码的.原来一直对程序编码这一概念不理解,不过现在好像有点开窍 ...
- 开通博客第一天 (先发一些android(java)常见异常信息
常见异常: java.lang.AbstractMethodError抽象方法错误.当应用试图调用抽象方法时抛出. java.lang.AssertionError断言错.用来指示一个断言失败的情况. ...
- HashMap深度解析(二)
本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/16890151 上一篇比较深入的分析了HashMap在put元素时的整体过 ...