posts - 195, comments - 34, trackbacks - 0, articles - 1

2010年4月18日


            偶然发现了盛大的maiku, 是一个不错的日志和资源整理平台。于是转向了它,地址是 http://note.sdo.com/u/dongwq
欢迎来看看。

posted @ 2011-05-15 21:53 小强摩羯座 阅读(244) | 评论 (0)编辑 收藏

•  前者:看见与不看见,但是位置保留。
      •  后者处理与位置有关:block, inline, none 分别是有前后换行,不换行,不显示功能但是不保留位置。
    
    
•  二者功能差异:保留位置,和位置形式

    
<script language="javascript">
    function toggleVisibility(me)
    {
    
if(me.style.visibility=="hidden")
    {
    me.style.visibility
="visible";
    }

    
else
    {
    me.style.visibility
="hidden";
    }
    }

    
</script>

    
<DIV  onclick="toggleVisibility(this)"

    style
="position:relative">

    第一行文本将会触发
"hidden""visible"属性,注意第二行的变化。

    
</DIV>

    
<DIV>因为visibility会保留元素的位置,所以第二行不会移动.</DIV>

    
<script language="javascript">

    function toggleDisplay(me){

    
if(me.style.display=="block"){

    me.style.display
="inline";

    alert(
"文本现在是:'inline'.");

    }

    
else{

    
if(me.style.display=="inline"){

    me.style.display
="none";

    alert(
"文本现在是:'none'.3秒钟后自动重新显示。");

    window.setTimeout(
"blueText.style.display='block';",

    
3000,"javascript");

    }

    
else{

    me.style.display
="block";

    alert(
"文本现在是:'block'.");

    }

    }

    }

    
</script>

    
<DIV><span id="blueText"

    onclick
="toggleDisplay(this)"

    style
="color:blue;position:relative;cursor:hand;">

    蓝色
</span>文字上点击来查看效果.</DIV>

posted @ 2010-09-14 13:47 小强摩羯座 阅读(1025) | 评论 (0)编辑 收藏

     摘要: 1 . 日志的组成:配置文件,写日志 log.cfg ############################################################ #      Default Logging Configuration File # # You&nbs...  阅读全文

posted @ 2010-09-09 15:09 小强摩羯座 阅读(408) | 评论 (0)编辑 收藏

项目经理之修炼(8)——别忘了告诉别人你是谁

文章分类:软件开发管理
副标题——名不正言不顺,项目管理难度加倍

你能想象美国总统上任,却没有总统就职仪式吗?
你能想象北京奥林匹克运动会,没有开幕式表演吗??
OK。相信你一定见过这样的场景:
某老板匆匆忙忙地进了屋,忽地来了一嗓子:“大家静静,通知大家一下:以后,某项目就由小张负责了!”

**************************************************

话说楚汉相争。刘邦在萧何的再三举荐下,决定让韩信为大将。

“来人,叫韩信过来,我要封他为大将。”刘邦道。

萧何表示异议:“汉王你一向傲慢没有礼貌,现在拜大将就和喊一个小孩子那么随便,所以韩信才会离开的。汉王要想用人家,必须选一个吉日,吃素,设祭坛,用非常郑重地礼节来拜将才行。”刘邦同意萧何的意见。

结果,尽管韩信是个无名小卒,却顺利的接过了军权,而没有碰到那些元老们的抵抗,成功地导演了一幕幕战争奇迹。

**************************************************

登台拜将,是一件具有深刻管理内涵的故事。它告诉我们这样一个道理:
——内容是重要的,但形式却是不容忽视。

我们不求老板非要在某个公开场合悠扬地宣告:“某项目成立了!!小张从此站起来了!!!”什么吉日,什么斋戒,什么礼仪。。。也就罢了。

但是,不给正式任命书;不在正式场合公布;甚至连一个头衔都舍不得。这绝对是没天理的。

**************************************************

“看,老板不重视这个项目。。。”(相关人员)
“瞧,老板不重视这个家伙。估计这个家伙没有什么后台” (相关人员)
“你负责某项目?我怎么不知道有这么个项目呢?你是哪位啊?” (相关人员)
“老板似乎并不重视/信任我啊” (项目经理)

***************************************************

以上种种,对项目的推动极为不利的。尤其是手下有资深员工、或者项目经理候补者等挑战者的时候,问题将会加倍严重。

大家可能会怀疑:“没有那么严重吧?”
没有不严重,只有更严重!!
这其中蕴含着一个深刻的道理——名不正则言不顺!!

言不顺是什么意思呢?

-你的意见可能被忽视;
-你的命令可能被当作建议;
-你的计划可能被别人忘记;
试想,你如果是项目经理,你的项目将会怎样。。。。。。

*********************************************************

Question: 我没有办法叫老板改变。那么,我该怎么办?
Answer:要写一封邮件!!告诉别人你是谁。

*********************************************************

你的老板犯了错误,可是你不能将错就错!你的老板忽视了“名”的问题(形式问题),你一定要扳回来!!
试想,你的老板不重视,你也不重视,你能指望别人重视吗??
当然,答案就是别人会更不重视!!

那么,这封邮件该怎么写呢??


**************************************************

MailTo: 所有下属
CC:     所有相关领导,所有相关人员,自己
Title:  【A项目】A项目的新项目经理小张向大家问好
Content:

1 开门见山地告诉别人自己的位置(正名)
2 向相关人员致敬,并自然地点出自己的优势(自我介绍)
3 向领导致敬致谢(拉近和领导关系)
4 暗示自己的权利范围(宣布自己的领地)
5 喊两句口号(合作和积极的姿态是必要的)
6 不要忘了签名(进一步加深印象)

//其中,1、2、4是必须要表现出来的

**************************************************

上面这封邮件,基本上完成了告诉别人你是谁的问题,而且完成了你的位置身份暗示。
如果说老板不负责任的任命形式带给你身份位置认同危机,沉重打击了你的威信的话,
通过这份邮件,你已经用身份暗示这个武器,夺回了主动权!!

从这封信以后,由于你的身份位置的明确,
相关人员在潜意识中会认同你的领地所有权,
会对在你的领地上和你发生冲突产生不自然,不合法甚至负罪感,
从而下意识中就会避免和你发生冲突。

反过来讲,你的位置身份的明确,将成为你自信的源泉,
而这种位置感产生的自信将使你的发言充满了正义感,
加上项目经理这个位置所带来的小小的势能。。。
权力这个东西,真好!!

嗯,一个好的开端,不是吗?

posted @ 2010-09-08 17:02 小强摩羯座 阅读(209) | 评论 (0)编辑 收藏



1、函数定义和使用

 

<script>

function sqrt(x) {
    return x * x;
}
function other(f) {
    var y = f(10);
    return y;
}

var farr = new Array();
farr[0] = function(arg) { return arg + arg;};
farr[1] = function(arg) { return arg * arg;};

document.write(farr[0](10) + '<br/>');
document.write(farr[1](10));

 

document.write(other(sqrt));

</script>

sqrt.count = 0;
sqrt.getcount = function() {
                    return this.count;
                }; // 附加函式

//sqrt();
document.write(sqrt.count, '<br/>');
document.write(sqrt.getcount());

posted @ 2010-07-25 15:38 小强摩羯座 阅读(189) | 评论 (0)编辑 收藏

杜拉拉升级记:


 关键一点,你的上级要喜欢你。工作中涉及要决策的都要跟上级报告。这是上级的作用。


 对于平级的同事是不能用命令,不能要求别人做事的。

 事情不能自己承担下来。

 

感谢小熊同学借我这本书看
    说说我的感受:此书没有书评中说的那么好,当然也没有那么坏。大家各取所需就好。与其叫小说,不如说是一种创新形式的职场教材。不要太去在意作者的文笔,而要更多的体会书中各位同学的处事之道。
    几句话总结一下:
    1、勤奋是王道,其他的都属于EQ范畴了
    2、要注意技巧,尤其是沟通技巧,别干了半天,没人知道你的工作量有多少。
    3、掂量自己的能力,做好该做的事,不做不该做的事,比如越级汇报。
    4、不要说人坏话,能帮助别人时要帮,关键时刻即使没有人帮你说话,但也不会有人说你的坏话。不信的话,去看看圣经怎么说得吧。
    5、要有气量,做事要圆通。
    6、要有自己的风格,风格没有好坏之分,但是一定要有。
    7、告诉我们什么是好工作,这点比较长,见下面的摘抄(感谢“木马|造化弄人”的贡献):
  
  “一、关于什么样的职位算好职位
    
  1.你得找一家好公司
  什么是好公司?
      
  1)产品附加值高,生意好,并且从业务线看,具备持续发展的能力和前景;
  2)有专业的/聪明能干的/经验丰富的/并且为人现实的管理层,在把握这公司,并且有保护一贯这样用人的制度的公司;
  3)有严格的财务制度,对预算、费用和利润等于投入产出有关的内容,敏感并且具有强控制力的公司;
  4)崇尚客户导向/市场导向/结果导向/执行力的公司;
  5)有专业严谨全面的流程和制度,并且其执行有利于推动业务的良性发展,具有控制性和实操性兼备的特点;
  ---总结起来,就是一家具有持续赢利能力的牛B公司
      
  2.你的找一个好的方向
      
  什么是好的方向?
   永远不要远离核心业务线。你得看明白,在企业中,哪个环节是实现利润最大化的关键环节。有时候是销售环节,有时候是市场策划环节,有时候是研发环节,有时候是生产环节,视乎你所在行业而不同。
   最重要的环节,总是 最贵的,最牛的,最得到重视的,也是最有发展前途的部门。它拥有最多的资源和最大的权威--你应该依附在这样的核心业务线上发展,至少能避免被边缘化,而成为关键人才的可能性则更大了。
      
  3.你得跟一个好老板。
      
    好老板的标准很多,关键的是,你要设法跟上一个在公司处于强势地位的老板。他强,你才能跟着上。跟了一个弱势的老板,你的前途就很同意被根着给耽搁了。
      
  二、关于具备谋取好职位的资格
  要具备怎么样的资格呢?一般情况下,你得是用人部门眼中的优秀者。
  
  
  怎么样才算优秀呢?
      
  1.对上级
      
  1)你要知道与他建立一致性,他觉得重要的事情,你就觉得重要,他认为紧急的事情你也认为紧急,你得和他劲往一处使--通常情况下,你得表现和能力好还是不好,主要是你得直接主管说了算的;
  
  2)你的具备从上级那里获得支持和资源的能力--别你干的半死,你的老板还对你爱搭不理的,那你就不具备本条件的能力。
      
  2.对下级
      
  1)要能明确有效的设置正确的工作目标,使其符合SMART原则;
  2)要能有效地管理团队内部冲突;
  3)要能公平合理地控制分配团队资源;
  4) 要有愿望和能力发展指导下属,并恰当授权;
  5)恰当的赞扬鼓励认可团队成员;
  6)尊重不同想法,分享知识经验和信息,建立信任的氛围。
      
  3.对内、外部客户
      
  1)愿意提供协助和增值服务(不然要你干嘛);
  2)善意聆听并了解需求(搞明白人家需要的到底是啥);
  3)可靠的提供产品和服务,及时跟进(千万注意及时);
  4)了解组织架构并具影响力。及早地建立并维护关键的关系,是这样的关系有利于你达成业绩(专业而明智的选择);
      
  比如你想取得一个内部职位,你的搞明白了,谁是关键的做决定的人物,别傻乎乎不小心给这个人留下坏印象。
      
  比如必要去客人那里拿订单,你找了一个关键的人物A,可是你也别忽略作购买决定环节上的另一个人物B,没准B和A是死敌,本来B会同意给你下订单的,就因为A同意给你单子,B就是不同意给你单子。
      
  4.对本岗任务
      
  1)清楚自己的定位和职责--别搞不清楚自己是谁,什么是自己的活,知道什么该报告,什么要自己独立做决定;
  2)结果导向--设立高目标,信守承诺,承担责任,注重质量、速度和期限,争取主动,无需督促;
  3)清晰的制定业务计划并有效实施;
  4)学习能力--愿意学,坚持学,及时了解行业趋势/竞争状况和技术更新,并学以致用;
  5)承受压力的能力--严峻的工作条件下,能坚忍不拔,想办法获取资源、支持和信息,努力以实现甚至超越目标;
  6)适应的能力--如适应多项要求并存,优先级变换以及情况不明等工作条件,及时调整自己的行为和风格来适应不同个人及团队的需要(工作重心会变化,老板会换人,客人也会变,别和他们说“我过去如何如何”,多去了解对方的风格) ”。

 

 

 

