声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2497|回复: 20

[编程技巧] 请教个避免用循环的编程技巧

[复制链接]
发表于 2007-12-13 09:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
程序:
a=[10 30 50];
b=[30 50 70];
c=[1 2 3];
aa=10:10:70;
for i=1:length(aa)-1
    j=find(a<=aa(i) & b>aa(i));
    cc(i)=c(j);%由于实际应用中的特殊设置,此处的j只可能为一个数
end
cc(end+1)=c(end);

怎么不用循环实现这个过程,谢谢!

[ 本帖最后由 花如月 于 2007-12-13 22:35 编辑 ]
回复
分享到:

使用道具 举报

发表于 2007-12-13 10:20 | 显示全部楼层
maybe

  1. cc=   c(1)*(aa>=a(1)&aa<=b(1))...
  2.     + c(2)*(aa>=a(2)&aa<=b(2))...
  3.     + c(3)*(aa>=a(3)&aa<=b(3));
复制代码

评分

1

查看全部评分

发表于 2007-12-13 10:27 | 显示全部楼层
原帖由 hyl2323 于 2007-12-13 09:39 发表
a=[10 30 80];
b=[20 50 100];
c=[1 2 3];
aa=a(1):10:b(end);
cc=如果aa(i)处于a(i)与b(i)之间,则cc(i)取c(i)的值。
怎么不用循环实现这个过程,谢谢!


aa有10个数据,a,b有3个,那aa后面那7个该怎么比啊??
发表于 2007-12-13 10:45 | 显示全部楼层
经过测试应该没有问题:“如果aa(i)处于a(i)与b(i)之间,则cc(i)取c(i)的值”边界没有取等于的情况,因此cc的第一个数总是为空,如果需要自己加上
  1. clear,clc
  2. a=[1 5 8];
  3. b=[20 50 100];
  4. c=[5 8 6];
  5. aa=a(1):10:b(end);
  6. index=1:length(c);
  7. cc=c((a(index)<aa(index))&(aa(index)<b(index)));
复制代码
没刷新已经有人回复了,我和2楼的思路一致。不过判断的时候可以完全矢量化,一个句子就够了。多余的7个就自动截断了,因为结果由c的长度决定。看这个例子:

>> a=[0 1 1];c=1:3;
>> c(a)
??? Subscript indices must either be real positive integers or logicals.
>> c(logical(a))
ans =
     2     3

以前一直注意过那个错误提示。这个例子说明逻辑0可以做下标,得到的是空数相当于删除操作

[ 本帖最后由 eight 于 2007-12-13 11:02 编辑 ]

评分

1

查看全部评分

 楼主| 发表于 2007-12-13 13:30 | 显示全部楼层

回复 #2 sugarcane 的帖子

a,b,c我只简单列了三个数,其实都是长度为n的行向量。所以你说的
cc=   c(1)*(aa>=a(1)&aa<=b(1))...
    + c(2)*(aa>=a(2)&aa<=b(2))...
    + c(3)*(aa>=a(3)&aa<=b(3));
其中的1 2 3,还是得用循环阿?
 楼主| 发表于 2007-12-13 13:33 | 显示全部楼层
结果是由aa的长度决定,对不起,我的意思没有表达清楚,问题重新修改编辑过了。

[ 本帖最后由 hyl2323 于 2007-12-13 13:38 编辑 ]
 楼主| 发表于 2007-12-13 13:34 | 显示全部楼层
问题还没有解决,楼上所说的我看明白了,谢谢。问题关键是aa与a b c不同长度。
发表于 2007-12-13 13:52 | 显示全部楼层

回复 #7 hyl2323 的帖子

又多了个j,问题似乎描述的有些问题,看不太懂。

[ 本帖最后由 花如月 于 2007-12-13 13:53 编辑 ]
 楼主| 发表于 2007-12-13 14:06 | 显示全部楼层
现在应该看得懂了,我琢磨了好久更正了描述了,我把实际应用说说吧,我是用来处理声音的3rd倍频程的,我想把每个3rd倍频程再细分,例如250Hz中心频率的倍频程范围为220-280Hz,声压级为L,我要将这个频带细分为220:10:280,那么各细分频带的声压级均为L-10lg((280-220)/10)。有30几个3rd倍频程。现在应该表述清楚了吧。可能不了解这个专业的难以明白物理意思。那就看主题帖吧。

[ 本帖最后由 hyl2323 于 2007-12-13 14:07 编辑 ]
 楼主| 发表于 2007-12-13 15:19 | 显示全部楼层
我用带for循环可以实现如下:帮助理解。
for i=1:length(aa)-1
    j=find(a<=aa(i) & b>aa(i));
    cc(i)=c(j);%由于实际应用中的特殊设置,此处的j只可能为一个数
end
cc(end+1)=c(end);
如何用向量计算代替这个for?值得思考!---最后编辑已经改对了!

[ 本帖最后由 hyl2323 于 2007-12-13 17:56 编辑 ]
 楼主| 发表于 2007-12-13 15:24 | 显示全部楼层
当然,我此处的for只要循环大概2000次,不会很耗资源的,只是学究一下,毕竟matlab最好少用循环,如何化循环为矩阵计算,确为不俗之技巧。高手们快支招,我也在冥思苦想。
发表于 2007-12-13 15:38 | 显示全部楼层

回复 #10 hyl2323 的帖子

这个程序根本无法运行,赋值的矩阵维数都不一样
???  In an assignment  A(I) = B, the number of elements in B and
I must be the same. j是个向量,不可能放到cc(i)里

因此的表述还是有问题,你的a,b是用来确定区间起始,c应该是代表的分的区间段数。

cc的结果是aa里每个元素所在的区间索引吧?这样理解对不?

[ 本帖最后由 花如月 于 2007-12-13 15:47 编辑 ]

评分

1

查看全部评分

 楼主| 发表于 2007-12-13 15:52 | 显示全部楼层
我身边没有matlab,没有调试过,可能是处理最后一个aa(end)返回的j为空矩阵[]的原因?我下班后再来弄。

[ 本帖最后由 hyl2323 于 2007-12-13 16:00 编辑 ]
 楼主| 发表于 2007-12-13 16:04 | 显示全部楼层

回复 #12 花如月 的帖子

a,b是区间,c是这个区间的一个函数总值,不是段数,cc相当于是一个插值后的c。只是插值是按照那个不等式来操作的。
发表于 2007-12-13 17:00 | 显示全部楼层

回复 #14 hyl2323 的帖子

最好先给个常规的解法
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-11-18 12:41 , Processed in 0.072394 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表