设A[1..n]是一个包含N个非负整数的数组。如果在i〈 j的情况下,有A〉A[j],则(i,j)就称为A中的一个逆序对。
例如,数组(3,1,4,5,2)的“逆序对”有<3,1>,<3,2><4,2><5,2>,共4个。
使用归并排序可以用O(nlogn)的时间解决统计逆序对个数的问题
定义:对于一个给定的数列,如果有i<j,且Ai>Aj,则称(i,j)为一逆序对.
要解决的问题是,给出一个数列,求出这个数列包含多少个逆序对
今天在《算法导论》上看到了这题,提示用归并算法,没想明白。在google搜了一下,有一些实现但是没讲清楚,后来自己动手做了一下算是弄明白了。
普通实现 O(n^2):
1
template<class Iterator>
2
int countInversePair(Iterator first, Iterator last)
3

{
4
int count = 0;
5
Iterator it;
6
while(first != last)
7
{
8
it = first;
9
while(it != last)
10
{
11
if(*it < *first)
12
count++;
13
it++;
14
}
15
first++;
16
}
17
18
cout << count << endl;
19
20
return count;
21
}
归并实现 O(nlogn):
1
int gCount = 0;
2
3
template<class Iterator>
4
int merge(Iterator begin, Iterator mid, Iterator end)
5

{
6
Iterator iL = begin;
7
Iterator iR = mid;
8
9
int count = distance(begin, end);
10
vector<int> v(count);
11
vector<int>::iterator it = v.begin();
12
13
while(iL != mid && iR != end)
14
{
15
if(*iL <= * iR)
16
{
17
*it++ = *iL++;
18
}
19
else
20
{
21
gCount += distance(iL, mid);
22
*it++ = *iR++;
23
}
24
}
25
26
if(iL == mid) copy(iR, end, it);
27
if(iR == end) copy(iL, mid, it);
28
29
copy(v.begin(), v.end(), begin);
30
31
return 0;
32
}
33
34
template<class Iterator>
35
int mergeSort(Iterator begin, Iterator end)
36