posted @ 2010-06-20 23:43 小强摩羯座 阅读(226) | 评论 (0)编辑 收藏

方与圆:


    最少期望的去感谢别人。不要抱着目的去感谢别人,甚至事前感谢也好。感谢只需说一次。

  发掘别人不明显的优点加以赞扬。
  赞扬行动和品性,而不要扩大到赞扬一个人。赞扬的原因要说明。


  和气生财吗?喝杯水。

  对陌生人要特别要笑。微笑是影响人气质的一个特别重要的东西。

 

  对生活的真诚,快乐的感情最能够打动人。 男的微笑也很好。

 

认真的品质:画一个月和十年。

组装的质量差?认真的态度。德国人的认真,指路会指出的很具体的。

只有最认真的人才能做出最好的产品。

 

自动自发的精神,一定要发挥自己的主观能动性。

当成自己的事来做吧。要主动的来做。


做好产品是人的一种尊严。争强好胜在自己的工作上面。因为这是你的发挥场地。

只办总裁班?成本与质量观念不一样的? 规模经济?质量了的产品成本会降低。

检查的目的是为了改进生活流程。

管制图?


困定的供货商?不是投标。是指定方式做。


永远追求持续不断的完善。

 有必要再试一次。

改进自己的产品吧。

也淘汰了自己的竞争者。 一个系列的生产方式是不错的。


到外去演讲,不做化疗?活过了三年?


要有自己的追求。活就要活出自己的价值。无论在何时的年龄,都要有自己的追求。

人生不是直线的,是C型的人生。


人生可以随时开始。

posted @ 2010-06-12 11:17 小强摩羯座 阅读(285) | 评论 (0)编辑 收藏

<设计模式:java语言中的应用>摘要、总结 收藏
<设计模式:java语言中的应用>一书已经学完,现做个摘要、总结。

创建模式(Creational Patterns)
Abstract Factory Builder
Factory Method  Prototype
Singleton

结构模式(Structural Patterns)
Adapter  Bridge
Composite Decorator
Facade  Flyweight
Proxy

行为模式(Behavioral Pattern)
Chain of Responsibility  Command
Interpreter   Iterator
Mediator   Memento
Observer   State
Strategy   Template Method
Visitor

一、创建模式(Creational Patterns)

1.Abstract Factory(抽象工厂)—把相关零件组合成产品
 Abstract Factory Pattern 是把各种抽象零件组合成抽象产品。换句话说,处理的重点是在接口(API)而不是零件的具体实现。只利用接口(API)就能把零件组合成产品.
 程序示例:
 --Main.java 测试用的类
 |-factory
 |    |-------Factory.java 表示抽象工厂的类(产生Link,Tray,Page)
 |    |-------Itme.java 用来统一处理Link和Tray的类
 |    |-------Link.java 抽象零件:表示HTML连接的类
 |    |-------Tray.java 抽象零件:抽取Link和Tray的类
 |    |-------Page.java 抽象零件:表示HTML网页的类
 |
 |-listfactory
      |-------listFactory.java 表示具体工厂的类(产生ListLink,ListTray,ListPage)
      |-------listLink.java 具体零件:表示HTML连接的类
      |-------listTray.java 具体零件:抽取Link和Tray的类
      |-------listPage.java 具体零件:表示HTML网页的类
 步骤:定义抽象零件->用抽象零件定义抽象工厂->定义具体零件(继承实现抽象零件)->定义具体工厂(继承实现抽象工厂,制造实际产品)

2.Factory Method
 Factory Method Pattern 在父类规定对象的创建方法,但并没有深入到较具体的类名.所有具体的完整内容都放在子类.根据这个原则,我们可以大致分成产生对象实例的大纲(框架)和实际产生对象实例的类两方面.
 程序示例:
 --Main.java 测试用的类
 |-framework
 |    |-------Product.java 仅定义抽象方法use的抽象类
 |    |-------Factory.java 规定createProduct,registerProduct,实现create的抽象类(类似模板方法)
 |
 |-idcard
      |-------IDCard.java 实现方法use的具体类
      |-------IDCardFactory.java 实现方法createProduct,registerProduct的类
 步骤:定义抽象产品->根据抽象产品定义抽象工厂->定义具体产品(继承实现抽象产品)->定义具体工厂(继承实现抽象工厂,制造实际产品)

3.Singleton(单件)-唯一的对象实例
 Singleton Pattern 是针对一个类而言. Singleton类只会产生1个对象实例.Singleton类把singleton定义为static字段(类变量),再以Singleton类的对象实例进行初始化.这个初始化的操作仅在加载Singleton类时进行一次.
 Singleton类的构造函数是private的,主要是为了禁止从非Singleton类调用构造函数.即使下面这个表达式不在此类之内,编译时仍然会出现错误.
  程序示例:
 |--Main.java 测试用的类
 |--Singleton.java 只有1个对象实例的类
 步骤:定义一个该类类型的static字段,同时实例化->该类的构造方法设为private->定义一个static的getInstance()方法,返回已经实例化的static字段.

4.Builder(生成器)-组合复杂的对象实例
 Builder Pattern 是采用循序渐进的方式组合较复杂对象实例的.
 程序示例:
 |--Main.java 测试用的类
 |--Builder.java 规定建立文件时的方法的抽象类
 |--Director.java 产生1个文件的类
 |--TextBuilder.java 产生plaintext格式(一般文本格式)的类
 |--HTMLBuilder.java 产生HTML格式的类
 步骤:定义建立文件时的通用方法(Builder.java)->根据通用方法组织建立文件(Director.java)->根据不同需求实现建立文件的通用方法(TextBuilder.java,HTMLBuilder.java)

5.Prototype(原型)-复制建立对象
 Prototype Pattern 不是利用类产生对象实例,而是从一个对象实例产生出另一个新对象实例.
 程序示例:
 |--Main.java 测试用的类
 |--MessageBox.java 把字符串框起来use的类.实现use和createClone
 |--UnderlinePen.java 把字符串加上下划线的类.实现use和createCone
 |--framework
      |-------Product.java 已声明抽象方法use和createClone的接口
      |-------Manager.java 利用createClone复制对象实例的类
 步骤:规定可复制产品的接口(Product.java,继承Cloneable接口)->保存可复制的产品(以Product类型存以哈西表中),并提供复制产品的方法create(调用产品的复制方法,复制工作在具体产品类中执行)(Manager.java)->定义可复制的具体产品(UnderlinePen.java,MessageBox.java,实现复制产品方法)


二、结构模式(Structural Patterns)

1.Adapter(适配器)-换个包装再度利用
 Adapter Pattern 把既有的无法直接利用的内容转换成必要的类型后再使用.具有填平"既有内容"和"需要结果"两者间"落差"的功能.
 Adapter Pattern 有继承和委托两种形式.
 程序示例:
 |--Main.java 测试用的类
 |--Banner.java 具有原始功能showWithParen,showWithAster的类
 |--Print.java 所需新功能printWeak,printStrong的接口或抽象类
 |--PrintBanner.java 把原始功能转换成新功能的类
 步骤:
 (继承)构造具有原始功能的类(Banner.java)->定义具有新功能的接口(Print.java)->转换(PrintBanner.java,继承Banner实现Print接口,即继承旧方法实现新功能)
 (委托)构造具有原始功能的类(Banner.java)->定义具有新功能的抽象类(Print.java)->转换(PrintBanner.java,继承具有新功能的Print类.定义委托对象,即原始功能类.构造时传入原始功能实例对象,新功能的实现利用委托对象的原始功能.)

2.Bridge(桥接)-分成功能层次和实现层次
 Bridge Pattern 沟通着"功能的类层次"和"实现的类层次"
 功能的类层次:给父类增加不同的功能
 实现的类层次:给父类以不同的实现
 Bridge Pattern 本质上是通过功能类(最上层的功能类)中的一个实现类(最上层的实现类,一般是抽象类)字段来桥接两个类层次的.
 程序示例:
 |--Main.java 测试用的类
 |--Display.java 功能类层次的最上层类
 |--CountDisplay.java 功能类层次的新增功能类
 |--DisplayImpl.java 实现类层次的最上层类
 |--StringDisplayImpl.java 实现类层次的实现类
 步骤:定义实现类层次的最上层类(DisplayImpl.java)->定义功能类层次的最上层类(Display.java,使用Adapter Pattern的委托方式把DisplayImpl.java的原始功能转换成Display.java的新功能)->定义功能类层次的新增功能类(CountDisplay.java)->定义实现类层次的实现类(StringDisplayImpl.java)

3.Composite(组成)-对容器和内容一视同仁
 有时候把容器和内容当作是同类来处理会比较好下手。容器里面可以是内容,也可以是更小一号的容器;而这个小一号的容器里还可以再放更小一号的容器,可以建立出像这样大套小的结构和递归结构的Pattern就是Composite Pattern
 使用Composite Pattern,容器和内容必须有一定的共性.
 程序示例:
 |--Main.java 测试用的类
 |--File.java 表示文件的类
 |--Directory.java 表示目录的类
 |--Entry.java 对File和Directory一视同仁的抽象类
 |--FileTreatmentException.java 欲在文件内新增Entry时所发生的异常类
 步骤:定义异常类(FileTreatmentException.java)->定义进入点类,即将容器和内容一视同仁的抽象类(Entry.java,容器和内容都含有共同的方法)->定义容器类和内容类(File.java,Directory.java,继承Entry,实现通用方法)

4.Decorator(装饰)-对装饰和内容一视同仁
 先建立一个核心对象,再一层层加上装饰用的功能,就可以完成符合所需的对象.可以看成是多个通用的适配器.
 程序示例:
 |--Main.java 测试用的类
 |--Display.java 打印字符串用的抽象类
 |--StringDisplay.java 只有1行的打印字符串用的类
 |--Border.java 表示"装饰外框"的抽象类
 |--SideBorder.java 只在左右加上装饰外框的类
 |--FullBorder.java 在上下左右加上装饰外框的类
 步骤:定义核心对象的抽象类(Display.java)->定义核心对象类(StringDisplay.java)->定义装饰类的抽象类(Border.java,继承核心对象的抽象类Display.java,以便装饰和内容一视同仁.装饰类中继承自核心对象抽象类的方法委托给传入的核心对象)->定义其它装饰类(SideBorder.java,FullBorder.java,继承Border.java)

5.Facade(外观)-单一窗口
 Facade Pattern 能整理错综复杂的来龙去脉,提供较高级的接口(API).Facade参与者让系统外部看到较简单的接口(API).而且Facade参与者还会兼顾系统内部各类功能和互动关系,以最正确的顺序利用类.
 Facade Pattern 把业务逻辑封装起来,只提供一个简单的接口给外部调用.
 程序示例:
 |--Main.java 测试用的类
 |--maildata.txt 邮件列表文件
 |--pagemaker
       |-------Database.java 从邮件信箱取得用户名称的类
       |-------HtmlWriter.java 产生HTML文件的类
       |-------PageMaker.java 根据邮件信箱产生用户网页的类
 步骤:定义业务逻辑需要的相关类(Database.java,HtmlWriter.java)->定义外部接口类(PageMaker.java)

