Re: [问题] swith_case 用法

楼主: totemist (totem)   2015-06-15 16:13:38
※ 引述《tropical72 (蓝影)》之铭言:
: ※ 引述《totemist (totem)》之铭言:
: <恕删>
: : input是相同的512笔data
: : 经由case去选择不同的处理方式
: <恕删>
: : 补充说明(Supplement):
: : 因为我是要做滤波器(fir filter - bandpass)
: : 我希望能给使用者自己选择频率(0~540hz,每60hz为一单位)
: : 所以我总共要做C10取2 有 45个case要做
: <恕删>
: : ex:
: : printf("enter A=100_500 or D=200_600 = ");
: : 就是直接给使用者看着指令选择
: : 但是我想做到的是给使用者自动输入想要的频宽
: : 只是觉得这样对使用者比较方便,不用把我45个代号看完就可以自动输入这样
: 对于叙述其实有点看不懂,因里面算出来的数字我真没办法对上 Orz
: 0~540 , 每 60 hz 为一个单位 , 这样只会切成 10 分,
: 为什么后面多出了 C(10,2) = 45 个 conditions ?
: A=100_500 代表若输入的是 'A', filter 范围是 (100,500)
: D=200_600 代表若输入的是 'D', filter 范围是 (200,600)
: 以下的叙述猜测就是 Feis 所提的方法。
: 根据最后一段叙述,我假设你需要的是 要做45次判断,依序执行相对应之函式,
: 那你倒是可以这么做
: const int iBoundCount = 45;
: const int iLowerBand[iBoundCount] = { 100,200,150,180,200, .... } ;
: const int iUpperBand[iBoundCount] = { 500.700.600.400.600. .... } ;
: iLowerBand 和 iUpperBand 可以用 struct stBand { int m_iLower , m_iUpper};
: 这里不赘述。另上面这些常数可以写到档案里面去,程式初始化时从档案读出,
: 这里也不赘述。值得注意的是,如果你的 Bound 范围是有规律的,事实上,上面的表
: 可以不用建立,只是为了说明方便,我还是以建表方式说明。
: 再来是使用者输入的时候,你可以让使用者自己去输入
: lower bound 及 upper bound ,再去搜寻对应到的是哪一个 index
: int iUserLower , iUserUpper ; // 假设已拿到数值
: int iSelIndex ; // 判断输入数值落在阵列里的哪个区间。
: for(iSelIndex = 0 ; iSelIndex < iBoundCount ; ++iSelIndex)
: if( iLowerBound[iSelIndex] == iUserLower &&
: iUpperBound[iSelIndex] == iUserUpper )
: break;
: if(iSelIndex == iBoundCount) { // 这里是使用者输入的值没在两个 array 找到 }
: else { // 这里是使用者输入的值刚好在 Lower[iSelIndex]/Upper[iSelIndex] }
: 换句话说,到这里得到的 iSelIndex 会是 [ 0, iBoundCount ] 之连续整数。
: 如果硬要用 switch 写的话还是可以,就变成了
: switch(iSelIndex)
: {
: case 0 : func0() ; break;
: case 1 : func1() ; break;
: case 2 : func2() ; break;
: ...
: case 44 : func44() ; break;
: default : InputError(); break; // 这里是 iSelIndex == 45
: }
: 这样看起来好像没什么改变对不对? 不对唷!关键是 iSelIndex 已经调整成 0~45,
: 它又可以拿来当阵列的索引值了,这时候就需要 函式指标阵列 了。
: 假设你的 function 每个都长得一样,都是长成 void func(void) ; (长其他样子也行,
: 重点是要长得一样),上面的 switch 可被拿掉变成
: typedef void (*pFilterFunc)(void) ;
: pFilterFunc pFuncAry[iBoundCount] = {
: func1 , func2 , func3 , func4 , func5 , ... , func45
: };
: if(iSelIndex != iBoundCount) // 别忘了刚刚的 iSelIndex 怎来的
: {
: // User Input Error Process
: }
: else
: {
: pFuncAry[iSelIndex] () ; // 使用函式指标阵列进行呼叫函式
: }
: 好了,你要的东西上面应该已经提供一套 solution 给你了,但其他更好的架构
: 方式,像是
: struct {
: int iLowerBound ;
: int iUpperBound ;
: void (*pFilter)() ;
: }FilterInfo[] = {
: {100,200, func1},
: {200,500, func2},
: ...
: {150,700, func45}
: };
: 资料结构和详细作法我也不再赘述了,也只是上述的东西再包过而已。然后这是用
: 纯 C 的刻法,另一种解法是 C++ template ,这个我也不赘述。
: 重点是…嗯…你可以先确认一下,知不知道什么是函式指标,什么是函式指标阵列。
: 不知道的话必须先补起来,才能讨论比较简洁、"好一点点" 的架构。
: 但.是 (如果没有但是的话下面可以不用看了...)
: 但.是. 如果好死不死,那些 func1 , func2 的 prototype 长得不一样的话呢?
: 像是 void func1(int, int) , double func2(double, int) , ... etc ,
: 这里其实我觉得还是直接用 45 个 switch-case 下去硬干会比较方便,
: 走 C 风格的话还是可以用 函式指标阵列,只是所有函式必须改写成
: void func(void *) 或是 int func( void *) ,至于 C++ 有没有比较好的解法?
: 嗯,我想是有的,只是我也没用过,也想知道。
这几天又重回这个问题啦!!!!
经过学长的提点,这次的想法跟Tropical大有点像
首先我先把我原本45个1维array,变成一个2维的array: myfilter[45][406]
然后我目前想法是
设一个 int filter_id
然后利用Fpass和Fstop 找对应filter_id 一对一 函数的关系
Fpass Fstop filter_id
0 60 0
0 120 1
.
.
.
.
0 540 8
60 120 9
60 180 10
.
.
.
60 540 16
120 180 17
120 240 18
.
.
.
120 540 23
.
.
.
.
一直到最后
480 540 44
共有45个filter_id (0~44)
这样的好处是
只要能找到filter_id,就能简化把filer变成 myfilter[filter_id][406];
在function就不用像我之前那样硬是要用45个case
一个就可以搞定了
只是我目前找的规律性还没有很好,有点硬凑OAQ
也是分了很多if else来找filter_id
if (Fpass == 0)
filter_id = (Fstop/60)-1;
else if (Fpass == 60)
filter_id = (Fpass/10)+(Fstop/60)+(Fstop/60)-1;
else if (Fpass == 120)
filter_id = (Fpass/10)+(Fstop/60)+(Fstop/60)-1;
else if (Fpass ==180)
filter_id = (Fpass/10)+(Fstop/60)+2;
.
.
方法不同
.
.
else (Fpass == 480)
filter_id = 44;
有没有人能有更简洁的关系式来找filter_id呢?
谢谢
作者: Feis (永远睡不着 @@)   2015-06-15 16:32:00
https://gist.github.com/feis/1ff45ffdd71c0d3a0849应该只是基础的离散数学
作者: anyoiuo   2015-06-15 16:53:00
9+8+7+6+5+4+3+2+1这是等差级数和n[(2*a1+(n-1)*d)]/2F大借抄一部分,感恩! https://ideone.com/Mzs6f3这不是程式这是数学来着...XDa1=9带入就会发现是F大的答案了
作者: tropical72 (蓝影)   2015-06-15 20:20:00
所以我之前发的不算是废文了吗…满满的感动
作者: anyoiuo   2015-06-16 14:34:00
加油吧! 问题 => 找规律 => 思考 => Divide & Conquer你的方向是对的,想出自己解法,再看看人家解法,就会进步!

Links booklink

Contact Us: admin [ a t ] ucptt.com