球一个高效算法

dos5gw 2010-01-25 10:59:42
已知long xdata[5000]中每个元素值随机,每个元素的范围是在0~4096,
要统计xdata[5000]在1897<xdata[i]<2149范围内的元素出现次数

可以建一个数组int a[251]来存放次数
a[250] 对应值=2148出现的次数
a[249] 对应值=2147出现的次数
...
a[0] 对应值=1898出现的次数

我写的如下, 看似很低效
//---------------------
int indexTemp=0;
for(int t=0;t<4096;t++)
{
if((xdata[t]>1897) && (xdata[t]<2149))
{
indexTemp=2148-(xdata[t]);
a[indexTemp]++;
//2048-150 ~ 2048+100
}
}
...全文
240 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
tony_chenypc 2010-01-25
  • 打赏
  • 举报
回复
map<unsigned int,unsigned int> mapTimes;
int f_between_1897_2149(int *iArray)
{
for(unsigned int i= 0;i < 5000;i++)
{
if(1897 <= iArray[i] && 2149 >= iArray[i])
{
mapTimes[iArray[i]].second++;
}
}
}
lin0119 2010-01-25
  • 打赏
  • 举报
回复
[Quote=引用楼主 dos5gw 的回复:]
//---------------------
    int indexTemp=0;
    for(int t=0;t <4096;t++)
    {
        if((xdata[t]>1897) && (xdata[t] <2149))
        {
            indexTemp=2148-(xdata[t]);
            a[indexTemp]++;
            //2048-150 ~ 2048+100
        }
    }

[/Quote]
这个应该是105吧,笔误啊
这个算法清晰,再要求高效没必要了。个人感觉在32位机上什么改也高不了多少,反而会为维护带来隐患。实在要改就上汇编。
mstlq 2010-01-25
  • 打赏
  • 举报
回复
这个已经够快了……
还想快,就整循环展开吧……
cattycat 2010-01-25
  • 打赏
  • 举报
回复
这个效率就是线性的了,对数组变量不可避免了,另外,外层循环应该是5000。至于t++还是++t在这里几乎影响不大。
除非用hash,只需要计算1897到2149之间的就行。
healer_kx 2010-01-25
  • 打赏
  • 举报
回复
如果把
for (int i = 0; i < 5000; ++i) {
if (i)
}
改为

for (int i = 0; i < 2500; ++i) {
if (func(i)) {}

if (func(i + 1)) {}
}
你改成这样的,那么你真的优化掉2500次比较和++i,比i++ => ++i的效果好多了。
那改成
i < 1250呢?循环里面写4个if,。。。你逐渐的展开循环。。。你效率高了。
但是代码可读性差了,可维护性差了。。。
没意思了吧~

tan870426 2010-01-25
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 stardust20 的回复:]
http://www.diybl.com/course/3_program/c++/cppjs/20091009/178314.html
楼主 可看下这个。。讲t++和++t的效率差在哪
[/Quote]这个编译器会优化的吧...
感觉LZ这样写效率已经挺高的了,反正我是没看出有什么需要优化的地方
healer_kx 2010-01-25
  • 打赏
  • 举报
回复
i++,和++i的效率问题,在VC6那样的编译器上,就会被优化了。如果你很在乎这种地方的效率,那你干脆展开循环算了。。。 。。。
stardust20 2010-01-25
  • 打赏
  • 举报
回复
http://www.diybl.com/course/3_program/c++/cppjs/20091009/178314.html
楼主 可看下这个。。讲t++和++t的效率差在哪
stardust20 2010-01-25
  • 打赏
  • 举报
回复
t++和++t的效率差在哪呢?
你可以想下他们的实现方法
t++要多用一个临时变量,来存加之前的值
dos5gw 2010-01-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wangchentangjuan 的回复:]
//int indexTemp=0;
    for(int t=0;t <4096;++t)
    {
        if((xdata[t]>1897) && (xdata[t] <2149))
        {
            //indexTemp=2148-(xdata[t]);
            ++a[2148-(xdata[t])];
            //2048-150 ~ 2048+100
        }
    }
少了很多次临时拷贝哦
[/Quote]
嗯,indexTemp可以去掉,不过++a[]和a[]++, t++和++t的效率差在哪呢?
尤其是++t, 既然++t效率高的话,为什么我之前看过的所有for都是t++呢? 请教
dos5gw 2010-01-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 healer_kx 的回复:]
效率不低,我只是觉得你逻辑写错了。。。 。。。

    for(int t=0;t <4096;t++)

红字部分,应该是5000吧?
[/Quote]
笔误, 是5000
wangchentangjuan 2010-01-25
  • 打赏
  • 举报
回复
//int indexTemp=0;
for(int t=0;t <4096;++t)
{
if((xdata[t]>1897) && (xdata[t] <2149))
{
//indexTemp=2148-(xdata[t]);
++a[2148-(xdata[t])];
//2048-150 ~ 2048+100
}
}
少了很多次临时拷贝哦
wangchentangjuan 2010-01-25
  • 打赏
  • 举报
回复
把 t++和a[]++换成++t ++a[] 效率会再高点
hh_xj 2010-01-25
  • 打赏
  • 举报
回复
线性是必须的吧,对每个元素判断。一定要改进,就用hash存数据,这样可以在那251个桶里累加统计就可以了。
healer_kx 2010-01-25
  • 打赏
  • 举报
回复
效率不低,我只是觉得你逻辑写错了。。。 。。。

for(int t=0;t <4096;t++)
{
if((xdata[t]>1897) && (xdata[t] <2149))
{
indexTemp=2148-(xdata[t]);
a[indexTemp]++;
//2048-150 ~ 2048+100
}
}

红字部分,应该是5000吧?
dos5gw 2010-01-25
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 wwwzyb2002 的回复:]
看楼主的结贴率
估计楼主不知道结贴为何物。
[/Quote]

-_-!
IT_lau 2010-01-25
  • 打赏
  • 举报
回复
暴强的逻辑
ruoxing 2010-01-25
  • 打赏
  • 举报
回复
#17楼 得分:0回复于:2010-01-25 16:19:10C/C++ code//已知long xdata[5000]中每个元素值随机,每个元素的范围是在0~4096,
//要统计xdata[5000]在1897 <xdata[i] <2149范围内的元素出现次数
//可以建一个数组int a[4097]来存放次数
//a[n] 对应值=n出现的次数
//---------------------
static int a[4097];
static int n;

for (int i=0;i<5000;i++)
{
a[xdata[i]]++;
}
for (i=1898;i<2149;i++)
{
n+=a[i];
}
printf("%d\n",n);

学习了,但要a【4097】空间。不过还是好强哎

wwwzyb2002 2010-01-25
  • 打赏
  • 举报
回复
看楼主的结贴率
估计楼主不知道结贴为何物。
耍宝王 2010-01-25
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 zhao4zhong1 的回复:]
C/C++ code//已知long xdata[5000]中每个元素值随机,每个元素的范围是在0~4096,//要统计xdata[5000]在1897 <xdata[i] <2149范围内的元素出现次数//可以建一个数组int a[4097]来存放次数//a[n] 对应值=n出现的次数//---------------------staticint a[4097];staticint n;for (int i=0;i<5000;i++)
{
a[xdata[i]]++;
}for (i=1898;i<2149;i++)
{
n+=a[i];
}
printf("%d\n",n);
[/Quote]
很有意思的思路,学习了

[Quote=引用 20 楼 zhao4zhong1 的回复:]
简单即是美!
[/Quote]
简洁即是美——出自C++ Primer 中文版(第四版) P141 嘻嘻
加载更多回复(5)

64,653

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