6.Flyweight(享元)-有相同的部分就共享,采用精简政策
 "尽量共享对象实例,不做无谓的new".不是一需要对象实例就马上new,如果可以利用其他现有的对象实例,就让它们共享.这就是Flyweigth Pattern的核心概念.
 Flyweight Pattern 实质是把创建的占用内存量大的对象存储起来(一般用hashtable存储),后续使用时,再从hashtable取出.
 程序示例:
 |--Main.java 测试用的类
 |--BigChar.java 表示"大型字符"的类
 |--BigCharFactory.java 共享并产生BigChar的对象实例的类
 |--BigString.java 表示多个BigChar所产生的"大型文本"的类
 步骤:定义占用内存量大,需要共享的类(Display.java)->定义共享实例的类(BigCharFactory.java,共享处理在此进行,将产生的共享对象存储在哈希表中,第二次使用时从表中取出即可,不需要new)->定义共享对象组合使用类(BigString.java)

7.Proxy(代理)-需要再建立
 代理就是那个代替本来应该自己动手做事的本人的人.
 由于代理纯粹只是代理工作而已,因此能力范围也有限.如果遇到超出代理能力所及的范围,代理就应该去找本人商量才对.
 程序示例:
 |--Main.java 测试用的类
 |--Printer.java 表示命名的打印机的类(本人)
 |--Printable.java Printer和PrinterProxy共享的接口
 |--PrinterProxy.java 表示命名的打印机的类(代理)
 步骤:定义本人和代理都能处理的问题的接口(Printable.java)->建立本人类(Printer.java,实现Printable.java接口)->建立代理类(PrinterProxy.java,定义本人字段,把代理无法处理的问题交给本人)


三、行为模式(Behavioral Pattern)

1.Chain of Responsibility(职责链)-责任转送
 先对人产生一个要求,如果这个人有处理的能力就处理掉;如果不能处理的话,就把要求转送给"第二个人".同样的,如果第二个人有处理的能力时就处理掉,不能处理的话,就继续转送给"第三个人",依此类推.这就是Chain of Responsiblility Pattern.
 Chain of Responsibility Pattern 的关键在于定义转送字段(next)和定义职责链.
 程序示例:
 |--Main.java 建立Support的连锁,产生问题的测试用类
 |--Trouble.java 表示发生问题的类.内有问题编号.
 |--Support.java 解决问题的抽象类.内有转送字段和处理方法.
 |--NoSupport.java 解决问题的具体类(永远"不处理")
 |--LimitSupport.java 解决问题的具体类(解决小于指定号码的问题)
 |--OddSupport.java 解决问题的具体类(解决奇数号码的问题)
 |--SpecialSupport.java 解决问题的具体类(解决特殊号码的问题)
 步骤:建立问题类(Trouble.java)->建立解决问题的抽象类(Support.java,定义了转送字段next,设置转送字段的方法setNext和处理问题的方法support)->建立解决问题的具体类(NoSupport.java,LimitSupport.java,OddSupport.java,SpecialSupport.java,继承Support.java)->产生处理问题的对象,建立职责链

2.Command(命令)-将命令写成类
 用一个"表示命令的类的对象实例"来代表欲执行的操作,而不需采用"调用方法"的类的动态处理.如欲管理相关纪录,只需管理该对象实例的集合即可.而若预先将命令的集合存储起来,还可再执行同一命令;或者是把多个命令结合成一个新命令供再利用.
 Command Pattern 重点在于存储/使用命令
 程序示例:
 --Main.java 测试用的类
 |-command
 |    |-------Command.java 表示"命令"的接口
 |    |-------MacroCommand.java 表示"结合多个命名的命令"的类
 |
 |-drawer
      |-------DrawCommand.java 表示"点的绘制命令"的类
      |-------Drawable.java 表示"绘制对象"的接口
      |-------DrawCanvas.java 表示"绘制对象"的类
 步骤:建立命令接口(Command.java)->建立命令结合类(MacroCommand.java,将各个命令存储到一个Stack类型的字段)->建立绘制命令类(DrawCommand.java,定义绘制对象字段drawable,实现命令接口)->建立绘制对象接口(Drawable.java)->建立绘制对象类(DrawCanvas.java,实现绘制对象接口,定义命令集合字段history)->测试

3.Interpreter(解释器)-以类来表达语法规则
 Interpreter Pattern 是用简单的"迷你语言"来表现程序要解决的问题,以迷你语言写成"迷你程序"而表现具体的问题.迷你程序本身无法独自启动,必须先用java语言另外写一个负责"解释(interpreter)"的程序.解释程序能分析迷你语言,并解释\执行迷你程序.这个解释程序也称为解释器.当应解决的问题发生变化时,要修改迷你程序来对应处理.而不是修改用java语言写成的程序.
 迷你语言语法:
 <program>::=program<command list>
 <command list>::=<command>* end
 <command>::=<repeat command>|<primitive command>
 <repeat command>::=repeat<number><command list>
 <primitive command>::=go|right|left
 程序示例:
 |--Main.java 测试用的类
 |--Node.java 树状剖析中"节点"的类
 |--ProgramNode.java 对应<program>的类
 |--CommandListNode.java 对应<command list>的类
 |--CommandNode.java 对应<command>的类
 |--RepeatCommandNode.java 对应<repeat command>的类
 |--PrimitiveCommandNode.java 对应<primitive command>的类
 |--Context.java 表示语法解析之前后关系的类
 |--ParseException.java 语法解析中的例外类
 步骤:确定迷你语言的语法->建立语法解析类(Context.java,使用java.util.StringTokenizer类)->建立解析异常类(ParseException.java)->建立语法节点抽象类(Node.java,定义parse解析方法)->建立各语法节点对应的语法类(ProgramNode.java,CommandListNode.java,CommandNode.java,RepeatCommandNode.java,PrimitiveCommand.java,继承语法节点Node.java类)

4.Iterator-迭代器
 Iterator Pattern 是指依序遍历并处理多个数字或变量.
 程序示例:
 |--Main.java 测试用的类
 |--Aggregate.java 表示已聚合的类
 |--Iterator.java 执行递增\遍历的接口
 |--Book.java 表示书籍的类
 |--BookShelf.java 表示书架的类
 |--BookShelfIterator.java 扫描书架的类
 步骤:定义聚合接口(Aggregate.java)->定义遍历接口(Iterator.java)->建立具体的遍历对象类(Book.java)->建立具体的聚合类(BookShelf.java,实现聚合接口)->建立具体的遍历类(BookShelfIterator.java,实现遍历接口)

5.Mediator(中介者)-只要面对一个顾问
 每个成员都只对顾问提出报告,也只有顾问会发出指示给各个成员;成员们彼此也不会去探问目前状况如何,或乱发指示给其他成员.
 程序示例:
 |--Main.java 测试用的类
 |--Mediator.java 决定"顾问"接口(API)的接口
 |--Colleague.java 决定"成员"接口(API)的接口
 |--ColleagueButton.java 实现Colleagues接口.表示按键的类
 |--ColleagueTextField.java 实现Colleagues接口.输入文本的类
 |--ColleagueCheckbox.java 实现Colleagues接口.表示选择项目(在此为选择按钮)的类
 |--LoginFrame.java 实现Mediator接口.表示登录对话框的类
 步骤:定义顾问接口(Mediator.java)->定义成员接口(Colleague.java)->建立具体的成员类(ColleagueButton.java,ColleagueTextField.java,ColleagueCheckbox.java,实现成员接口)->建立具体的顾问类(LoginFrame.java,实现顾问接口)

6.Memento(备忘录)-存储状态
 Memento Pattern 会把某个时间点的对象实例状态记录存储起来,等到以后再让对象实例复原到当时的状态.
 程序示例:
 |--Main.java 进行游戏的类.先把Memento的对象实例存储起来,如有必要时再复原Gamer的状态
 |--game
     |-------Gamer.java 玩游戏的主人翁的类
     |-------Memento.java 表示Gamer状态的类.产生Memento的对象实例
 步骤:建立需要存储状态的类(Gamer.java)->建立状态类(Memento.java,状态类与需要存储状态的类Gamer.java应具有相同的必要字段)

7.Observer(观察者)-通知状态变化
 当被Observer Pattern 列入观察名单的状态发生变化,就会通知观察者.在写一些跟状态变化有关的处理时,Observer Pattern是很好用的工具.
 程序示例:
 |--Main.java 测试用的类
 |--Observer.java 表示观察者的接口
 |--NumberGenerator.java 表示产生数值对象的抽象类
 |--RandomNumberGenerator.java 产生随机数的类
 |--DigitObserver.java 以数字表示数值的类
 |--GraphObserver.java 以简易长条图表示数值的类
 步骤:定义观察者接口(Observer.java)->建立被观察的类(NumberGenerator.java,RandomNumberGenerator.java,定义观察者结合字段将观察者存储起来)->建立具体的观察者类(DigitObserver.java,GraphObserver.java,实现观察者接口)

8.State(状态)-以类表示状态
 以类来表示状态之后,只要切换类就能表现“状态变化”,而且在必须新增其他状态时,也很清楚该编写哪个部分。
 程序示例:
 |--Main.java 测试用的类
 |--State.java 表示金库状态的接口
 |--DayState.java 实现State的类。表示白天的状态
 |--NightState.java 实现State的类。表示夜间的状态
 |--Context.java 管理金库的状态变化,跟保安中心联络的接口
 |--SafeFrame.java 实现Context的类。含有按钮、画面显示等的用户接口
 步骤:定义状态接口(State.java,将使用State Pattern之前各种行为方法抽象出来)->建立具体的状态类(DayState.java,NightState.java,实现状态接口,状态变化的具体动作在这里执行)->定义管理状态变化的接口(Context.java,规定状态变化及相关的调用方法)->建立状态管理类(SafeFrame.java,实现状态管理接口)

9.Strategy(策略)-把算法整个换掉
 在Strategy Pattern之下,可以更换实现算法的部分而且不留痕迹。切换整个算法,简化改为采用其他方法来解决同样的问题。
 程序示例:
 |--Main.java 测试用的类
 |--Hand.java 表示猜拳“手势”的类
 |--Strategy.java 表示猜拳“战略”的接口
 |--WinningStrategy.java 表示猜赢之后继续出同样招式的战略的类
 |--ProbStrategy.java 表示从上一次出的招式,以概率分配方式求出下一个招式机率的类
 |--Player.java 表示玩猜拳的游戏者的类
 步骤:定义策略接口(Strategy.java)->建立具体的策略类(WinningStrategy.java,ProbStrategy.java,实现策略接口)->建立使用策略的类(Player.java,定义策略字段,以便使用切换策略)->建立其它类(Main.java,Hand.java)

10.Template Method(模板方法)-实际处理交给子类
 在父类指定处理大纲、在子类规定具体内容的Design Pattern就称为Template Method Pattern
 程序示例:
 |--Main.java 测试用的类
 |--AbstractDisplay.java 只实现方法display的抽象类
 |--CharDisplay.java 实现方法open,print,close的类
 |--StringDisplay.java 实现方法open,print,close的类
 步骤:定义模板类(AbstractDisplay.java,实现dispaly方法,即制作了模板)->建立具体内容类(CharDisplay.java,StringDisplay.java,继承模板类,实现模板类没有实现的方法)

11.Visitor(访问者)-在结构中穿梭还同时做事
 Visitor Pattern 把数据结构和处理两者分开,另外写一个表示在数据结构内穿梭来去的主体“访客”的类,然后把处理交给这个类来进行。如此一来,如果想追加新的处理行为时,只要再建立一个新的“访客”即可。而在数据结构这边,也只要能接受来敲门的“访客”就能完成动作。
 在父类指定处理大纲、在子类规定具体内容的Design Pattern就称为Template Method Pattern
 程序示例:
 |--Main.java 测试用的类
 |--Visitor.java 表示访问文件或目录的访客的抽象类
 |--Acceptor.java 表示接受Visitor类的对象实例的数据结构的接口
 |--ListVisitor.java Visitor类的子类,打印文件和目录信息的类
 |--Entry.java File和Directory的父类的抽象类(实现Acceptor接口)
 |--File.java 表示文件的类
 |--Directory.java 表示目录的类
 |--FileTreatmentException.java 发生在对File进行add时的例外类
 步骤:定义访问者的抽象类(Visitor.java,定义访问方法)->定义受访者接口(Acceptor.java,定义接受访问的方法)->建立具体的访问者类(ListVisitor.java,继承访问者抽象类,实现访问方法)->建立具体的受访者类(Entry.java,File.java,Directory.java,实现受访者接口)->编写异常类(FileTreatmentException.java)

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/pian_yun/archive/2007/09/14/1784981.aspx

posted @ 2010-05-28 16:24 小强摩羯座 阅读(357) | 评论 (0)编辑 收藏

直接在html中使用xml导入数据

<xml id="cdcat" src="cd_catalog.xml"></xml>
<table border="1" datasrc="#cdcat">
  <tr>
    <td><span datafld="ARTIST"></span></td>
    <td><span datafld="TITLE"></span></td>
      <td datafld="price"> </td>
 <td><span datafld="year"></span></td>
  </tr>
</table>


注意可以引入xml字段的元素有 限:
例如,与DIV元素绑定的代码如下:
 d: U) f1 y
  注意:并非所有的HTML元素都能与XML数据岛绑定。目前,支持这种DSO绑定机制的元素如下:. H2 V- _% j! E/ {4 i
$ \( \$ l" b+ H( M& Y
  A、APPLET、BUTTON、DIV、FRAME、IFRAME、 IMG、INPUT (此处类型是:CHECKBOX、HIDDEN、 LABEL、PASSWORD、RADIO和TEXT)、LABEL、 MARQUEE、SELECT、SPAN、TABLE和 TEXTAREA。

posted @ 2010-05-27 10:24 小强摩羯座 阅读(538) | 评论 (0)编辑 收藏

H.264中的NAL技术

NAL技术

1.NAL概述
NAL全称Network Abstract Layer, 即网络抽象层。
在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。
现实中的传输系统是多样化的,其可靠性,服务质量,封装方式等特征各不相同,NAL这一概念的提出提供了一个视频编码器和传输系统的友好接口,使得编码后的视频数据能够有效地在各种不同的网络环境中传输。

2.NAL单元
NAL单元是NAL的基本语法结构,它包含一个字节的头信息和一系列来自VCL的称为原始字节序列载荷(RBSP)的字节流。头信息中包含着一个可否丢弃的指示标记,标识着该NAL单元的丢弃能否引起错误扩散,一般,如果NAL单元中的信息不用于构建参考图像,则认为可以将其丢弃;最后包含的是NAL单元的类型信息,暗示着其内含有效载荷的内容。
送到解码器端的NAL单元必须遵守严格的顺序,如果应用程序接收到的NAL单元处于乱序,则必须提供一种恢复其正确顺序的方法。

3.NAL实现编解码器与传输网络的结合
NAL提供了一个编解码器与传输网络的通用接口,而对于不同的网络环境,具体的实现方案是不同的。对于基于流的传输系统如H.320、MPEG等,需要按照解码顺序组织NAL单元,并为每个NAL单元增加若干比特字节对齐的前缀以形成字节流;对于RTP/UDP/IP系统,则可以直接将编码器输出的NAL单元作为RTP的有效载荷;而对于同时提供多个逻辑信道的传输系统,我们甚至可以根据重要性将不同类型的NAL单元在不同服务质量的信道中传输[2]。

4.结论
为了实现编解码器良好的网络适应性,需要做两方面的工作:第一、在Codec中将NAL这一技术完整而有效的实现;第二、在遵循H.264/AVC NAL规范的前提下设计针对不同网络的最佳传输方案。如果实现了以上两个目标,所实现的就不仅仅是一种视频编解码技术,而是一套适用范围很广的多媒体传输方案,该方案适用于如视频会议,数据存储,电视广播,流媒体,无线通信,远程监控等多种领域。

NALU类型

标识NAL单元中的RBSP数据类型,其中,nal_unit_type为1, 2, 3, 4, 5及12的NAL单元称为VCL的NAL单元,其他类型的NAL单元为非VCL的NAL单元。

0:未规定
1:非IDR图像中不采用数据划分的片段
2:非IDR图像中A类数据划分片段
3:非IDR图像中B类数据划分片段
4:非IDR图像中C类数据划分片段
5:IDR图像的片段
6:补充增强信息 (SEI)
7:序列参数集
8:图像参数集
9:分割符
10:序列结束符
11:流结束符
12:填充数据
13 – 23:保留
24 – 31:未规定

NALU的顺序要求

H.264/AVC标准对送到解码器的NAL单元顺序是有严格要求的,如果NAL单元的顺序是混乱的,必须将其重新依照规范组织后送入解码器,否则解码器不能够正确解码。

1.序列参数集NAL单元必须在传送所有以此参数集为参考的其他NAL单元之前传送,不过允许这些NAL单元中间出现重复的序列参数集NAL单元。所谓重复的详细解释为:序列参数集NAL单元都有其专门的标识,如果两个序列参数集NAL单元的标识相同,就可以认为后一个只不过是前一个的拷贝,而非新的序列参数集。
2.图像参数集NAL单元必须在所有以此参数集为参考的其他NAL单元之先,不过允许这些NAL单元中间出现重复的图像参数集NAL单元,这一点与上述的序列参数集NAL单元是相同的。
3.不同基本编码图像中的片段(slice)单元和数据划分片段(data partition)单元在顺序上不可以相互交叉,即不允许属于某一基本编码图像的一系列片段(slice)单元和数据划分片段(data partition)单元中忽然出现另一个基本编码图像的片段(slice)单元片段和数据划分片段(data partition)单元。
4.参考图像的影响:如果一幅图像以另一幅图像为参考,则属于前者的所有片段(slice)单元和数据划分片段(data partition)单元必须在属于后者的片段和数据划分片段之后,无论是基本编码图像还是冗余编码图像都必须遵守这个规则
5.基本编码图像的所有片段(slice)单元和数据划分片段(data partition)单元必须在属于相应冗余编码图像的片段(slice)单元和数据划分片段(data partition)单元之前。
6.如果数据流中出现了连续的无参考基本编码图像,则图像序号小的在前面。
7.如果arbitrary_slice_order_allowed_flag置为1,一个基本编码图像中的片段(slice)单元和数据划分片段(data partition)单元的顺序是任意的,如果arbitrary_slice_order_allowed_flag置为零,则要按照片段中第一个宏块的位置来确定片段的顺序,若使用数据划分,则A类数据划分片段在B类数据划分片段之前,B类数据划分片段在C类数据划分片段之前,而且对应不同片段的数据划分片段不能相互交叉,也不能与没有数据划分的片段相互交叉。
8.如果存在SEI(补充增强信息) 单元的话,它必须在它所对应的基本编码图像的片段(slice)单元和数据划分片段(data partition)单元之前,并同时必须紧接在上一个基本编码图像的所有片段(slice)单元和数据划分片段(data partition)单元后边。假如SEI属于多个基本编码图像,其顺序仅以第一个基本编码图像为参照。
9.如果存在图像分割符的话,它必须在所有SEI 单元、基本编码图像的所有片段slice)单元和数据划分片段(data partition)单元之前,并且紧接着上一个基本编码图像那些NAL单元。
10.如果存在序列结束符,且序列结束符后还有图像,则该图像必须是IDR(即时解码器刷新)图像。序列结束符的位置应当在属于这个IDR图像的分割符、SEI 单元等数据之前,且紧接着前面那些图像的NAL单元。如果序列结束符后没有图像了,那么它的就在比特流中所有图像数据之后。
11.流结束符在比特流中的最后。

 

本文来自CSDN博客,转载请标明出处:file:///D:/新建文件夹/桌面/H_264中的NAL技术%20-%20Bolt%20的专栏%20-%20CSDN博客.htm

posted @ 2010-05-06 17:58 小强摩羯座 阅读(323) | 评论 (0)编辑 收藏

生成zigzag序,
1、分析关键,在以zigzag序的每一行,以上三角为计算对象分别以i或j的增序排列,因此利用这一点就可以得出结果。
    程序中s即为zigzag行号,而变换则以i和j交替。所以程序很简单。

 

#include<iostream>
#include<iomanip>

using namespace std;

#define M 255

void zigzag(const int N)
{
    int squa = N * N;
    int a[M][M]={0};
    for (int i = 0;i < N; i++)
    {
        for (int j = 0;j < N;j++)
        {
            int s = i + j;
            if ( s < N)
            {
                 a[i][j] = s * (s+1)/2 + ( (s %2 !=0)?i:j);//注意?:的优先级低于+
            }
            else
            {
                int sn = (N-1-i) + (N-1-j);
                a[i][j] = squa - sn * (sn+1)/2 - (N - ( (sn%2 != 0)? i:j));
            }
        }
    }

    for (int i=0; i < N; i++)
    {
        for (int j = 0;j < N;j++)
        {

            cout<<setw(4)<<a[i][j]<<",";
        }
        cout<<endl<<endl;
    }
}

int main()
{
 zigzag(5);
 cout<<endl;
 
 zigzag(8);
 cout<<endl;

    return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void zigzag(int n)
{
int **a =(int**) malloc(n*sizeof(int *)); //分配空间

if(NULL == a)
return ;
int i;
for(i = 0; i < n; i++) {
        if((a[i] =(int*) malloc(n * sizeof(int))) == NULL) {
            while(--i>=0)
                free(a[i]);
            free(a);
            return;
        }
    }

bool flag = false; //这个标志位用来判断是从45度角生成还是225度角生成
int count = 0;
for(i=0; i<n; i++) //生成的上半部分的数据
{

if(flag)
{
   for(int r = 0; r<=i; r++)
   {
    a[r][i-r] = count;
    count++;
   }
   flag = false;
}
else
{
   for(int r = i; r>=0; r--)
   {
    a[r][i-r] = count;
    count++;
   }
   flag = true;
}
}
for(i=n-1; i>=0; i--) //生成的是下半部分的数据
{
// cout<<i<<endl;
if(flag)
{
   for(int r = 0; r<=i-1; r++)
   {
    int r1 = n-i+r;       //代表当前行
    int c1 = 2*n-i-1-r1; //代表当前列
    a[r1][c1] = count;
    count++;
   }
   flag = false;
}
else
{
   for(int r = i-1; r>=0; r--)
   {
    cout<<"ddd"<<endl;
    int r1 = n-i+r;
    int c1 = 2*n-i-1-r1;
//   cout<<r1<<","<<c1<<endl;
    a[r1][c1] = count;
    count++;
   }
   flag = true;
}
}
for(int r = 0; r<n; r++)
{
for(int c=0; c<n; c++)
   cout<<a[r][c]<<",";
cout<<endl;
}
}
int main()
{
int n;
cin>>n;
zigzag(n);
return 0;
}
网上还有一个人写了一个比较巧的算法:
/**
* 得到如下样式的二维数组
* zigzag(jpeg编码里取象素数据的排列顺序)
*
*   0, 1, 5, 6,14,15,27,28,
*   2, 4, 7,13,16,26,29,42,
*   3, 8,12,17,25,30,41,43,
*   9,11,18,24,31,40,44,53,
*   10,19,23,32,39,45,52,54,
*   20,22,33,38,46,51,55,60,
*   21,34,37,47,50,56,59,61,
*   35,36,48,49,57,58,62,63
*/

#include <stdio.h>
int main()
{
    int N;
    int s, i, j;
    int squa;
    scanf("%d", &N);
    /* 分配空间 */
    int **a = malloc(N * sizeof(int *));
    if(a == NULL)
        return 0;
    for(i = 0; i < N; i++) {
        if((a[i] = malloc(N * sizeof(int))) == NULL) {
            while(--i>=0)
                free(a[i]);
            free(a);
            return 0;
        }
    }
    /* 数组赋值 */
    squa = N*N;   
    for(i = 0; i < N; i++)
        for(j = 0; j < N; j++) {
            s = i + j;
            if(s < N)
                a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? i : j);
            else {
                s = (N-1-i) + (N-1-j);
                a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? i : j));
            }
        }
    /* 打印输出 */   
    for(i = 0; i < N; i++) {
        for(j = 0; j < N; j++)
            printf("%-6d", a[i][j]);
        printf("\n");
    }
    return 0;
}

posted @ 2010-05-03 17:26 小强摩羯座 阅读(265) | 评论 (0)编辑 收藏

几道面试笔试题
2008-02-26 18:38

