2.1-2
View Code
1 publicstaticvoid insertionSort(int[] A) {
2 int j;
3 int key;
4 int i;
5 for (j =1; j < A.length; ++j) {
6 key = A[j];
7 i = j -1;
8 while (i >=0&& A[i] < key) {
9 A[i +1] = A[i];
10 i = i -1;
11 }
12 A[i +1] = key;
13 }
14 }
2.1-3
View Code
1 publicstaticint find(int[] A, int v) {
2 for (int i =0; i < A.length; ++i) {
3 if (v == A[i]) {
4 return i;
5 }
6 }
7 return-1;
8 }
2.1-4
View Code
1 publicstaticboolean[] BiAdd(boolean[] A, boolean[] B) {
2 boolean[] mResult =null;
3 int i;
4 boolean mAcc =false;
5 if (A.length != B.length) {
6 returnnull;
7 }
8 mResult =newboolean[A.length +1];
9 for (i = mResult.length -1; i >0; --i) {
10 mResult[i] = B[i -1] ^ mAcc;
11 if (A[i -1]) {
12 mResult[i] =!mResult[i];
13 mAcc = B[i -1] | mAcc;
14 } else {
15 mAcc = B[i -1] & mAcc;
16 }
17 }
18 mResult[0] = mAcc;
19 return mResult;
20 }
2.2-1
Θ(n^3)
2.2-2
View Code
1 publicstaticvoid selectionSort(int[] A) {
2 int i;
3 int j;
4 int mCurrMin;
5 int mCurrMinIndex;
6 int mLastIndex;
7 int mLength;
8 int mAj;
9
10 mLength = A.length;
11 mLastIndex = mLength -1;
12
13 for (i =0; i < mLastIndex; ++i) {
14 mCurrMin = Integer.MAX_VALUE;
15 mCurrMinIndex =-1;
16 for (j = i; j < A.length; ++j) {
17 mAj = A[j];
18 if (mAj < mCurrMin) {
19 mCurrMin = mAj;
20 mCurrMinIndex = j;
21 }
22 }
23 A[mCurrMinIndex] = A[i];
24 A[i] = mCurrMin;
25 }
26 }
Loop invariant: min(A[i .. n-1])=A[i] ⋀ {a|a∈A}|begin-of-loop={a|a∈A'}|end-of-loop
Why only the first n - 1 elements: i=n-1: min(A[i .. n-1])=min(A[n-1 .. n-1])=min(A[n-1])=A[n-1]
Best-case: Θ(n^2); Worst-case: Θ(n^2)
2.2-3
How many elements to be checked on the average: n/2
How many for worst-case: n
Average-case: Θ(n); Worst-case: Θ(n)
2.3-2
View Code
publicstaticvoid merge(int[] A, int Left, int Middle, int Right) {
int mLeftLength;
int mRightLength;
int i;
int mCurrLeft;
int mCurrRight;
int[] mLeft;
int[] mRight;
int mLeftData;
int mRightData;
mLeftLength = Middle - Left +1;
mRightLength = Right - Middle;
mLeft =newint[mLeftLength];
mRight =newint[mRightLength];
for (i =0; i < mLeftLength; ++i) {
mLeft[i] = A[Left + i];
}
for (i =0; i < mRightLength; ++i) {
mRight[i] = A[Middle + i +1];
}
mCurrLeft =0;
mCurrRight =0;
i = Left;
do {
mLeftData = mLeft[mCurrLeft];
mRightData = mRight[mCurrRight];
if (mLeftData < mRightData) {
A[i] = mLeftData;
++mCurrLeft;
} else {
A[i] = mRightData;
++mCurrRight;
}
++i;
} while (mCurrLeft < mLeftLength && mCurrRight < mRightLength);
if (mCurrLeft < mLeftLength) {
while (mCurrLeft < mLeftLength) {
A[i] = mLeft[mCurrLeft];
++i;
++mCurrLeft;
}
} else {
while (mCurrRight < mRightLength) {
A[i] = mRight[mCurrRight];
++i;
++mCurrRight;
}
}
}
publicstaticvoid mergeSort(int[] A, int Left, int Right) {
int mMiddle;
if (Left < Right) {
mMiddle = (Left + Right) /2;
mergeSort(A, Left, mMiddle);
mergeSort(A, mMiddle +1, Right);
merge(A, Left, mMiddle, Right);
}
}
2.3-3
(k=1: n=2^k=2^1=2 => T(n)=T(2)=2*lg(2)=2) ⋀
((k=t: n=2^k=2^t => T(n)=T(2^t)=2^t*lg(2^t)=t*2^t)
=> (k=t+1: n=2^k=2^(t+1) => 2*T(2^(t+1)/2)+2^(t+1)=(t+1)*2^(t+1)=T(2^(t+1))=T(n))) => (T(n)=n*lg(n))
这里我不谈减低色彩深度时, 采用抖动减少误差的方法. 因为本文将着力于找到尽可能快的算法 (虽然最快的方法一定存在, 但我们只能去接近它, 而无法达到, 因为优化是无至尽的, 而且随着 CPU 而变化)实时转化 24bit (或32bit) 的真彩色位图到16bit(15bit)的高彩色.
为什么要实时转换颜色深度?
通常, 2D 游戏中的位图, 无论在外存中按什么颜色深度存放, 加栽后都被转换成了需要的颜色深度. 我们不太注意颜色深度转换说需要的时间.
但是, 现在不同了. 云风未来的计划中, 最重要的一项是制作一个超级 2D 引擎. 将支持 Voxel 物体和实时光线处理这样的特性, 而且在光线处理中, 32 级的光线亮度级别也远远不够, 所以, 未来的 2D 游戏的发展趋势应该是采用真彩色, 至少是在内部运算时使用. 在某些场合下, 我们可能需要做 15/16bit 高彩色的输出, 所以有必要找到更快的方法实时处理.
下面, 我们对此做一些探讨, 虽然显卡可以支持 15 或 16 bit 色中的一种, 但这里全部用 16bit 色举例:
先来看看 C 版本:
red=(truecolor> > 8)&0xf800;
green=(truecolor> > 5)&0x7e0;
blue=(truecolor> > 3)&0x1f;
hicolor=red|green|blue;
这样当然是相当慢的, 所以我们还是要借助汇编. 而汇编能极大的优化它:
lodsd ;RRRRRRRR GGGGGGGG BBBBBBBB
shr eax,3 ;000RRRRR RRRGGGGG GGGBBBBB
shl al,2 ;000RRRRR RRRGGGGG GBBBBBxx
shl ax,3 ;000RRRRR GGGGGGBBB BBxxxxx
dec esi
shr eax,5 ;00000000 RRRRRGGG GGGBBBBB
stosw
是不是精简了很多? 但不幸的是, 虽然看起来很简洁, 但由于大量使用部分寄存器, 对流水线的冲击很大. 代码几乎把流水线的效率减到了最低. 优化方案很多, 我们可以在一次循环里处理两个点, 分别使用 eax 和 ebx, 然后交错那些代码; 又或者将上面代码的后半部分改为查表, 相信都能提高速度. 但是下面我还想提出另一种方案, 采用 MMX 指令级:
mm7=F800F800F800F800
mm6=FC00FC00FC00FC00
------------------------------
punpcklbw mm0,[red+edx]
;mm0=RRRRRRRR 00000000 RRRRRRRR 00000000 RRRRRRRR 00000000 RRRRRRRR 00000000
punpcklbw mm1,[green+edx]
;mm1=GGGGGGGG 00000000 GGGGGGGG 00000000 GGGGGGGG 00000000 GGGGGGGG 00000000
punpcklbw mm2,[blue+edx]
;mm2=BBBBBBBB 00000000 BBBBBBBB 00000000 BBBBBBBB 00000000 BBBBBBBB 00000000
pand mm0,mm7
;mm0=RRRRR000 00000000 RRRRR000 00000000 RRRRR000 00000000 RRRRR000 00000000
pand mm1,mm6
;mm1=GGGGGG00 00000000 GGGGGG00 00000000 GGGGGG00 00000000 GGGGGG00 00000000
psrlw mm2,11
;mm2=00000000 000BBBBB 00000000 000BBBBB 00000000 000BBBBB 00000000 000BBBBB
psrlw mm1,5
;mm1=00000GGG GGG00000 00000GGG GGG00000 00000GGG GGG00000 00000GGG GGG00000
por mm0,mm2
por mm0,mm1
;mm0=RRRRRGGG GGGBBBBB RRRRRGGG GGGBBBBB RRRRRGGG GGGBBBBB RRRRRGGG GGGBBBBB
movq [dis+edx*2],mm0
add edx,4
我们对 MMX 的运用是针对它的并行运算, 直接从 RGB888 格式利用并行处理变成 RGB565 似乎不可能, 但是, 如果我们将 RGB 三个色素分开存放, 就将其变为了可能. 可以同时读入 4 个色素, 并行处理, 然后合并, 这样便在一个循环内处理了 4 个点. 考虑到 CACHE 的效率, 最好不要将 RGB 三块内存分的太开. 我的建议是, 位图的每一行分成三个部分, 即为 Red 段, Green 段 和 Blue 段.
上面的方法都是可以继续优化的, 本文旨在启发朋友们的灵感, 找出更好的方法.
这几天终于把SVN的事情搞定了——这本来是一件极其简单的事情,可是由于各种悲剧导致各种复杂。
本来我选择SourceForge的用来SVN,可是想到宿舍里的校园网是根本打不开SourceForge的主页的,况且打开中国大陆地区的网页也是十分吃力的,以前用不是宿舍的校园网,虽然能上SourceForge,但是CVS(当时SVN还没有流行开来~~哈哈)有次提交一个4KB的源文件花了十几分钟……
然后重点是Zend Studio for Eclipse自带的SVN客户端插件极其的诡异(他的CVS客户端没什么诡异的),莫名其妙的说有Conflict,或者没办法设置svn:keywords或者svn:ignore,总之很闹心。不过后来费了一番周折,问题都解决了——果断使用乌龟SVN。
现在项目的SVN地址在Google Code上,地址是http://code.google.com/p/frameworkdsw/。如果你想看看源代码是什么样子,单击这里浏览,下面是Checkout的命令,请用计算机或者人工点击鼠标执行……
svn checkout http://frameworkdsw.googlecode.com/svn/trunk/ frameworkdsw-read-only
- 最新进展
现在主要忙于容器框架和统一数据库访问层。下次再出成果介绍(或者SVN上源代码先看起来)……
顺便指出一下,你认为下面的代码合理吗,然后看看会不会出错呢?
<?php
abstract class TAbstractParam {
protected $FValue = null;
public abstract function getType(); //getType
public function Dump() {
return "TYPE=" . $this->getType() . " VALUE=" . $this->FValue;
}
}
interface IParam {
public function getType(); //getType again.
}
class TStringParam extends TAbstractParam implements IParam {
public function getType() {return 'VARCHAR'; } //another getType, the fatal error goes here.
}
想发表意见请最好去这里:http://bugs.php.net/bug.php?id=51826,当然这里留下您的评论也可以~

