请教大数据量的嵌套循环如何解决

basin_yi 2010-04-19 04:15:13
如果要做多层的嵌套循环~
而且每层的循环量在十万级到百万级
请问有什么好的方式解决 ?
...全文
789 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
qjtttt 2010-04-21
  • 打赏
  • 举报
回复
我还是用了纳秒,呵呵不能用毫秒,误差啊
qjtttt 2010-04-21
  • 打赏
  • 举报
回复
没用,我看出来楼主的问题了,他的意思就是说,界面让用户输入一个数值参数
而他程序内部实际上是这么写的
假设textfield内的指被传递进来了我们赋值给变量 long x楼主的意思就是说他还定义了如下代码,然后问我们如何减少
for(int i=0;i<=x;i++){
执行代码;
}
这样子的意思是吧?然后你还写成四个嵌套,循环的次数分别是四个传递进来的参数
要是这样的话,只能有两个方面去思考

第一你的循环确实一定需要循环传递进来的参数的次数么?
例如
for(int i=0;i<=x;i++){
if(flag)
执行代码;
else
break;
}

甚至你可以优化一下,可能其实你本来就只需要循环一半,说到一半这个词楼主应该想到什么了吧?
别告诉我你不知道二分

第二
从你的业务逻辑和你的程序设计合理性思考,是不是有必要让用户输入那么巨大的数字
是不是只有这一种办法可以得到你要的结果,是不是我们可以通过分段操作来执行?
例如
用户输入的参数比如说四个参数,A B C D,分别代表用户输入的次数就是循环次数,可以得到每次执行循环的需要用的时间
那么其实你可以在用户输入循环次数的时候,只要得到单步步长时间 也就是说你完全可以只循环一次,记录下时间
然后么就是一个数学问题了,HOHO

int x=2,y=3,z=4,p=5;
int aaa=1;
long start=System.nanoTime();
long time1,time2;

long start2=System.nanoTime();
for(int m=0;m<1;m++)
aaa++;
System.out.println(("for2 time is==="+x*y*z*p*(time2=(System.nanoTime()-start2))));


for(long i=0;i<x;i++){
for(long j=0;j<y;j++){
for(long k=0;k<z;k++){
for(long n=0;n<p;n++){
aaa++;
}
}
}
}
System.out.println("for1 time is==="+(time1=(System.nanoTime()-start)));

System.out.println("time2-time1==="+(time2-time1));

这个例子只是简单的举例,其实计算机运算的时候每一次消耗的时间不是相同的,所以肯定有误差的,这里就不用纳秒了,用毫秒,看不出误差,呵呵,第一个就是运算一次,然后简单的把所有的循环次数分别相乘得到的就是总共要循环的次数,最后乘上单次循环获得的时间,是不是减少了循环次数?

这里又引申出来个话题,呵呵,估计大部分人运算出来的结果很好玩,time2应该比time1要大,差不多正好是一倍左右,因为我的电脑是双核的,而java是原生支持多核多线程的,我猜测底层可能是用多核心的方式处理的运算,而且结果误差可以看到两次时间的误差差不多正好是0.8倍左右,酷睿2的性能比单核Intel的说法就是同样的主频和缓存提高0.8倍,呵呵,有虚拟机的朋友可以测试下,我的机子跑虚拟机老是错误,反正最近也用不到就懒得重装了,HOHO
欢乐极客 2010-04-20
  • 打赏
  • 举报
回复
对于这种问题,可以设计数据结构,或者使用其他算法。比如某些查找,可能需要很多循环,如依次搜索这种暴力查找方法,可以使用个迭代器之类的东西来改进代码。
hardycheng 2010-04-20
  • 打赏
  • 举报
回复
单算 X1中的数 相加 然后和 外面的系数再做乘积
basin_yi 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 michaellufhl 的回复:]

知道了终极方案:Java code
long foo(long x1,long x2,long x3,long x4){
long A=...;long B=...;long C=...;long D=...;
return x1*A+x2*B+x3*C+x4*D;
}

:)
[/Quote]
汗……重点不是这个~是X1,X2,X3,X4的循环如何解决,让整体计算过程能够高效
ArayChou 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用楼主 basin_yi 的回复:]
如果要做多层的嵌套循环~
而且每层的循环量在十万级到百万级
请问有什么好的方式解决 ?
[/Quote]

好方案就是: 引导用户需求,不要设计这样的程序。

大家都试图了解楼主到底有什么需求,需要如此嵌套循环,可楼主就是不说。

michaellufhl 2010-04-20
  • 打赏
  • 举报
回复
知道了终极方案:
long foo(long x1,long x2,long x3,long x4){
long A=...;long B=...;long C=...;long D=...;
return x1*A+x2*B+x3*C+x4*D;
}

:)
basin_yi 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 qjtttt 的回复:]

引用 35 楼 basin_yi 的回复:
如果真能提炼出方法~我肯定去简化
这个方程就是开始的入口~~
变量时按照前台人为输入~没有规律~

现在单纯就是两个方向
一,多层嵌套循环,优化循环方式,或者有好的代码方式
二,用其他手段实现以达到简化效果,但是必须是4个变量,逐一循环,代入方程得到结果


这就不好办了-。-
程序是你设计的你可以在前台控制输入的值的范围啊,有了……
[/Quote]
其实这只是业务处理其中一步而已,界面用SWING写的~~四个变量输入没有要求
反正最小是1,最大可能达到十万级别的数
qjtttt 2010-04-19
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 basin_yi 的回复:]
如果真能提炼出方法~我肯定去简化
这个方程就是开始的入口~~
变量时按照前台人为输入~没有规律~

现在单纯就是两个方向
一,多层嵌套循环,优化循环方式,或者有好的代码方式
二,用其他手段实现以达到简化效果,但是必须是4个变量,逐一循环,代入方程得到结果
[/Quote]

这就不好办了-。-
程序是你设计的你可以在前台控制输入的值的范围啊,有了范围才有可能精练出算法,至于变量时按照前台人为输入的这个问题么。。。。我有点好奇,变量还能是执行的时候输入的?我只知道可以在执行的时候把用户输入的数据赋值给我事先定义好的变量,至于表达式么更是事先写好的了
你的情况我能够想到最贴切的情况就是

你在程序里放了一个List,然后在控制台捕获用户输入的数据,捕获一行就放入List,如果用户输入的是你事先定义好的字符串,例如“start”就停止用户输入,你的程序开始运行
可能运行的是类似

Pattern pattern = Pattern.compile("[0-9]+");
List<Long> list=new ArrayList<Long>();
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
String str=null;
try {
System.out.println("Please input a value of integer:");
while (!(str = in.readLine()).equals("start")) {
System.out.println("Please input a value of integer:");
if((pattern.matcher(str).matches()))
list.add(Long.parseLong(str));
}
long j=0;
if(list.size()>0)
j=list.get(0);
for(int i=1;i<list.size();i++)
j+=list.get(i);
System.out.println(j);

} catch (IOException e) {
e.printStackTrace();
}

其实楼主仔细看这里其实依然是赋值的过程,我实在想不出有什么办法用户可以输入变量,楼主说的太少了,实在模拟不出情景,楼主多说一点吧,好奇中,HOHO
basin_yi 2010-04-19
  • 打赏
  • 举报
回复
行业玩意~~这是其中一个步骤
要得到公式计算结果而已
这是独立的一个步骤,只是单独模块化以供调用
这里是绝对可以独立出来的
justlearn 2010-04-19
  • 打赏
  • 举报
回复
能透露下这个程序的目的是什么吗
basin_yi 2010-04-19
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 qjtttt 的回复:]

google的运算数字不是用十万计的,sun以前有个bug就是Arrays的binarySearch方法,因为数组下标是int型的,早先是用的/2后来因为google的运算实在过于庞大以至于int范围越界了,变成负值,后来改成了>>> 1才解决这个问题,google你在实用他们的服务的时候有觉得非常缓慢么?google的访问量也绝对的巨大,一方面是通过优化硬件环境硬件性能,google更让人称道……
[/Quote]
如果真能提炼出方法~我肯定去简化
这个方程就是开始的入口~~
变量时按照前台人为输入~没有规律~

现在单纯就是两个方向
一,多层嵌套循环,优化循环方式,或者有好的代码方式
二,用其他手段实现以达到简化效果,但是必须是4个变量,逐一循环,代入方程得到结果
qjtttt 2010-04-19
  • 打赏
  • 举报
回复
google的运算数字不是用十万计的,sun以前有个bug就是Arrays的binarySearch方法,因为数组下标是int型的,早先是用的/2后来因为google的运算实在过于庞大以至于int范围越界了,变成负值,后来改成了>>> 1才解决这个问题,google你在实用他们的服务的时候有觉得非常缓慢么?google的访问量也绝对的巨大,一方面是通过优化硬件环境硬件性能,google更让人称道的是他们网络了太多的算法天才,所以繁琐的运算在算法下减少了运算次数,不管你说你循环是不是冗余的,但是可以肯定不是最有效率的方法,不是么?
qjtttt 2010-04-19
  • 打赏
  • 举报