一、如何判断一个单链表是有环的?(注意不能用标志位,最多只能用两个额外指针)
   struct node { char val; node* next;}
   bool check(const node* head) {} //return false : 无环;true: 有环
    一种O(n)的办法就是(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然):
    bool check(const node* head)
    {
         if(head==NULL)
              return false;  
         node *low=head, *fast=head->next;
         while(fast!=NULL && fast->next!=NULL)
        {
               low=low->next;
               fast=fast->next->next;
               if(low==fast)
                    return true;
        }
       return false;
   }

二、删除一个单项链表的最中间的元素,要求时间尽可能短(不能使用两次循环)
struct link
{
    int data;
    struct link *next;
};
void delMiddle(link *head)
{
    if(head == NULL)
           return;
    else if(head->next == NULL)
    {
            delete head;
            return;
    }
    else
    {
            link *low = head;
            link *fast = head->next;
            while(fast != NULL && fast->next != NULL)
            {  
                       fast = fast->next->next;
                       if(fast == NULL)
                                    break;
                       low = low->next;
            }
            link *temp = low->next;
            low->next = low->next->next;
            delete temp;

    }
}
int main()
{
       struct link *head,*l;
       struct link *s;
       head = (link*)malloc(sizeof(link));
       head->data=0;
       head->next = NULL;
       l = head;
       for(int i=1; i<9; i++)
       {
            s = (link*)malloc(sizeof(link));
            s->data = i;
            s->next = NULL;
            l->next= s;
            l = l->next;
       }
       print(head);
       delMiddle(head);
       print(head);
       return 0;
}

三、输入n,求一个n*n矩阵,规定矩阵沿45度线递增(威盛)
/**
* 得到如下样式的二维数组
* zigzag(jpeg编码里取象素数据的排列顺序)
*
*   0, 1, 5, 6,14,15,27,28,
*   2, 4, 7,13,16,26,29,42,
*   3, 8,12,17,25,30,41,43,
*   9,11,18,24,31,40,44,53,
*   10,19,23,32,39,45,52,54,
*   20,22,33,38,46,51,55,60,
*   21,34,37,47,50,56,59,61,
*   35,36,48,49,57,58,62,63
*/
void zigzag(int n)
{
int **a =(int**) malloc(n*sizeof(int *)); //分配空间

if(NULL == a)
return ;
int i;
for(i = 0; i < n; i++) {
        if((a[i] =(int*) malloc(n * sizeof(int))) == NULL) {
            while(--i>=0)
                free(a[i]);
            free(a);
            return;
        }
    }

bool flag = false; //这个标志位用来判断是从45度角生成还是225度角生成
int count = 0;
for(i=0; i<n; i++) //生成的上半部分的数据
{

if(flag)
{
   for(int r = 0; r<=i; r++)
   {
    a[r][i-r] = count;
    count++;
   }
   flag = false;
}
else
{
   for(int r = i; r>=0; r--)
   {
    a[r][i-r] = count;
    count++;
   }
   flag = true;
}
}
for(i=n-1; i>=0; i--) //生成的是下半部分的数据
{
// cout<<i<<endl;
if(flag)
{
   for(int r = 0; r<=i-1; r++)
   {
    int r1 = n-i+r;       //代表当前行
    int c1 = 2*n-i-1-r1; //代表当前列
    a[r1][c1] = count;
    count++;
   }
   flag = false;
}
else
{
   for(int r = i-1; r>=0; r--)
   {
    cout<<"ddd"<<endl;
    int r1 = n-i+r;
    int c1 = 2*n-i-1-r1;
//   cout<<r1<<","<<c1<<endl;
    a[r1][c1] = count;
    count++;
   }
   flag = true;
}
}
for(int r = 0; r<n; r++)
{
for(int c=0; c<n; c++)
   cout<<a[r][c]<<",";
cout<<endl;
}
}
int main()
{
int n;
cin>>n;
zigzag(n);
return 0;
}
网上还有一个人写了一个比较巧的算法:
/**
* 得到如下样式的二维数组
* zigzag(jpeg编码里取象素数据的排列顺序)
*
*   0, 1, 5, 6,14,15,27,28,
*   2, 4, 7,13,16,26,29,42,
*   3, 8,12,17,25,30,41,43,
*   9,11,18,24,31,40,44,53,
*   10,19,23,32,39,45,52,54,
*   20,22,33,38,46,51,55,60,
*   21,34,37,47,50,56,59,61,
*   35,36,48,49,57,58,62,63
*/

#include <stdio.h>
int main()
{
    int N;
    int s, i, j;
    int squa;
    scanf("%d", &N);
    /* 分配空间 */
    int **a = malloc(N * sizeof(int *));
    if(a == NULL)
        return 0;
    for(i = 0; i < N; i++) {
        if((a[i] = malloc(N * sizeof(int))) == NULL) {
            while(--i>=0)
                free(a[i]);
            free(a);
            return 0;
        }
    }
    /* 数组赋值 */
    squa = N*N;   
    for(i = 0; i < N; i++)
        for(j = 0; j < N; j++) {
            s = i + j;
            if(s < N)
                a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? i : j);
            else {
                s = (N-1-i) + (N-1-j);
                a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? i : j));
            }
        }
    /* 打印输出 */   
    for(i = 0; i < N; i++) {
        for(j = 0; j < N; j++)
            printf("%-6d", a[i][j]);
        printf("\n");
    }
    return 0;
}


四、打印1到1000的整数,不能使用流程控制语句(for,while,goto等)也不能使用递归
1.
typedef struct _test{
    static int a;
    _test(){
        printf("%d\n",_test::a);
        a++;
    }
}Test;
int Test::a = 1;

int   main()  
{  
    Test tt[1000];
    return 0;
}  
2.
#include   <stdio.h>
#define   B   P,P,P,P,P,P,P,P,P,P
#define   P   L,L,L,L,L,L,L,L,L,L
#define   L   I,I,I,I,I,I,I,I,I,I,N
#define   I   printf( "%3d   ",i++)
#define   N   printf( "\n ")
int main()
{
    int   i   =   1;
    B;
}

#define A(x) x;x;x;x;x;x;x;x;x;x;
int main ()
{
    int n = 1;
    A(A(A(printf ("%d ", n++))));

    return 0;
}

 

五、struct   S   {
        int   i;
        int   *   p;
};
void   main()
{
        S   s;
        int   *   p   =   &s.i;
        p[0]   =   4;
        p[1]   =   3;
        s.p   =   p;
        s.p[1]   =   1;
        s.p[0]   =   2;
}
问程序会在哪一行死掉。 (microsoft)
解: S   s;
         int   *   p   =   &s.i;        //s.i的地址存储在p里
        p[0]   =   4;                    //修改了s.i
         p[1]   =   3;                    //修改了s.p
         s.p   =   p;                    //s.p指向s.i
         s.p[1]   =   1;               //修改s.p本身
        s.p[0]   =   2;               //s.p指向的是0x00000001,尝试向这里写,出错
     s.p[0]       =       2;   时出错
     因为s.p存的是s.i的地址,s.p[1]为s.p,当s.p[1]=1时,s.p此时存放的是1了,而不是地址s.i,故在s.p[0]   =   2时出错.
此时相当于s.p=ox00000001;地址ox0000001   =   2;当然就出错了

如果语句s.p[0]   =2   先于s.p[1]=1则程序就不会出错.此时语句相当于s.i=2;s.p=1;


六、题目描述:
1.   int   swap(int   *x,int   *y)
{
    if(x==NULL   | |   y==NULL)
        return   -1;
    *x   +=   *y;
    *y   =   *x-   *y;
    *x   -=   *y;
      return   1;
}
请改错,溢出已经考虑,不是错误
2.
void   foo(int   *x,   int   *y)
{
    *x   +=   *y;
    *x   +=   *y;
}
void   fun(int   *x,   int   *y)
{  
    *x   +=   2   *   (*y);
}
问两个函数是否等价,能否互换
解答:第一题的函数是交换。但假如考虑x,   y都是指向同一个变量,结果是这个变量的值为0.
第二题的两个函数是有区别的,也考虑x,y是指向同一个变量.这样第一个函数的结果是这个变量的4倍.但第二个函数的结果是变量的3倍.

posted @ 2010-05-03 17:25 小强摩羯座 阅读(143) | 评论 (0)编辑 收藏

C++ placement new 用法举例zz
2009-12-17 16:16

在处理内存分配的时候,C++程序员会用new操作符(operator new)来分配内存,并用delete操作符(operator delete)来释放内存。这是一个new操作符的例子。

class CTest
{
     
/* 成员函数和成员数据 */
};

// . . . 代码

//
分配一个对象
CTest * pTest = new Test;
// 分配一个有十个对象的数组 (CTest 要有缺省构造函数(default constuctor)
CTest * p10Tests = new Test[ 10];

虽然这种写法在大多数时候都工作得很好,但还是有些情况下使用new是很烦人的,比如当你想重新分配一个数组或者当你想在预分配的内存上构造一个对象的时候。

比如第一种情况,重新分配一个数组效率是很低的:

// 分配一个有10个对象的数组
CTest * pTests = new Test[ 10];
// . . .
//
假设现在我们需要11个对象
CTest * pNewTests = new Test[ 11];
// . . . 我们必须把原来的对象拷贝到新分配的内存中
for ( int i = 0; i < 10; i++)
     pNewTests[ i] = pTests[ i];
delete pTests;
pTests = pNewTests;

如果你想在预分配的内存上创建对象,用缺省的new操作符是行不通的。要解决这个问题,你可以用placement new构造。它允许你构造一个新对象到预分配的内存上:

// buffer 是一个void指针 (void *)
//
用方括号[] 括起来的部分是可选的
[CYourClass * pValue = ] new( buffer) CYourClass[( parameters)];

下面是一些例子:

#include <new>

class CTest
{
public:
     CTest()
     {}
     CTest( int)
     {}
    
/* 代码*/
};

int main(int argc, char* argv[])
{

     //
由于这个例子的目的,我们不考虑内存对齐问题
     char strBuff[ sizeof( CTest) * 10 + 100];
     CTest * pBuffer = ( CTest *)strBuff;

    
// 缺省构造
     CTest * pFirst = new(pBuffer) CTest;

    
// 缺省构造
     CTest * pSecond = new(pBuffer + 1) CTest;
    
    
// 带参数的构造;
     //
不理会返回的指针
     new(pBuffer + 2) CTest( 5);

    
// 带参数的构造
     CTest * pFourth = new( pBuffer + 3) CTest( 10);

    
// 缺省构造
     CTest * pFifth = new(pBuffer + 4) CTest();

    
// 构造多个元素(缺省构造)
     CTest * pMultipleElements = new(pBuffer + 5) CTest[ 5];
     return 0;
}

当你有自己的内存缓冲区或者在你实现自己的内存分配策略的时候,placement new会很有用。事实上在STL中广泛使用了placement new来给容器分配内存;每个容器类都有一个模版参数说明了构造/析构对象时所用的分配器(allocator)。

在使用placement new的时候,你要记住以下几点:

  • 加上头文件#include <new>
  • 你可以用placement new构造一个数组中的元素。
  • 要析构一个用placement new分配的对象,你应该手工调用析构函数(并不存在一个“placement delete”)。它的语法如下:

pFirst->~CTest();
pSecond->~CTest();

前段事件,我问过关于placement new的问题,一位仁兄讲了一些道理,他说道:

::栈上的对象(注意,是类对象,char类型就无需了,后面还会提到)保证放在对齐地址上. 

但是,个人实验了一下,发现并不是这样

例如:
int main()
{
char c1 = 'A' ;
char c2 = 'B' ;
char c3 = 'C' ;
char c4 = 'D' ;
char c5 = 'E' ;

//-------- 验证这四个地址是否是 4 的倍数 --------------//
if ( ((int)(&c1)) % 4 == 0 )
cout << "c1:Yes" << endl ;

if ( ((int)(&c2)) % 4 == 0 )
cout << "c2:Yes" << endl ;

if ( ((int)(&c3)) % 4 == 0 )
cout << "c3:Yes" << endl ;

if ( ((int)(&c4)) % 4 == 0 )
cout << "c4:Yes" << endl ;

if ( ((int)(&c5)) % 4 == 0 )
cout << "c5:Yes" << endl ;

cout << (int)(&c1) << endl // 输出四个字符所在的地址(输出结果都是 4 的倍数)
 << (int)(&c2) << endl 
 << (int)(&c3) << endl 
 << (int)(&c4) << endl 
 << (int)(&c5) << endl ;
}
-----------------------------
上面的执行结果在VC下运行都是 4 的倍数
--------------

--> 问题1:连栈上分配的空间地址都是 4 的倍数,那就说明系统分配的空间都是 4 的倍数吧???

--> 问题2:如果万一,如果放一个对象的地址不是4的倍数,那么会出现什么情况??可以给简单说一下吗?

--> 问题3:地址对齐的通用性???
   -------------
   程序1:
Class C1
{
int i ;
char c ;
} ;
cout << sizeof(C1) << endl ;// 输出结果: 8 (是 4 的倍数)
   程序2:
class C2
{
char c1 ;
char c2 ;
} ;
cout << sizeof(C2) << endl ;// 输出结果:2 ( 上一个中char类型也给了4个字节,怎么这个地方都给了一个字节??)
--> 问题4:由上面的程序2 引出下面的程序
class C2// sizeof(C2) =2 ,在VC实验下的结果,不是 4
{
char c1 ;
char c2 ;
} ;
//----------用placement new方法建立对象----------------
void *ptr = operator new(100) ;// 分配内存
C2 *POINTER = (C2*)ptr ;// 类型转换
String *str1 = new (POINTER) C2() ;// 建立一C2对象
String *str2 = new (POINTER+1) C2() ;// 再建立一个对象
String *str3 = new (POINTER+2) C2() ;// 再建立一个对象

cout << (int)(str1) << endl// 结果:3608720(  是4的倍数)
      << (int)(str2) << endl // 结果:3608722(不是4的倍数)!!
                     << (int)(str3) << endl ;// 结果:3608724(不是4的倍数)!!

posted @ 2010-04-20 17:15 小强摩羯座 阅读(3793) | 评论 (0)编辑 收藏

很实用的word的高级用法总汇2009-04-23 16:26

 

任意放大/变小 字体

