免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: reiase
打印 上一主题 下一主题

现在觉得算法代码很难写 [复制链接]

论坛徽章:
0
31 [报告]
发表于 2012-04-18 01:58 |只看该作者
回复 30# walleeee


    怎么又变成自底向上了。算了,懒得说。

论坛徽章:
0
32 [报告]
发表于 2012-04-18 02:05 |只看该作者
本帖最后由 家住马戏团 于 2012-04-18 02:08 编辑

#define arithmeticB 1
#define arithmeticC 0

#define LINK(A,B) LINK_I(A,B)
#define LINK_I(A,B) A##B

#define IF(BIT,A,B) IF_I(LINK(IF_,BIT),A,B)
#define IF_I(FUNC,A,B) FUNC(A,B)

#define IF_1(A,B) A
#define IF_0(A,B) B

#define DELAY(A) A

#define func(val)     \
{                           \
    blockA;                \
    IF(val,DELAY(blockB;Call c),DELAY(blockD;Call e)); \
}

不吵架了,年纪大了,吵个架连觉都睡不着
试试这个版本,直接敲在留言板上的,没编译。
预处理分派。
用法:
如果没写错的话
func(arithmeticB)走blockA blockB call c
另外一个相反



论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
33 [报告]
发表于 2012-04-18 02:28 |只看该作者
回复 32# 家住马戏团

C++的元编程其实都很勉强,C宏更是连图灵完备都达不到。


实践中,与其这样用C宏,还不如:
1. 依赖编译器优化

  1. void f(int N)
  2. {
  3.       block A
  4.       if (N) {
  5.             block B
  6.             call C
  7.       } else {
  8.             block D
  9.             call E
  10.       }
  11. }

  12. void f0(void) { f(0); }
  13. void f1(void) { f(1); }
复制代码
然后使用f0, f1。


如果编译器无法将f0优化为block A, block B, call C:

2. 多源代码

  1. /* template.inl */
  2. void f(void)
  3. {
  4.       block A
  5.       if (N) {
  6.             block B
  7.             call C
  8.       } else {
  9.             block D
  10.             call E
  11.       }
  12. }
复制代码

  1. /* f0.c */
  2. #define N 0
  3. #define f f0
  4. #include "template.inl"
复制代码

  1. /* f1.c */
  2. #define N 1
  3. #define f f1
  4. #include "template.inl"
复制代码
3. 单源代码

如果觉得这样多文件麻烦,而且对构建系统有更多的了解,可以只使用template.inl, 只是将它编译两次:

  1. gcc -c -x c -DN=0 -Df=f0 template.inl -o f0
  2. gcc -c -x c -DN=1 -Df=f1 template.inl -o f1
  3. gcc f0.o f1.o ... -o a.out
复制代码
这样的f函数依然是很普通的C代码,始终是可读/可修改/可维护的。

论坛徽章:
0
34 [报告]
发表于 2012-04-18 09:43 |只看该作者
回复 28# starwing83

如果最开始,你不知道算法是否可行怎么办?如果求一个值,你不知道用A,用B,还是用C怎么办?一百行的函数,拆成四五个函数,为了避免传递参数,把数据都放进类里边吗?

主要是讨论下,在信息不足,信心不足的情况下,怎么写代码。举个例子吧:

  1. class SMB
  2. {
  3. public:
  4.   enum {REROLLING=1, SEMILEARNING=1<<1, INITED=1<<2};
  5.   int flags;
  6.   Mat w;
  7.   Mat init_w;
  8.   
  9.   void trainingClassifier(int RND);
  10.   void trainingClassifier_1(int RND);
  11.   double predict(Mat &sample);
  12. };

  13. void SMB::trainingClassifier(int RND)
  14. {
  15.     if (flags & REROLLING)
  16.         w = init_w.clone();
  17.     else
  18.         w = Mat::zeros(lng, 1, dtype);

  19.     !!! Statistics = ....;

  20.     if (!(flags & INITED)) {
  21.         !!! search for initial w;
  22.         init_w = w.clone();
  23.         flags |= INITED;
  24.     }

  25.     while (RND > 0) {
  26.         !!! choose a direction;
  27.         !!! choose a step;
  28.         w = w + direction * step;
  29.         RND--;
  30.     }
  31.    
  32.     !!! post processing;
  33. }

  34. void SMB::trainingClassifier_1(int RND)
  35. {
  36.     if (flags & REROLLING)
  37.         w = init_w.clone();
  38.     else
  39.         w = Mat::zeros(lng, 1, dtype);

  40.     !!! Statistics = ....;

  41.     if (!(flags & INITED)) {
  42.         !!! search for initial w;
  43.         init_w = w.clone();
  44.         flags |= INITED;
  45.     }

  46.     while (RND > 0) {
  47.         !!! choose a direction;
  48.         !!! choose a step;
  49.         w = w + direction * step;
  50.         RND--;
  51.     }
  52.    
  53.     !!! post processing;
  54. }
复制代码
其中 search for initial w、choose a direction、choose a step、post processing是几个代码块,可能一样,可能不一样。SMB::trainingClassifier和SMB::trainingClassifier_1都一百来行的样子。我要试验一种新的choose a direction,或者实验新的choose a step,或者两个一起实验。有可能只是舍掉一项,让计算速度变快,但是误差也变大一点。

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
35 [报告]
发表于 2012-04-18 12:23 |只看该作者
这是把复杂逻辑用代码表述清晰的一种能力,多写多改,发现不清晰推倒重来,反复多练就够了

论坛徽章:
0
36 [报告]
发表于 2012-04-18 13:02 |只看该作者
如果不是所有的方法(即抽象流程)都要求先执行blockA,blockA就应该单独放到方法B和方法C中,提取到分支之前就是过度设计。

否则,不提取到分支之前也没啥。先提取成函数,各自调用,等到有更多分支的时候再说。

论坛徽章:
0
37 [报告]
发表于 2012-04-18 15:11 |只看该作者
回复 35# koolcoy


我也有这个经历。后来慢慢有了经验,于是重写的概率就大大减小了。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
38 [报告]
发表于 2012-04-18 17:25 |只看该作者
回复 34# reiase


    看下面的35和37吧……

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
39 [报告]
发表于 2012-04-18 17:27 |只看该作者
回复 33# OwnWaterloo


    最近几个方法在C立面做方法模板的时候就这么弄过了。

论坛徽章:
0
40 [报告]
发表于 2012-04-18 18:46 |只看该作者
OwnWaterloo 发表于 2012-04-17 23:58
回复 14# 家住马戏团

>> 动态:你多个函数,我用的是装饰模式

昨天还没看清,你用的是什么c++编译器,居然支持函数模板偏特化?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP