以棋会友,诚聘高贤;→又加了算法大挑战,越来越有意思了!→补充新条件:计算机专业、本科以上的人--基本不要,还骂了几句,有人能反驳吗?但求一败!→骂的更厉害了!

在哪儿和你下棋?我的qq号:11428130,kangdeguo@sohu.com...
 
能找到比自己强的人就算输了也是收获嘛。 :)
你的数据已经按照分类代码排序,这个条件非常好。用一个长度为6的数组,记录每层父节点
的位置,出现一个叶子节点时,就对这些父节点的对应数据进行增量计算。具体计算时,还有
优化的技巧:
如果当前结点的分类代码和上一层的一样长,那么说明它们的父节点没有变化;
如果..................比........短,那么说明该点相对上一层已经回溯,父节点数组
的有效长度应该缩短;
如果............................长,那么说明该点是上一个节点的子节点,父节点数组
的有效长度应该相应的加长;
算法的大致过程为:
1.初始化父节点数组(将元素都置为-1),同时将数组有效长度、上一节点长度初始化为0;
2.主循环(双重循环,总时间复杂度为O(n*TreeLevel))
for i:=0 to ElementCount-1do
begin
Len:=Length(IDStr);
ParentArray[Len-1]:=i;
//父节点数组数据更新(只要更新最后一个即可)
if Len<ParentArrayValidLen then
Start:=Len
else
Start:=ParentArrayValidLen;
for j:=Start-1do
wnto 0do
//对父节点的数据进行增量操作
if ParentArray[j]>=0 then
Data[ParentArray[j]]:=Data[ParentArray[j]]+Data;
ParentArrayValidLen:=Len;
//更新有效长度
end;

没有检验过,但我估计大概算法思路就是这样了...
 
[8D]
有点对头了,但效率还是差好几个级数。
把思路再转一下,真会更快的,而且很简单。
 
>>还是差好几个级数
哇!我已经尽力了,虽然上面的代码可能会有一些小问题,但是我自认为已经将时间复杂度
降至最低(n*TreeLevel——这个n无论如何都是要有的——您至少要遍历数组吧,TreeLevel
在本问题中为6——连一个“数量级”都谈不上——还有比我的强“几个”级数的算法吗?),
空间复杂度也只是O(n+TreeLevel),而其中为了累加附加上去的空间仅为ParentArray数组和
一个ParentArrayValidLen变量而已。
lid=0479090、0555596、1277180
 
利用这2个select写循环
select 科目编码 from table where 科目编码<1000
select sum(当前余额) from table where 科目编码>(100+100000) and 科目编码 <(100000+100*10)
``` ```
我也凑个热闹,提一个我现在正在做的东东里的东西:
字节的8-7
要求:将字节的最高位提出放入下一个字节的末尾

举例:假设有3个字节,二进制码为
10000001
10000010
10000100
要求转换为:
00000001
00000101
00010010
00000000
说明:
转换后每一个字节小于128,
也就是说
第一个字节要将最高位一位取出放入下一个字节末尾,
则第二个字节要取最高位2位放入第三个末尾,
则第三个字节要取最高位3位放入第四个个末尾,
以此类推,所有字节都是这样
当然实际工作不会只有3个字节,而是一张图片,
所以请大家考虑用流来入
我也已经写完了,看看有什么更快的算法
 
[8D][8D]
不是我夸张,确实差几个级数:
当你找到一个子节点的数值时,是不是要回去把这个数值加到所有父节点上去?
究竟有几个父节点,最多六个,是吧,那你不是要回去六次?
而且你是针对数组操作,那要把数据表读到内存里,有没有影响啊?
你放弃掉计算机,用手算一下,是不是要把这个帐本来回翻动呢?
我的方法:不用来回翻,只要从头到尾检视一遍,所有数据全部搞定。是不是快几个级数?
问题是怎么处理的?
To wolfsong:
你的SQL语句写得不对吧,我看实现不了。
就是用这种办法实现了,也只是我的第一种方案,慢得要命!
 
一点意思都没有![:(!]就一个算法而已,还搞得神神秘秘的,有自恋的嫌疑!还不知道是
不是真的有那么快!
 
我没写代码测试,真正写代码不会用那2个select:-)
我并没有把它看成一棵树
我只是这样想:
你的父节点id都小于1000,子节点都大于100000,同时你只有2层
那么可以这样理解:
我只用一次select,然后对依次判断,小于1000作为父节点,
大于1000的我判断在哪个范围内
例:101的子节点都是大于101000小于102000。
我完全可以在一次select后得出我想要的结果,剩下就是插入。

 
TO : 舞雪,
我觉得你真令人扫兴。好在大家都不怪你。
 
从头到尾只走一遍的方法我想是这样的:
把数据库的数据倒排序,最大的最长的在前面,
171002 势欧 借方 其它应收款→势欧 1350
171001 樱达利息 借方 其它应收款→樱达利息 6750
171000 昌盛 借方 其它应收款→昌盛 41306.85
171 其它应收款 借方 其它应收款 49406.85
137 产成品 借方 产成品 0
135 半成品 借方 半成品 0
123003 铜板纸 借方 原材料→铜板纸 1477.17
123002 坑纸 借方 原材料→坑纸 48803.4135
123001 白板纸 借方 原材料→白板纸 81211.3245
123 原材料 借方 原材料 131491.908
5个变量intV,分别表示5层的和。
5个变量strV,分别表示当前在那一层。
从第一个记录开始走:
分拆这个科目,如果原始叶子(或者不等于0的,反正是最小的分支)的则,所有的亲属都加上这个值。
如果是中间的某各层,则将相应的层次的值intV等于这个值。前面(到原始结点方向)的intV置0。
一直 循环到结束。
不知道这样你说能不能明白我的意思,不过这样确实只有一次循环就能搞定的。
楼主: 对吗?
 
要我做肯定用临时表了
 
[8D][8D][8D]
哈哈哈……
果然有高手,这么轻松就想到了,我还想申请专利呢。——开个玩笑。
确实是这样,思路对了,很简单。而且如果在存储过程中用游标的话,肯定很快,几千条记录,根本不在话下。
creation-zy想对了一半,就是用编码长短变化来判断父子关系,可惜忽略了另一点:要倒过来排序才行。因为如果没有子节点数据的话,是没法汇总的,汇总后的数据,一定要倒退才能赋值;但如果先检视子节点的话,却可以马上记录下父节点所需的数据,进而对不同层次的父节点操作。
和大家探讨一下,贻笑大方了。
大笑几声,不妨事吧。——笑对人生嘛。
不知道“自恋”是什么意思,不过作为程序员,肯定是经常“自赏”的,实现一个功能,编出一个产品,对着他左右把玩,能不高兴?知音奇少,说与谁知?何不“自赏”?

 
没有意思,做多了。
 
[8D][8D]
“老子”说过:“祸福相倚,雌雄相从”(可能记错了,有时间我差一下)。
果然不错!
问题没解决,一声不吭。一旦问题被解决,马上其它声音出来了:[red]没有意思,做多了。[/red]
果然不错!
 
pyzfl :
不用去理他,相信 DFW 的大多数人对技术都是非常的热爱的,讨论技术,不和那种人一般见识。
^_^。。
 
唉,没想到倒序。
那我的算法怎么没人给个?
 
[8D][8D]
古有“比武招亲”,今有“比棋招工”,怎么还没有人来啊?
名额不多,良机难得,先下手为强啊。
 
古代也有以棋招大臣的,棋谱现在还有。
本人颇喜象棋,不知愿手谈一次。
 
看来在这个问题上我还“棋差一招”——应该是“反向遍历、一次搞定”。您谈到了数组
定位的耗时问题,我个人认为,对于Basic之类的语言,数组肯定是存放在内存中的,定位
数据的代价远比现在的关系数据库小,因此我还是认为不可能存在“数量级”的差距。
我在上面写的代码,数千条记录百分之几秒就处理完毕,我相信比什么“存储过程”之类
的东东一定要快,而且不只一点(我到现在还对数据库持蔑视态度)。只是我觉得数据传输
是一个大问题,是算法本身耗时的近5倍,综合比较下来,用存储过程肯定划算。但是,如果
问题更加复杂,就必须下载到本地用算法解决了(不知道数据库能否直接用ActiveX或者DLL
什么的,直接操作数据,而不用通过什么ODBC之类的接口,就像Web Server调用ISAPI一样)。
弄了半天还是要下棋呀...
 
顶部