快捷键ctrl+] 放大 字体      ctrl+[ 缩小字体

把文字替换成图片
首先把图片复制到 剪贴板中,然后打开替换对话框,在“查找内容”框中输入将被替换的文字,接着在 “替换为”框中输入“^c”(注意:输入的一定要是半角字符,c要小写),单击替换 即可。说明:“^c”的意思就是指令Word XP以剪贴板中的内容替换“查找内容”框中的内 容。按此原理,“^c”还可替换包括回车符在内的任何可以复制到剪贴板的可视内容,甚至Excel表格。

三招去掉页眉那条横线
1、在页眉中,在“格式”-“边框和底纹”中设置表格和边框为“无”,应用于“段落”
2、同上,只是把边框的颜色设置为白色(其实并没有删的,只是看起来没有了,呵呵)
3、在“样式”栏里把“页眉”换成“正文”就行了——强烈推荐!
会多出--(两个横杠) 这是用户不愿看到的,又要多出一步作删除--
解决方法:替换时在前引号前加上一个空格 问题就解决了

插入日期和时间的快捷键
Alt+Shift+D:当前日期
Alt+Shift+T:当前时间

批量转换全角字符为半角字符
首先全选。然后“格式”→“更改大小写”,在对话框中先选中“半角”,确定即可


Word启动参数简介
单击“开始→运行”命令,然后输入Word所在路径及参数确定即可运行,如“C:\ PROGRAM FILES \MICROSOFT Office \Office 10\ WINWord.EXE /n”,这些常用的参数及功能如下:
/n:启动Word后不创建新的文件。
/a:禁止插件和通用模板自动启动。
/m:禁止自动执行的宏。
/w:启动一个新Word进程,独立与正在运行的Word进程。
/c:启动Word,然后调用Netmeeting。
/q:不显示启动画面。
另外对于常需用到的参数,我们可以在Word的快捷图标上单击鼠标右键,然后在“目标”项的路径后加上该参数即可。

快速打开最后编辑的文档
如果你希望Word在启动时能自动打开你上次编辑的文档,可以用简单的宏命令来完成:
(1)选择“工具”菜单中的“宏”菜单项,单击“录制新宏”命令打开“录制宏”对话框;
(2)在“录制宏”对话框中,在“宏名”输入框中输入“autoexec”,点击“确定”;
(3)从菜单中选择“文件”,点击最近打开文件列表中显示的第一个文件名;并“停止录制”。保存退出。下次再启动Word时,它会自动加载你工作的最后一个文档。

格式刷的使用
1、设定好文本1的格式。
2、将光标放在文本1处。
3、单击格式刷按钮。
4、选定其它文字(文本2),则文本2的格式与文本1 一样。
若在第3步中单击改为双击,则格式刷可无限次使用,直到再次单击格式刷(或按Esc键)为止。

删除网上下载资料的换行符(象这种“↓”)
在查找框内输入半角^l(是英文状态下的小写L不是数字1),在替换框内不输任何内容,单击全部替换,就把大量换行符删掉啦。

选择性删除文件菜单下的最近使用的文件快捷方式。
工具→选项→常规把“列出最近使用文件数改为0”可以全部删除,若要选择性删除,可以按ctrl+Alt+ -三个键,光标变为一个粗减号后,单击文件,再单击要删除的快捷方式就行了。

建立一个矩形选区:
一般的选区建立可用鼠标左键,或用shift键配合pgup、pgdn、home、end、箭头等功能键,当复制一个规则的矩形区域时,可先按住Alt键,然后用鼠标左键来选。我一般用此来删除段首多余的成块的空格。大家试一试*^_^*

将字体快速改为上标或下标的方法:
本人在一次无意间发现了这个方法,选定你要下标的字,然后在英文状态下按住Ctrl,再按一下BASKSPACE旁的+/=的键,就可以了。上标只要在按Ctrl的同时也按住Shift,大家可以试试。

让Word表格快速一分为二
将光标定位在分开的表格某个位置上,按下“Ctrl+Shift+Enter”组合键。这时你就会发现表格中间自动插入一个空行,这样就达到了将一个表格一分为二的目的。

用Word来拆字
首先点击“工具/自定义/命令/分解图片”,按住鼠标左键把它拖放到工具栏任意位置即可;然后点击“插入/图片/艺术字”,例如输入空心字“心”,选择该“心”字剪切,在选择性粘贴中选图片(Windows图元文件),选中该字,点击工具栏中的“分解图片”按钮,这样可以选择“心”中的任意笔画进行一笔一画的拆分了。

快速删除段前段后的任意多个空格
选定这些段段落,单击居中按钮,然后再单击原来的那种对齐方式按钮(如果原来是居中对齐的,先单击其它对齐方式按钮,再单击居中按钮就行了),是不是这些空格全不见了?


只要打开WORD新建一个空文档的时候,出现的不是空的文档,而是我以前打的一份文档
首先:将资源管理器设置为显示所有文件和文件夹;
然后:
C:\Documents and Settings\Administrator\Application Data\Microsoft\Templates文件夹下将所有Normal.doc文件删掉;
然后:OK(XP系统)

快速输入平方的方法
先输入2,然后选重后,按ctrl加shift加+就可以了.

WORD中表格的选择性录入
1.设置好表格,选定表格-视图-工具-窗体-插入下拉型窗体域
2.输入数据,完成
3.点击锁按钮,保护,输入完后再点击进行其它的输入.

标点符号的全角/半的转换用:Ctrl+.
数字字母的全角/半的转换用:Shift+空格

轻松了解工具栏按钮的作用
按下“shift+F1”键,鼠标指针旁多了一个“?”号,想知道哪个按钮
的作用,就用鼠标单击哪个。

要经常在文档中插入自己公司的信息
公司名称
公司住址
联系电话
联系人姓名
QQ号码
可以先选定这些内容,再单击工具→自动更正→在替换框中输入标记名称(如“公司信息”)→添加→确定,以后凡是在文档中要用到这个信息的地方键入“公司信息”(不要引号)这几个字后就自动替换成:
公司名称
公司住址
联系电话
联系人姓名
QQ号码
说明:有些输入法不支持这个功能,键入标记名称后要按一下空格才行。

快速换页的方法
双击某页的右下脚,光标即可定位在那里,然后按回车直到换页。ctrl+回车点插入按纽,分隔符,选中分页符,然后确认就OK了 !!!

表格的简单调整宽度
鼠标放在表格的右边框上带鼠标变成可以调整大小的时候
双击
根据表格内的内容调节表格大小

代替金山词霸
点工具——语言——翻译,在右边出现的搜索框中输入要查的单词,回车就可以翻译了。可以选择英语翻成中文或中文翻成英语。
第一次使用可能要安装。

[Alt]键实现标尺的精确定位
如果你经常使用水平标尺来精确定位标签、页边框、首字缩进及页面对象的位置,那么你点击标尺设置页边框或标签时,您只可以将其设置为1字符或2字符,但不能设为1.5字符!要想设置更为精确的度量单位(例如百分之几字符),在按住[Alt]键的同时,点击并移动标尺或边框,此时标尺将用数字精确显示出当前的位置为百分之几字符位置。

用“记事本”去除格式
网页上COPY下来的东西往往都是有网格的,如果直接粘贴在WORD中会杂乱无章。先粘贴到记事本当中,再粘贴到WORD中,就可以去除网格等格式,再全选选择清除格式,居中再取消居中即可取消所有格式。可以直接在WORD中进行:(菜单)编辑/选择性粘贴……/无格式文本/确定。这样省事多了。

快速将文档转换成图片
先把欲想转换的文档保存退出.如:保存在桌面
然后新建一个文件.把想转换的文档(鼠标左建按住该文档不放)直接施放在页面上

恢复office的默认设置
比如不小心把word设置乱了(如删了菜单栏等等).
查找normal.dot直接删除.
下一次启动word会恢复默认值.

让Word只粘贴网页中的文字而自动去除图形和版式
方法一、选中需要的网页内容并按“Ctrl+C”键复制,打开Word,选择菜单“编辑”→“选择性粘贴”,在出现的对话框中选择“无格式文本”。
方法二、选中需要的网页内容并按“Ctrl+C” 键复制,打开记事本等纯文本编辑工具,按“Ctrl+V”键将内容粘贴到这些文本编辑器中,然后再复制并粘贴到Word中。

ctrl+alt+f可以输入脚注
这个对于经常写论文的朋友应该有点帮助。

将阿拉伯数字转换成中文数字或序号
1、先输入阿拉伯数字(如1234),全选中,单击“插入/数字/数字类型(壹、贰……)/确定”,即变为大写数字(如壹仟贰佰叁拾肆),会计朋友非常适用。
2、其他像一千二百三十四,甲、乙……,子、丑……,罗马数字等的转换,可参考上法。

Word中的常用快捷键吧
“字体”对话框     Ctrl+D
选择框式工具栏中的“字体”框     Ctrl+Shift+F
加粗 Ctrl+B
倾斜 Ctrl+I
下划线Ctrl+U
“上标”效果     Ctrl+Shift+=
“下标”效果     Ctrl+=
“关闭”命令     Ctrl+W
Word快捷键一览表
序号       快捷键CTRL+       代表意义
1…………Z…………撤消
2…………A…………全选
3…………X…………剪切
4…………C…………复制
5…………V…………粘贴
6…………S…………保存
7…………B…………加粗
8………… Q…………左对齐
9…………E…………据中
10…………R…………右对齐
11…………]…………放大
22…………[…………缩小
12…………N…………新建文档
13…………I…………字体倾斜
14…………W…………退出
15…………P…………打印
16…………U…………下划线
17…………O…………打开
18…………k…………插入超级连接
19…………F…………查找
20…………H…………替换
21…………G…………定位
23…Ctrl+Alt+L……带括号的编号
24…Ctrl+Alt+.________…
25…Alt+数字………区位码输入
26…Ctrl+Alt+Del………关机
27…Ctrl+Alt+Shift+?……¿
28…Ctrl+Alt+Shift+!……¡
29…Alt+Ctrl+E……………?
30…Alt+Ctrl+R……………®
31…Alt+Ctrl+T……………™
32…Alt+Ctrl+Ctrl…………©
33……Ctrl+D……………格式字体
34……Ctrl+Shift+= ………上标
35……Ctrl+=………………下标
36……Ctrl+Shift+>……放大字体
37……Ctrl+Shift+< ……缩小字体
38……Alt+Ctrl+I………打印预览
39……Alt+Ctrl+O………大刚示图
40……Alt+Ctrl+P………普通示图
41……Alt+Ctrl+M………插入批注
42……Alt+菜单上字母………打开该菜单

无级微调
打开“绘图”工具栏-点开下拉菜单-绘图网格...-将水平间距和垂直间距调到最小0.01-确定,这样你就可以无级微调

把work设置成在线打开,但不能修改‘只读’怎搞啊?
文件夹共享为只读

在WORD中输入三个等号然后回车。。。出来的是双横线哦。。。
同样的方法也可以做出波浪线单横线哦!~~~~~ ,
###为中间粗上下细的三线, ***为点线, ~~~为波浪线, ---为单线

输入拼音字母的音调怎么输入
用智能ABC,键入v9,然后自己挑选吧!

页码设置
1、打开页眉/页脚视图,点击插入页码按钮,将页码插入(此时所有的页码是连续编号的) 2、切换到页面视图,在需要从1计数的页面上插入连续分节符(插入--分隔符--分节符--连续) 3、再次换到页眉/页脚视图,点击设置页码格式按钮,将页码编排-起始页码设置为1

把Excel中的表格以图片形式复制到Word中
除了用抓图软件和全屏拷贝法外还有更简单的呢
先选定区域,按住Shift健点击"编辑"会出现"复制图片""粘贴图片",复制了后,在Word中选"粘贴图片"就可像处理图片一样处理Excel表格了!

Ctrl+鼠标滑轮(左右键中间的那个轮子)可以迅速调节显示比例的大小(100%)。向上滑扩大,向下滑缩小。


快速调整页眉横线长度
在word插入页眉后,会自动在此位置添加一条长横线。如果需要调整此线的长度及其水平位置,可以首先激活页眉,选择格式下的段落命令,调整一下左右缩进的字符值,确定可以看到最终效果了!

快速浏览图片
在WORD2003中,如果插入的图片过多,会影响打开和翻滚的速度。其实,我们可以通过改变图片的显示方式改变浏览速度。
工具--选项--视图--图片框
这样,先显示的是图片框,需要看的时候,停留,即可显示!

WORD 中如何输入分数
1、打开word,点击工具菜单栏的“插入”,在下拉菜单中点“域”。
2、在打开的复选框中的类别栏中“选等式公式”,域名中“EQ”。然后点击“选项”,在出现的菜单选项中选“F(,)”,接着点击“添加到域”并“确定”。
3、然后在输入F(,)数字,如要输入23 只需在F(,)输入F(2,3)就能得到2/3

怎样使WORD 文档只有第一页没有页眉,页脚
答:页面设置-页眉和页脚,选首页不同,然后选中首页页眉中的小箭头,格式-边框和底纹,选择无,这个只要在“视图”——“页眉页脚”,其中的页面设置里,不要整个文档,就可以看到一个“同前”的标志,不选,前后的设置情况就不同了

Word中双击鼠标的妙用
在Word的程序窗口中不同位置上双击,可以快速实现一些常用功能,我们归纳如下:
在标题栏或垂直滚动条下端空白区域双击,则窗口在最大化和原来状态之间切换;
将鼠标在标题栏最左边WORD文档标记符号处双击,则直接退出WORD(如果没有保存,会弹出提示保存对话框);
将鼠标移到垂直滚动条的上端成双向拖拉箭头时双击,则快速将文档窗口一分为二;
将鼠标移到两个窗口的分界线处成双向拖拉箭头时双击,则取消对窗口的拆分;
在状态栏上的“修订”上双击,则启动“修订”功能,并打开“审阅”工具栏。再次双击,则关闭该功能,但“审阅”工具栏不会被关闭;
在状态栏上的“改写”上双击,则转换为“改写”形式(再次“双击”,转换为“插入”形式);
如果文档添加了页眉(页脚),将鼠标移到页眉(页脚)处双击,则激活页眉(页脚)进入编辑状态,对其进行编辑;在空白文档处双击,则启动“即点即输”功能;
在标尺前端空白处双击,则启动“页面设置”对话框。


在word编辑中经常要调整字休大小来满足编辑要求
选中要修改的文字,按ctrl+]或ctrl+[来改变字体的大小!
这个方法可以微量改字体大小~



文本框的线条
1. 制作好文档后,通过“视图→页眉页脚”命令,调出“页眉页脚”工具栏,单击其中的“显示→隐藏文档正文文字”按钮,隐藏正文部分的文字内容。
2. 选择“插入”菜单中的“文本框”命令,在页眉的下方插入一个空文本框。
3. 在文本框内加入作为水印的文字、图形等内容,右击图片,选择快捷菜单中的“设置图片格式”命令,在对话框中“图片”选项卡下,通过“图像控制”改变图像的颜色,对比度和亮度,并手动调整图片的大小。   
4. 通过“设置文本框格式”命令,把文本框的线条色改为无线条色。
5. 单击“页眉页脚”工具栏的“关闭”按钮,退出“页眉页脚”编辑。

每页添加水印的操作
1. 制作好文档后,通过“视图→页眉页脚”命令,调出“页眉页脚”工具栏,单击其中的“显示→隐藏文档正文文字”按钮,隐藏正文部分的文字内容。
2. 选择“插入”菜单中的“文本框”命令,在页眉的下方插入一个空文本框。
3. 在文本框内加入作为水印的文字、图形等内容,右击图片,选择快捷菜单中的“设置图片格式”命令,在对话框中“图片”选项卡下,通过“图像控制”改变图像的颜色,对比度和亮度,并手动调整图片的大小。   
4. 通过“设置文本框格式”命令,把文本框的线条色改为无线条色。
5. 单击“页眉页脚”工具栏的“关闭”按钮,退出“页眉页脚”编辑。
6. 完成上述步骤的操作,水印制作得以完成,这样就为每一页都添加了相同的水印。

让Word页面快速一分为二
将光标定位在想分开的位置上,按下“Ctrl+Shift+Enter”组合键。


使Word中的字体变清晰
Word文档中使用 “仿宋” 字体很淡,可按以下方法使字体更清晰:
右击桌面,点 “属性”,点 “外观”,点 “效果”,选中“使用下列方式使屏幕字体的边缘平滑”选“清晰”,确定。

Word双面打印技巧
   我们平时用电脑的时候可能都少不了打印材料,Word是我们平常用的最多的Office软件之一。有时我们要用Word打印许多页的文档,出于格式要求或为了节省纸张,会进行双面打印

  我们一般常用的操作方法是:选择“打印”对话框底部的“打印”下拉列表框中的“打印奇数页”或“打印偶数页”,来实现双面打印。我们设定为先打印奇数页。等奇数页打印结束后,将原先已打印好的纸反过来重新放到打印机上,选择该设置的“打印偶数页”,单击“确定”按钮。这样通过两次打印命令就可以实现双面打印。

  我们也可以利用另一种更灵活的双面打印方式:打开“打印”对话框,选中“人工双面打印”,确定后就会出现一个“请将出纸器中已打印好的一面的纸取出并将其放回到送纸器中,然后‘确定’按键,继续打印”的对话框并开始打印奇数页,打完后将原先已打印好的纸反过来重新放到打印机上,然后按下该对话框的“确定”按键,Word就会自动再打印偶数页,这样只用一次打印命令就可以了。

  两种方法对比,后者较前者更为方便。

posted @ 2010-04-20 10:26 小强摩羯座 阅读(238) | 评论 (0)编辑 收藏

字符串拆分的中文处理问题

容健行@20077

转载请注明出处

原文出处:http://www.devdiv.net/home/space.php?uid=125&do=blog&id=365

概述:

拆分一个字符串在程序中使用非常广泛,特别是我们经常跟表格打交道的程序员们。所谓拆分字符串,就是将一个字符串中间以某个(或某些)字符为分隔,拆分成多个字符串。如 std::string s = "abc | ddd | 中国";    如果以竖线“|”拆分,可以将这个字符串拆分成三个字符串。

当然字符串拆分还包括通过正则表达式来拆分,为了简化问题,我们以单个字符做分隔的拆分,因为这种拆分用得最多。代码使用C++来讲解。

问题:

问题来源于实际,是之前我们组和其他组都有遇上的。先看一个例子,使用"|"拆分以下字符串,看起来怎么数都是分为48列,但我看到好几个版本的字符串拆分函数却报有49列:

"AGZGY1000004|200|刘瓅||20100101||OPRT10|1|0||AAGZ0Y100|0|0|24|0|0|0|0||-1|20030101|0|20991231||AGZGK6172888|200|曾晓翔||20100101||OPRT10|1|0||AAGZ0K617|0|0|24|0|0|0|0||-1|20061215|1|20061215||"

原因分析:

让我们先把以上字符串放到UltraEdit中,并切换到16进制的编辑模式,看看它的编码。

原因是原来的字符串拆分函数只是简单的查找“|”(编码为0x7c,而没有考虑到中文的处理(源代码太多,且有好几个版本,这里略去)。

boss中,c++程序使用的编码方式几乎全为ansi,而在ansi中,表示中文是用两个字符,且第一个字符是一个大于0x80的字符(字符的第一位为1),第二个字符为任意字符。这里引起一个问题:

当我们要分割字符串时,假如用"|"(0x7c)作为分割符,当分析上面这个字符遇到""(编码为0xad,0x7c)这个字符时,会把它第二个字符作为了分割符,结果就多出了一列。

解决方案:

问题原因找到了,重新写了一下字符串拆分函数-Split,这里使用的方法是:找到分隔符后,再向前查找字符看一下它前一个字符是否为东亚文字的第一个字符编码(编码大于0x80)。

考虑到以后支持unicode,这里使用了模板。以下可能不是最高效简单的实现,但如果以后遇上这种问题,可以参考一下。

#include "stdafx.h"

#include <stdio.h>

#include <tchar.h>

#include <iostream>

#include <string>

#include <vector>

#include <algorithm>

#include <fstream>

// unicode 分割策略

inline

    bool __SplitPolicy(

    const std::wstring& s,

    const std::wstring& splitchar,

    std::wstring::size_type& pos)

{

    pos = s.find_first_of(splitchar, pos);

    return pos != std::string::npos;

}

// ansi 分割策略

inline

    bool __SplitPolicy(

    const std::string& s,

    const std::string& splitchar,

    std::string::size_type& pos)

{

    pos = s.find_first_of(splitchar, pos);

    if (pos != std::string::npos)

    {

       // 如果前一个字符的第一位为1,且当前字符是在东亚文字的第二个字符,

       // 则认为该字符是东亚字的其中一个字符,要跳过,不作为分割符。

       std::string::size_type i = 1;

       for (; i < pos; ++i)

       {

           if (!((char)(s[pos - i]) & 0x80)) // 判断第一位是否为1。(0x80的二进制为 10000000)

              break;

       }

       if (!(i % 2)) // 看一下当前字符是否为东亚文字的第二个字符

       {

           ++pos;

           __SplitPolicy(s, splitchar, pos);

       }

    }

    return pos != std::string::npos;

}

template<typename char_type> inline

    int Split(

    const std::basic_string<char_type>& s,

    const std::basic_string<char_type>& splitchar,

    std::vector<std::basic_string<char_type> >& vec)

{

    typedef std::basic_string<char_type>   string_t;

    typedef typename string_t::size_type   size_t;

    string_t tmpstr;

    size_t pos = 0, prev_pos = 0;

    vec.clear();

    while (__SplitPolicy(s, splitchar, pos))

    {

       tmpstr = s.substr(prev_pos, pos - prev_pos);

       vec.push_back(tmpstr);

       prev_pos = ++pos;

    }

    size_t len = s.length() - prev_pos;

    if (len > 0)

       vec.push_back(s.substr(prev_pos, len));

    return static_cast<int>(vec.size());

}

// ansi版本测试

void testSplit()

{

    std::vector<std::string> vec;

    const std::string str = "AGZGY1000004|200|刘瓅瓅||20100101||OPRT10|1|0||AAGZ0Y100|0|0|24|0|0|0|0||-1|20030101|0|20991231||AGZGK6172888|200|曾晓翔||20100101||OPRT10|1|0||AAGZ0K617|0|0|24|0|0|0|0||-1|20061215|1|20061215||a";

    const std::string sp = "|";

    int count = Split(str, sp, vec);

    for (std::vector<std::string>::const_iterator it = vec.begin(); it != vec.end(); ++it)

       std::cout << *it << " ";

}

// unicode版本测试

void testSplitW()

{

    std::vector<std::wstring> vec;

    const std::wstring str = L"AGZGY1000004|200|刘瓅||20100101||OPRT10|1|0||AAGZ0Y100|0|0|24|0|0|0|0||-1|20030101|0|20991231||AGZGK6172888|200|曾晓翔||20100101||OPRT10|1|0||AAGZ0K617|0|0|24|0|0|0|0||-1|20061215|1|20061215||";

    const std::wstring sp = L"|";

    Split(str, sp, vec);

    const char head[3] = {0xff, 0xfe, 0};

    const wchar_t line[3] = L" ";

    // 控制台输出不了unicode字符,使用输出到文件的方式

    std::ofstream fileOut("C:/out.txt");

    fileOut.write(head, 2);

    for (std::vector<std::wstring>::iterator it = vec.begin(); it != vec.end(); ++it)

    {

       fileOut.write((const char*)it->c_str(), it->length() * 2);

       fileOut.write((const char*)line, 2);

    }

}

int main()

{

    testSplit();

    testSplitW();

}

参考:

1http://unicode.org/

2《谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词》

posted @ 2010-04-19 01:47 小强摩羯座 阅读(756) | 评论 (0)编辑 收藏

关于C++中文字符的处理

一 引入问题
代码 wchar_t a[3]=L”中国”,编译时出错,出错信息为:数组越界。但wchar_t 是一个宽字节类型,数组a的大小应为6个字节,而两个汉字的的unicode码占4个字节,再加上一个结束符,最多6个字节,所以应该不会越界。难道是编译器出问题了?
二 解决引入问题所需的知识
   主要需两方面的知识,第一个为字符尤其是汉字的编码,以及语言和工具的支持情况,第二个是vc/c++中MutiByte Charater Set 和 Wide Character Set有关内存分配的情况.
三 汉字的编码方式及在vc/c++中的处理
1.汉字编码方式的介绍
对英文字符的处理,7位ASCII码字符集中的字符即可满足使用需求,且英文字符在计算机上的输入及输出也非常简单,因此,英文字符的输入、存储、内部处理和输出都可以只用同一个编码(如ASCII码)。
而汉字是一种象形文字,字数极多(现代汉字中仅常用字就有六、七千个,总字数高达5万个以上),且字形复杂,每一个汉字都有"音、形、义"三要素,同音字、异体字也很多,这些都给汉字的的计算机处理带来了很大的困难。要在计算机中处理汉字,必须解决以下几个问题:首先是汉字的输入,即如何把结构复杂的方块汉字输入到计算机中去,这是汉字处理的关键;其次,汉字在计算机内如何表示和存储?如何与西文兼容?最后,如何将汉字的处理结果从计算机内输出?
为此,必须将汉字代码化,即对汉字进行编码。对应于上述汉字处理过程中的输入、内部处理及输出这三个主要环节,每一个汉字的编码都包括输入码、交换码、内部码和字形码。在计算机的汉字信息处理系统中,处理汉字时要进行如下的代码转换:输入码→交换码→内部码→字形码。
(1)输入码: 作用是,利用它和现有的标准西文键盘结合来输入汉字。输入码也称为外码。主要归为四类:
a)      数字编码:数字编码是用等长的数字串为汉字逐一编号,以这个编号作为汉字的输入码。例如,区位码、电报码等都属于数字编码。
b)      拼音码:拼音码是以汉字的读音为基础的输入办法。
c)      字形码:字形码是以汉字的字形结构为基础的输入编码。例如,五笔字型码(王码)。
d)      音形码:音形码是兼顾汉字的读音和字形的输入编码。
(2)交换码:用于汉字外码和内部码的交换。交换码的国家标准代号为GB2312-80。
(3)内部码:内部码是汉字在计算机内的基本表示形式,是计算机对汉字进行识别、存储、处理和传输所用的编码。内部码也是双字节编码,将国标码两个字节的最高位都置为"1",即转换成汉字的内部码。
(4)字形码:字形码是表示汉字字形信息(汉字的结构、形状、笔划等)的编码,用来实现计算机对汉字的输出(显示、打印)。
2.VC中汉字的编码方式
     vc/c++正是采用了GB2312内部码作为汉字的编码方式,因此vc/c++中的各种输入输出方法,如cin/wcin,cout/wcout,scanf/wsanf,printf/wprintf...都是基于GB2312的,如果汉字的内码不是这种编码方式,那么利用上述各种方法就不会正确的解析汉字。