回复
你说每个变量都要循环,只能说你对算法两个字理解的还不够透彻
qjtttt 2010-04-19
  • 打赏
  • 举报
回复
没有办法减少,只能控制循环的冗余运算,你没把你的情景放出来,简单的放了个很简单的方程式,要根据方程式和你说的话,只能说没办法,这就是个排列组合的问题
只有你自己得把握好你这四个变量可能出现的范围,然后才能优化出算法
例如 有变量X,我知道X的取值范围是1-100,如果把x所有可能的值求和 那么我就可以知道
1+99和2+98是一样大的,这样可以加50次,最后还有一个50没有数字和其配对
结果就是
那么其实你就可以把x的取值范围想象成一个数组,数组元素==数组下标
那么就是(array[0]+array[array.length-2])*array[array.length-1]/2+array[array.length-1]/2;这样就是一个算法 表示 (1+99)*100/2+100/2

更精练的话就是 (array[0]+array[array.length-1])*end/2
就是(1+100)*100/2
再精练的话就是
自己好好思考下你自己的算法怎么写,没办法的,算法都要慢慢琢磨的
也就是说如果有人告诉我,给我一个正整数让我计算从0开始到这个数字求和
我不需要循环,我找到了规律
直接

public int sum(int x) {
return (1 + x) * x / 2;
}

如果sum(100);
只要进行3次运算就可以得到结果了,但是如果用循环的话仅仅++操作就要100次
如果是sum(1000000);呢?这就是你现在的问题所在了,去摸索你的问题里面存在的算法吧
zfq642773391 2010-04-19
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 basin_yi 的回复:]
引用 29 楼 zfq642773391 的回复:

引用 28 楼 basin_yi 的回复:
引用 26 楼 justlearn 的回复:

引用 24 楼 basin_yi 的回复:
引用 22 楼 justlearn 的回复:

那问个假设,来简单点的,不要十万级别,
假设X1(2-5),X2(3-7),X3(8-9),X4(4-10)
你要计算的是什么结果呢
是2-……
[/Quote]
怎么会没有冗余,你是每次固定了三个值,但你运算X1*A+X2*B+X3*C+X4*D时,
当x4=1时,你要算X1*A+X2*B+X3*C;当x4=2时,你还要算X1*A+X2*B+X3*C,...直到你把x4算完
同理,你其余两层嵌套还有很多冗余的
basin_yi 2010-04-19
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 zfq642773391 的回复:]

引用 28 楼 basin_yi 的回复:
引用 26 楼 justlearn 的回复:

引用 24 楼 basin_yi 的回复:
引用 22 楼 justlearn 的回复:

那问个假设,来简单点的,不要十万级别,
假设X1(2-5),X2(3-7),X3(8-9),X4(4-10)
你要计算的是什么结果呢
是2-5都乘以A,然后3-7都乘以B...最后相加?

每……
[/Quote]
没有冗余的~每次变量的取值得到的公式结果都是需要的
每次固定3个变量的值,循环另外1个就行
zfq642773391 2010-04-19
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 basin_yi 的回复:]
引用 26 楼 justlearn 的回复:

引用 24 楼 basin_yi 的回复:
引用 22 楼 justlearn 的回复:

那问个假设,来简单点的,不要十万级别,
假设X1(2-5),X2(3-7),X3(8-9),X4(4-10)
你要计算的是什么结果呢
是2-5都乘以A,然后3-7都乘以B...最后相加?

每次4个变量(X1,X2,X3,X4)都取得范围中……
[/Quote]
把大量的冗余运算除去,运算时间会好很多,因为冗余太多了
basin_yi 2010-04-19
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 justlearn 的回复:]

引用 24 楼 basin_yi 的回复:
引用 22 楼 justlearn 的回复:

那问个假设,来简单点的,不要十万级别,
假设X1(2-5),X2(3-7),X3(8-9),X4(4-10)
你要计算的是什么结果呢
是2-5都乘以A,然后3-7都乘以B...最后相加?

每次4个变量(X1,X2,X3,X4)都取得范围中的固定值代入公式得到结果
例如X1(2-5),X……
[/Quote]
肯定每次循环都是必要的
但是如果嵌套4层,并且每层都是十万次以上的循环量
速度肯定慢死~~想找个好的方式
basin_yi 2010-04-19
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 michaellufhl 的回复:]

谁理解这个需求? :)
[/Quote]

就像一个四元一次方程
其中有4个参数~
只是这4个参数是范围取值
加载更多回复(26)

62,624

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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