用链表解决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操作是 ...
随机推荐
- javascript之文档碎片,文档碎片在理论上可以提高DOM操作的执行效率
刚来到这里,趁着还没有忘记,来记录一下,昨晚学习的一个知识点——JavaScript中的文档碎片. 一.对文档碎片的基本认识 文档碎片可以提高DOM操作性能(理论上,注意!!理论上的) 文档碎片原理 ...
- POJ1330Nearest Common Ancestors——近期公共祖先(离线Tarjan)
http://poj.org/problem? id=1330 给一个有根树,一个查询节点(u,v)的近期公共祖先 836K 16MS #include<iostream> #includ ...
- 关于Win8对getElementsByTagName等dom方法兼容性的替代方法
在对Twebbrowser进行dom编程时,引用MSHTML并使用其中的HTMLDocument; IHTMLElementCollection;IHTMLElement;能获得较好的代码提示 其中封 ...
- jQuery支持mobile的全屏水平横向翻页效果
这是一款支持移动手机mobile设备的jQuery全屏水平横向翻页效果插件. 该翻页插件能够使页面在水平方向上左右全屏翻动,它支持手机触摸屏,支持使用鼠标滚动页面. 整个页面过渡平滑,效果很不错. 在 ...
- android 10 事件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layo ...
- Java基础知识强化之集合框架笔记46:Set集合之TreeSet存储自定义对象并遍历练习2(自然排序:Comparable)
1. TreeSet存储自定义对象并遍历练习2: (1)Student.java package cn.itcast_06; /* * 如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口 * ...
- 10.30 morning
P75竞赛时间: ????年??月??日??:??-??:?? 注意事项(请务必仔细阅读) [ 问题描述] 从1 − N中找一些数乘起来使得答案是一个完全平方数,求这个完全平方数最大可能是多少.[输入 ...
- 分享一下自己在用的CSS样式重置代码
通过借鉴网上大牛们的经验和自己在工作中碰到的一些问题,总结出了这些比较常用的CSS样式重置的代码: @charset "utf-8"; /* 防止用户自定义背景颜色对网页的影响,添 ...
- JAVA除去制定字符的方法
只需调用replaceAll()方法: public class Test { public static void main(String[] args) { String s= "abc ...
- IOC之Unity
项目最近用到,查找到比较好的资料,记录哈: Unity 3(一):简介与示例: Unity 3(二):Unity在AOP方面的应用