仔细观察ASCII字符表,从第161个字符开始,后面的字符并不经常为用户所使用,负值也未使用。GB2312编码方式充分利用这一特性,将161-255(-95~-1)之间的数值空间作为汉字的标识码。既然255-161 = 94不能满足汉字容量的要求,就将每两个字符并在一块(即一个汉字占两个字节),显然,94* 94 =8836基本上已经满足了常用汉字个数的要求。计算机处理字符时,当连续处理到两个大与160(或-95~-1)的字节时,就认为这两个字节存放了一个汉字字符。可以用下面的Demo程序来模拟vc/c++中输出汉字字符的过程。
    unsigned char input[50];
cin>>input;
    int flag=0;
     for(int i =0 ;i < 50 ;i++)
      {
         if(input[i] > 0xa0 && input[i] != 0)
          {
              if(flag == 1)
               {
                    cout<<"chinese character"<<endl;
                    flag = 0;
               }
              else
               {
                    flag++;
               }
          }
         else if(input[i] == 0)
          {
              break;
          }
         else
          {
               cout<<"english character"<<endl;
          }
}
输入:Hello中国 (“中国”对应的GB2312内码为:214 208,185 250)
输出:english character
english character
english character
english character
english character
chinese character
chinese character
vc/c++中的英文字符仍然采用ASCII编码方式。可以设想,其他国家程序员利用vc/c++编写程序输入本国字符时,vc/c++则会采用该国的字符编码方式来处理这些字符。
    问题又产生了,韩国的vc/c++程序在中国的vc/c++上运行时,如果没有相应的内码库,则对韩语字符的显示有可能出现乱码。我个人猜测,vc安装程序中应该带有不同国家的内码库,这样一来肯定会占用很大的空间。如果所有的国家使用统一的编码方式,且所有的程序设计语言和开发工具都支持这种编码方式该多好!而现实中,确实已经有这种编码方式了,且许多新的语言也都支持这种编码方式,如Java、C#等,它就是下面的Unicode编码
3.新的内码标准---Unicode
Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。随着计算机工作能力的增强,Unicode也在面世以来的十多年里得到普及。最新版本的 Unicode 是 2005年3月31推出的Unicode 4.1.0 。另外,5.0 Beta已于2005年12月12日推出,以供各会员评价。
Unicode 编码系统可分为编码方式和实现方式两个层次。
编码方式:Unicode 的编码方式与 ISO 10646 的通用字符集(Universal Character Set,UCS)概念相对应,目前的用于实用的 Unicode 版本对应于 UCS-2,使用16位的编码空间。也就是每个字符占用2个字节。这样理论上一共最多可以表示 216 个字符。基本满足各种语言的使用。实际上目前版本的 Unicode 尚未填充满这16位编码,保留了大量空间作为特殊使用或将来扩展。
实现方式:Unicode 的实现方式不同于编码方式。一个字符的 Unicode 编码是确定的。但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对 Unicode 编码的实现方式有所不同。Unicode 的实现方式称为Unicode转换格式(Unicode Translation Format,简称为 UTF)。如,UTF-8 编码,这是一种变长编码,它将基本7位ASCII字符仍用7位编码表示,占用一个字节(首位补0)。而遇到与其他 Unicode 字符混合的情况,将按一定算法转换,每个字符使用1-3个字节编码,并利用首位为0或1进行识别。
Java与C#语言都是采用Unicode编码方式,在这两种语言中定义一个字符,在内存中存放的就是这个字符的两字节Unicode码。如下所示:
char a='我';     => 内存中存放的Unicode码为:25105
4.内码的相互转换
(1)vc中的实现方法
   利用Windows系统提供的API:::MultiByteToWideChar::WideCharToMultiByte
::MultiByteToWideChar实现当前码到Unicode码的转换;
::WideCharToMultiByte实现Unicode码到当前码的转换;
(2)Java中的实现方法
    String vcString=new String(javaString.getBytes("UTF-8"),"gb2312");
java的编码应该是UTF-8
(3)C#中的实现方法
    ??
四 vc中的MutiByte Charater Set 和 Wide Character Set
1.MultiByte Charater Set方式
   这种方式以按字节为单位存放字符,即如果一个字符码为两字节,则在内存中占两字节,字符码为一字节,就占一字节。例如,字符串“中国abc”的编码为:中(0xd6、0xd0)、国(0xb9、0xfa)、a(0x61)、b(0x62)、c(0x63)、\0(0x00),就存为如下方式:
对应的类型,方法有:
char、scanf、printf、cin、cout …
2.Wide Character Set
这种方式是以两字节为单位存放字符,即如果一个字符码为两字节,则在内存中占四字节,字符码为一字节,就占两字节。例如,字符串“中国abc”就存为如下方式:
对应的类型,方法有:
wchar_t、wscanf、wprintf、wcin、wcout …
造成上面存储方式的根本原因在于,wchar_t类型其实是一个unsigned short 类型。如,存储上面字符串的数组的定义为:wchar_t buffer[8] 等价于unsigned short buffer[8].而所有以字母w开头的方法也都是以unsigned short类型,即两字节为单位来处理字符,因此,存储在wchar_t类型数组中的字符串无法用cout显示,只能用wcout方法来显示。
由于Unicode码也是采用两个字节,因此Wide Character Set方式能够很好的支持Unicode码的存储,但是在vc的环境下要将一个Unicode码存入两字节而不是四字节内存中,必须通过上面的API函数::MultiByteToWideChar首先,将当前的编码转换为Unicode码,然后,将每个字符的Unicode码放入每一个wchar_t类型的变量中。以下是一个实例代码:
char input[50];
cin>>input;
int size;
size=::MultiByteToWideChar(CP_ACP,0,input,strlen(input)+1,NULL,0);
if(size==0)
     return -1;
wchar_t *widebuff=new wchar_t[size];
::MultiByteToWideChar(CP_ACP,0,input,strlen(input)+1,widebuff,size);
输入:中国abc
Debug断点调试:
size==6
数组widebuff[0-size]占12字节,存放了6个字符的Unicode码,码值为:
中(0x4e2d) 国(0x56fd) a(0x0061) b(0x0062) c(0x0063) d(0x0000)
这时,数组的大小size等于输入的字符个数加上一个结束符,符合我们的想象。
五 引入问题的错误分析
(1) 没有理解编译器中的编码方式
    虽然vc/c++中汉字的编码占两个字节,但并不是Unicode码,是GB2312码。
(2) 没有理解MutiByte Charater Set 和 Wide Character Set的存储原则;
    在vc/c++中,“中国”按char[5]来对待,而wchar_t a[3]实际上是三个unsigned short类型的变量,因此赋值时会越界。

posted @ 2010-04-18 01:10 小强摩羯座 阅读(217) | 评论 (0)编辑 收藏