{
37
int count, step;
38
count = distance(begin, end);
39
40
if(count <= 1)
41
{
42
return 0;
43
}
44
45
step = count / 2;
46
47
mergeSort(begin, begin + step);
48
mergeSort(begin + step, end);
49
50
merge(begin, begin + step, end);
51
52
return 0;
53
}
重点在 gCount += distance(iL, mid)
逆序对数实质就是插入排序过程中要移动元素的次数。
归并的时候 前后两个序列都是有序的,可以把这个过程想象成插入排序,将第二个序列的内容插入到第一个有序的序列中
那么插入第二个序列中的元素时,要移动的元素的位数即第一个序列中还未插入到新序列中的元素的个数
即: distance(iL, mid)
posted @ 2008-11-06 00:09 哈哈熊 阅读(755) 评论(1)
编辑
问题:
给定一个数组,要求向左或向右循环移动k位
如 1,2,3,4,5,6,7,8,9 向左循环移动移动3位变成4,5,6,7,8,9,1,2,3
答案:
1. 反转数组
reverse(v.begin(), v.begin() + k);
reverse(v.begin() + k, v.end());
reverse(v.begin(), v.end());
2. 最大公约数
int gcd(int m, int n)
{
return n == 0? m : gcd(n, m % n);
}
void rotate(char* data, size_t count, int k)
{
size_t d = gcd(count, k);
for(int i = 0; i < d; i++)
{
size_t cur_pos = i;
size_t prev_pos = cur_pos;
char temp = data[cur_pos];
while((prev_pos = (prev_pos + k) % count ) != i)
{
data[cur_pos] = data[prev_pos];
cur_pos = prev_pos;
}
data[cur_pos] = temp;
}
}
3 模拟STL的rotate
void rotate(char* data, size_t count, int k)
{
int next = k;
int first = 0;
while(first != next)
{
data[first++] == data[next++];
if(next == count)
{
next = k;
}
else if(first == k)
{
k = next;
}
}
}
posted @ 2008-10-26 13:48 哈哈熊 阅读(139) 评论(0)
编辑
I watched an video about SOA on youtube today. After talking a lot of things, the presenter give us the point why we need SOA: Change. SOA make the IT system more flexible. On catching this, I aware that during the evolution process of software development, there are so many thing we do are due to fitting change. OO TDD SOA. What's next?
posted @ 2008-06-25 00:11 哈哈熊 阅读(74) 评论(0)
编辑
在博客园混了很久了,写的不多看的多。今天发个求职信息,大家看看有没有合适的不?
现在研二,去年课上完后在学校就没什么事了。去年下半年在北京一个公司实习了半年。我今年年底毕业,也不知道现在能找工作签约不?不能签就打算继续实习吧。
.NET 5年经验 从03年4月开始学习.NET算到现在正好5年了。
本科到现在几年大部分时间是用ASP.NET做Web开发,校园网站(
www.stuplaza.net)、校外网站(hb.gmw.cn)做过很多,然后也用WinForm断断续续用了2年时间做过一个软件,没卖到什么钱,就当是熟悉WinForm吧。
去年在北京那个公司是做Web GIS,写了半年的js, 主要是做客户端API,让用户通过几条简单的js语句就能创建一个Google Maps那样的地图应用。基本都是我一个人写,对js这个语言算是比较熟悉了。在做这之前虽然做了几年Web开发,但是对js一直不怎么熟。本来公司只打算让我改改老api的,后来看做的还行就决定把整个API重写了,呵呵。以前只能在IE下用,现在在FF下也能用了。然后现在整体结果比老的好了很多,扩展起来比较方便。
有些东西自己做的项目中很多时候都用不到,但是自己经常摸索,不算精通,算是有点熟悉吧:SVN、Linux、设计模式?、NUnit
开发工具VS2003 2-008,2003用的最多,Eclipse也用了半年,不过主要用来写js。
SQL Server很熟悉,因为这几年一直在用,然后My SQL只能说用过。Oracle?听过,呵呵。因为我参加的大多项目都用不到它。
面向对象,算是比较了解吧。面向方面?看过一些资料,没具体用过。
计算机专业6年,该学的课程基本都学过,有好有差吧,总体还行。GPA TOP 1%? 呵呵
写的比较乱,总结下,做做广告:基础还行,学习能力比较强吧,与人沟通能力也还行。欢迎拍砖。
MSN:xiongharry在hotmail.com
posted @ 2008-02-21 00:12 哈哈熊 阅读(333) 评论(2)
编辑
OpenLayers是一个非常不错的开源的GIS库,纯js编写。我实习的公司原本打算开发一套自己的客户端API,在开发过程中发现OpenLayers的设计和我们自己的设计有很多相似的地方,而且OpenLayers本身已经比较完善。所以在后期,我们放弃了自己开发的API,转向了OpenLayers,结合我们已经开发的那一部分,将OpenLayers的修改成符合我们需求。
目前大部分地方完成了,现在的主要工作是性能优化,特别是对于VML渲染速度的优化。研读了一下OpenLayers的关于VML渲染的代码,发现它的设计虽然比较完善,但是在代码的执行效率上还有很多需要改进的地方。
1、由于OpenLayers对于Geometry的层层套嵌的组织方式,导致Geometry.Point执行的次数太多,而prototypejs那种Class和initialize的方式可能比较慢(没具体测试过),所以这里来是一个可以改进的地方。要么将Geometry.Point改成原生的Function方式来声明,要么直接在Geometry.Polygon这样的类中不使用Geometry.Point。
2、在由Geometry转化的过程中,拼path串时,OpenLayers采用的是path+="abc"这样的方式,这时目前导致效率低下的第一原因。将这种方式改为path.push("abc")然后path.join(" ")这种方式之后,整体效率大大提高。
3、对于点没有进行去重复的处理。即当一个Geometry转化程屏幕上的VML时,有很多点是重合的。
4、即使一个Geometry不在viewPort范围之内,OpenLayers仍然会画出一个Geometry。不过这又分出两种情况,一种情况是整个Geometry都不在范围内,二是只有部分不在范围内。对于第二种情况的处理比较麻烦。
暂时总结这么多吧。
posted @ 2008-01-10 15:50 哈哈熊 阅读(697) 评论(2)
编辑
摘要: 好多时候写的js在Firefox下面调试通过,可是拿到IE下面确运行不了,找了半天错误,最后发现原来是一个小小的逗号引发的悬案。比如定义一个对象var abc = {a: null,b: "haha",c: function(){},}这段js在FF下面是没有问题的,可是到了IE确不行。就是因为最后的那个逗号,如果去掉那个逗号就可以了。
阅读全文
posted @ 2007-12-07 11:27 哈哈熊 阅读(53) 评论(0)
编辑
摘要: 在程序中要生成很多的HTML,Dom方式比较自然,但是很满,innerHTML的方式快,但是看起来又不够自然,所以我决定写一个简单的小工具来结合两者的功能。HElement=Class({strs:null,INSERT_POINT:"__inserPoint__",initialize:function(tagName,back,attributes,intext){attributes=att...
阅读全文
posted @ 2007-11-30 13:00 哈哈熊 阅读(75) 评论(0)
编辑
摘要: 前几天装了ubuntu,把以前在Windows下的应用基本都转移到了linux下来了。linux用起来很多方面还是不如Windows方便。比如说界面很难配置的比Windows好看,呵呵,我比较看重这个,什么东西都要讲究个用着舒心是吧。另外很多软件在linux下面没有对应的,即使有很多时候也比Windows下面的体验差一些。比如说QQ,LumaQQ是个好东西,但是还是有多问题,在我这里经登不上,而且...
阅读全文
posted @ 2007-03-04 00:05 哈哈熊 阅读(26) 评论(0)
编辑
摘要: 学计算机很多年了,对于计算机的认识也不断的加深,当然更多的是在计算机软件方面。从以前用QBasic做一些小游戏开始,一路学了C、VB、C++、C#、Java、Python等。学了一大堆乱七八糟的东西,可是上了CSDN论坛看别人的提问,还是大多不会回答。自己总结了一下,大概有两个原因。一、自己没有实际做一些实际项目的经验;二、自己对于所学的各方面的知识都不够深入。所以面对工程技术实际中的问题,总是面...
阅读全文
posted @ 2007-01-16 02:44 哈哈熊 阅读(37) 评论(0)
编辑