有十个阿狸桃子中有几个人物 每人分三个 够分多少人

华为人才管理核心经验:桃子、绳子、鞭子和筛子 : 经理人分享
华为人才管理核心经验:桃子、绳子、鞭子和筛子
企业在人才管理方面普遍奉行的“双重博弈”逻辑,是导致企业陷入人才管理困境的核心原因。可以推断,几乎每一家企业都不希望在人才管理方面继续奉行“双重博弈”逻辑。但问题是,怎样才能做到呢?首先让我们从商业领域的实践中获得灵感吧——在现代服务业中,有许多经营实体都在谋求采取一定的策略“圈”住其顾客,并对被“圈”顾客实施“垄断经营”,比如干洗店、保健品商店、美容美发机构、健身会所、桑拿中心、网站建设机构、一部分网上商店等等。它们所采取的基本方式是:通过一定的利益承诺,诱使目标顾客成为自己的VIP会员,当顾客获得会员资格之后,特别是当顾客通过预付金购买了会员身份之后,它们便对这些顾客一定程度上实现了“垄断经营”——顾客在特定的时间内消费同类商品或服务时,只能从它们那里购买。先讲一个我亲身经历的小例子,从中我们可以体会到上述经营手段设计的奥妙之处。2014年年初,我到我公司附近的一家上海著名的美容美发连锁机构“文峰”去理发。按照他们的标价,我需要为这次消费支付38元。理发结束后付款时,服务台的工作人员告诉我,如果花1500元购买他们的一张会员卡,不仅以后每次理发只需要支付11.4元,而且本次消费立刻由38元减至11.4元。我被说服了,因为:第一,它的打折很有诱惑力;第二,反正我每月至少要理发两次,在哪里理都是理;第三,它离我的公司很近,我每次理发比较方便;第四,这是一家知名的美容美发连锁机构,不大可能倒闭,即便倒闭了,我受到的损失也不足挂齿;最后,这次消费体验的效果令我比较满意。我于是成了“文峰”的VIP会员。自此之后,我每次在上海要理发时,都会到这家机构消费。我敢肯定,在我将会员卡中的1500元用完之前,其它理发店是没法与文峰竞争我这位顾客的,如果我对它的服务比较满意,我还有可能继续充值——延长它对我这位顾客的“垄断经营”时间。上述服务型企业谋求“圈”住顾客,从而实现对顾客“垄断经营”的做法,正在向几乎所有的新兴和传统商业领域快速蔓延(限于篇幅,就不再举例了)。在此,我想说的是,这正是一种试图超越“双重博弈”逻辑的商业行为。道理其实十分简单:只要不再与顾客博弈,就不再需要与竞争者博弈;或者,只要降低与顾客博弈的强度,就可以降低与竞争者博弈的强度。那么,可否将上述商业领域超越“双重博弈”的思想和行为引入到企业的人才管理领域呢?我认为这是完全可以的。本文将通过抽象出华为在人才管理方面的经验来论证这一点。近几年来,有许多培训公司和咨询机构都在把华为的人才管理经验作为自己的产品不遗余力地贩卖,而且生意做得十分火爆。这一方面说明,现实中的许多企业真真切切地面临了越来越严峻的人才管理问题,它们急切地渴望通过学习标杆企业的人才管理经验,来解决自身的人才管理问题;另一方面,众多的培训公司和咨询机构“号召”企业学习华为的人才管理经验,并得到广泛的企业一致响应,这一事实,也充分证明了华为在人才管理方面的经验是被普遍认可的。对于华为在人才管理方面的经验,不同的人有不同的解读。我的解读是,华为之所以能够打破“双重博弈”的逻辑,或者降低“双重博弈”的强度,是因为华为系统有效地解决了以下四个看似简单、但实则蕴含着人才管理全部学问的问题:如何吸引人才?如何留住人才?如何让人才创造价值?如何淘汰不优秀的人才?华为针对上述四个方面的问题所采取的人才管理策略,我将其形象地比喻为“桃子”、“绳子”、“鞭子”和“筛子”,由此给出的基本观点如下:任何一位人才到任何一家企业工作,都是受特定利益驱动的。我将人才们希望从企业那里获得的利益称为“桃子”。企业只有愿意并有能力给予人才们想要的“桃子”,才可能吸引到众多的人才,并从中挑选出自己想要的优才。华为在运用“桃子”吸引人才方面的一系列策略组合,是绝大多数民营企业难以望其项背的。企业要想留住优秀的人才,又不至于使企业的固定用人成本过高(招才和留才的成本一旦过高,对企业的发展将造成深远的负面效应;许多跨国公司在中国市场雄风不再,极大程度上与其使用人才的固定成本过高有直接关系),就需要采取高超的策略来对特定的人才实施适当的“捆绑”。我将企业用来“捆绑”人才的策略称之为“绳子”。华为显然是极善于使用“绳子”来捆绑优秀人才的企业,因为它总是能够让人才们在不知不觉中心甘情愿地被“捆绑”。企业招聘和保留人才的根本目的,是为了让人才们最大化地为企业创造价值。但是,人都是有惰性的,都是有趋利避害本性的,特别是在某些环境条件下,人是容易滋生出许多问题来的。因此,企业需要设计一套有效的培养与管理手段,来保证人才们不得不收敛自己的“性情”,而千方百计地、竭尽全力地和最大化地为企业创造价值。我把企业为促使人才不断学习成长、促使人才最大化地为企业创造价值的管理手段称之为“鞭子”。华为毫无疑问在这方面也是无与伦比的高手。所有的企业都知道,在一个组织或团队中,总会有一些人,即便你拿“鞭子”抽他,他也产生不了工作意愿或提高不了工作能力;而且,过去优秀的人才,并不代表现在依然优秀,现在优秀的人才,并不代表未来同样优秀;特别是,有些人在组织中拥有了地位和金钱之后,就可能会变得安于现状、不思进取,甚至会走向骄横或堕落;还有少数人,就其个体能力而言,他们算得上是“英雄”,但在特定团队中,他们则是有害的因子……在这些情况下,企业就应该设计一套淘汰机制,使那些不适应于或有害于组织发展的人在组织内没有生存的土壤或空间。我将这种企业用于淘汰劣才的机制称之为“筛子”。有了“筛子”,不仅可以减少那些可能存在的对组织发展有害的因子,而且可以促使上述“桃子”、“绳子”和“鞭子”发挥应有的或更好的效用。显然,华为在这方面也做到了无以复加的地步。华为在人才管理方面的上述四大经验,是否具有前述商业创新实践中的“圈”住顾客和对顾客“垄断经营”一样的性质呢?我的回答是肯定的。具体观点见下表。“圈”住顾客“圈”住人才吸引通过产品和服务吸引顾客桃子通过利益承诺吸引人才捆绑设置顾客退出障碍绳子设置人才退出障碍激励鼓励顾客大量、多样和持续购买鞭子促使人才最大化为企业创造价值淘汰淘汰低价值/无价值的顾客筛子淘汰不优秀的人才接下来,我将扼要性地指出华为人才管理经验的实质,并在此基础上,分别提示性地说明“桃子”、“绳子”、“鞭子”和“筛子”在人才管理过程中的作用。不过,我不想在这里与你全面深入地讨论华为在人才管理方面的具体经验。因为:关于华为在人才管理方面的经验,已经有大量的书籍记载和论述;各种媒体上有关华为的文章,几乎到了汗牛充栋的地步,而且每天都在被人们广泛地转发;此外,在我们每一个人的记忆中,已经有了许多关于华为的故事和因华为而创造的管理概念。为此,在这里,我仅想提示读者们(尤其是民营企业家们)从纷繁复杂的华为人才管理经验中关注和思考以下五个方面:关注和思考1:任正非在人才管理方向的时间和精力投入华为总裁任正非认为,自己对华为的产品创造贡献为“0”,因为在华为所创造的技术发明中,没有一项专利发明是由任正非创造的。他一直把他的主要时间和精力放在人才管理方向(人才管理一定会涉及企业管理的方方面面),而人才管理正是公认的“华为能发展到今天的基础”。无独有偶,中国近几年最受追捧的另外三家企业的大老板——阿里巴巴的马云、腾讯的马化腾和小米科技的雷军,也都是把自己的主要时间和精力放在了人才管理方向的。这是否可以认为,关注人才管理,是现在和未来的企业成功的“牛鼻子”呢?我以为是。反观其他许多民营企业家,他们大多是营销或技术或生产方面的高人——他们的企业能够发展到今天,前期主要就是靠着他们在营销或技术或生产方面有着足够出彩的个人表现。但是,当他们的企业发展到一定规模以后,便碰到了瓶颈。大家注意观察将会发现,几乎所有的民营企业发展的瓶颈主要集中在人才管理方面。而之所以人才管理成为了民营企业发展的瓶颈,核心原因就在于,民营企业的老板们在人才管理方面存在能力短板。因为人才管理是他们的能力短板,他们往往不愿意在这个方向上投入过多的时间和精力(回避矛盾),如此一来,这一瓶颈便一直不能得到有效解决。在这个意义上讲,我认为出现了人才管理瓶颈的民营企业家,很有必要像任正非(也包括马云、马化腾、雷军)那样把大量的时间和精力放到人才管理方向上来。民营企业要学习华为的人才管理经验,首先要求民营企业家像任正非同志那样,要把自己有限的时间和精力向人才管理方向倾斜。虽然这对于一部分民营企业家来说,可谓是“勉为其难”或“赶鸭子上架”,但是由于人才管理是其企业发展的瓶颈,要想走出困境就必须迎难而上。事实上,从不懂到懂有一个过程,虽然当前不懂或似懂非懂,但投入的时间和精力多了,自然就会懂的。任正非也是在众多“军师”的帮助下,“摸着石头过河”,逐步成为人才管理方面的时代高人的。关注和思考2:华为吸引人才的“桃子”华为在吸引人才方面也曾有过沉痛的教训。比如,2000年的时候,华为曾一次性地从名牌大学招聘了300多名应届生,但是不到一年时间,这些人才“跑”了个精光。又比如,任正非自己也承认,他曾许多次在招聘人才时“看走了眼”——把那些“伪人才”(任正非称之为“不优秀的人才”)招到了公司里来,因此“给公司造成了惨重损失”。但是,华为在经历了无数次的教训之后,终于找到了一套吸引人才的有效办法,它是华为的人才管理得以有效展开的一个前提性条件。人才管理的核心问题,是首先要有可选择的人才;有了可选择的人才时,其他一切管理办法都好使;在没有可选择的人才时,企业的一切人才管理的行为都将是被动的。比如,你对一位人才的能力不满意,但你却没有可以替代他的人选,这时即便你对他很不满,也只能将就着使用他,否则工作就没有人做;而在你既对他不满意、又不得不使用他时,你的一切管理手段都要大打折扣,甚至你根本就不敢大胆地出台和使用人才管理手段。华为显然非常清楚这一点。因此,华为一直把人才招聘工作放在人才管理整体工作的优先位置。尽管华为也曾招聘过大量有工作经验的人才,但它主要还是以招聘应届毕业生为主,然后让他们从基层一步一步往上发展。这样做有很多好处,最大的好处是,应届生“一张白纸好写字”——这便于把华为的价值观装进人才们的脑子里(这是人才管理中最“狠”的一招)。无论是有经验的人才,还是应届大学生,人才们凭什么愿意到你的企业任职呢?这会是一个大问题(这也是许多民营企业招聘不到人才、因而人才管理工作一直十分被动的根本原因之所在)。解决这个大问题,只有一个办法,就是要有吸引人才加盟的“桃子”。正如你所知道的那样,华为是极善于运用“桃子”来吸引人才的企业。华为在吸引人才方面主要使用了三个大“桃子”:1)通过华为的战略、组织和品牌影响力,给人才们以丰富的未来想象空间;2)给人才以有竞争力的薪酬、福利、奖金和股票期权;3)给人才们提供良好而又多样的学习与成长平台和职业发展与内部创业机会。任何人才都不会凭白无故地到一家企业工作。驱使人才选择企业的原因是人才的需要。一般而言,人才是否愿意进入一家企业工作,取决于他们对三项利益的判断。一是,金钱收入;二是,职业发展机会;三是,工作的意义。这就是所谓的“桃子”。不同的人才在这三个方面的要求会有不同倾向,并且人才处于不同的发展阶段时,其要求的侧重点也会有所不同。但总体上说,如果企业没有意愿和能力满足人才们对“桃子”的要求,就别指望能够吸引大量的优秀人才加盟。换言之,企业要想吸引大量的优秀人才加盟,就必须考虑应该给人才们以怎样的“桃子”。关注和思考3:华为捆绑人才的“绳子”在华为的人才管理经验中,你很少见到它在直接刻意地运用什么“绳子”捆绑人才。因为,华为一直奉行的是“自由雇佣制度”。所谓“自由雇佣制度”,是指企业从人力资源市场招聘人才,企业与人才之间建立合法的契约关系,人才可以选择是否在企业服务,是否自愿地为企业做贡献。如任正非在其演讲稿《华为的红旗到底能打多久》中这样说道:“公司与员工在选择权利上是对等的,员工对公司的贡献是自愿的。自由雇佣制度促使每个员工都成为自强、自立、自尊的强者,从而保证公司具有持久的竞争力……由于双方的权利是对等的,对双方都起到了威慑作用,这更有利于矛盾的协调……企业和员工的交换是对等的,企业做不到的地方员工要理解,否则你可以不选择企业,若选择了企业就要好好干,若不好好干,你随时都可以离开。”但是,这并不意味着华为没有用“绳子”来“捆绑”优秀人才的思考和实践。深入分析华为的经验,你将看到,华为设计的人才管理机制,对于优秀的人才是明显具有“捆绑”效果的。这种“捆绑”行为主要体现在三个方面:一是,通过战略、组织和品牌的影响力来促使人才们从心底里认同华为的文化。这是最高明的人才捆绑策略,是精神的“捆绑”。二是,通过为人才们提供有竞争力的薪酬、福利、奖金和股票期权来“捆绑”人才。它给人才们的暗示是,在华为工作,如果你能满足公司的要求,你就有可能获得在其他企业不能获得的金钱回报,这是物质利益的“捆绑”。众所周知的,任正非所说的“不能让雷锋吃亏”,主要体现在这一点上。三是,通过为人才们提供良好而又多样的学习与成长平台和职业发展与内部创业机会来“捆绑”人才。在华为,人才们不仅拥有自主选择工作的权利,而且拥有轮岗学习和其他众多的学习机会。而且华为为优秀人才在公司向上升迁提供了三条清晰的通道(管理、技术和项目),这对那些希望获得职业成功的人才们来说是极具诱惑力的。可供企业用于“捆绑”优秀人才的“绳子”一般说来有四条。一是文化的“绳子”。一旦人才们接受和认同了某种企业文化,他们便很可能对其他的企业不适应,因而会选择留在企业中发展,而不是选择随意跳槽。二是,物质利益的“绳子”。当一家企业给予员工的物质利益回报较大时,员工会倾向于留在现有的企业,并努力满足企业的要求。三是,职业发展机会的“绳子”,当一家企业能够提供更多和更好的学习成长与晋升机会时,人才们会倾向于留在该企业。四是,其他利益的“绳子”。如内部职称认定、更为细致的专业分工、住房和汽车贷款、解决家属就业和子女就学问题等等。值得注意的是,许多民营企业在“捆绑”优秀的人才方面,动用的往往只是一些“线头线脑”,而没有真正有效的“绳子”。最为有效的“捆绑”人才的“绳子”是人才最为关注的需求,而不同人才的需求是有所侧重的。关注和思考4:华为抽打人才的“鞭子”华为是一家极善于严酷地运用“鞭子”来“抽打”人才的企业。“抽打”人才的目的有两个,一是让人才不断学习进步,二是让人才为企业创造更好的业绩;前者是迫使人才有工作意愿和工作能力,后者是迫使人才为企业(也是为人才自身)创造价值。华为用于“抽打”员工的“鞭子”主要有两条:第一条“鞭子”是重视对人才的培养。著名教授陈春花在其作品《领先优势》中这样写道:“1996年开始,华为凭借高薪积聚了大量的来自著名高校的毕业生,一年招聘进几百、上千名大学生,甚至一次性招聘5000人。为确保这些学生在华为能够成长为对企业有价值的人才,任正非最早在企业内部建立起适合业务需求与人才成长特点的分层和分类人力资源开发、培训体系,如在各业务系统分别建立管理者培训中心、营销培训中心、研发培训中心、客户培训中心等。在中国本土企业中,任正非引领的华为,是为数有限的在人力资源培训开发方面倾注了大量热情和资金的公司。”华为对人才的培养主要分为这样几种形式:新员工入职培训、全员导师制、企业文化培训、在岗学习、轮岗学习、后备干部培养、倡导员工自主学习、职业生涯通关培训,等等。有统计表明,华为员工参加培训的时间约占员工工作时间的7%.之所以将华为对人才的培养称之为“鞭子”,是因为华为在培养人才时,“会让员工感到痛苦、煎熬并铭记终身”。有许多华为的员工把公司的培训总结为:特苦、特累,考试特多。比如,有人就这样形容新员工入职培训:“如同高考冲刺阶段,这一段时间的考试次数远远超过了大学四年的总和。”任正非曾经说过一句非常经典的话:“烧不死的鸟就是凤凰”,这句话恰恰体现出了华为在人才培养方面所奉行的“鞭打”理念。华为重视人才培养的逻辑说起来简单而明确:只有通过严格多样的培训,才能帮助人才建立足够的工作意愿和能力;只有人才有了足够的工作意愿和能力,才能为组织创造最大化的业绩;只有为组织创造了最大化的业绩,个人在组织中才能得到最大化的回报。第二条“鞭子”是重视对人才的绩效管理。华为的绩效管理充分借鉴了IBM的管理体系,但比IBM来得更加严苛。它的绩效考核的基本过程为:制定绩效目标→建立工作期望→建立目标任务指导书→绩效形成过程指导→绩效考核→绩效面谈→制定绩效改进计划。乍乍一看,这个过程与大多数企业绩效管理的通行套路并无根本区别。但是在华为,绩效几乎是任何一位人才是否能够在公司立足并获得发展的唯一依据,因为本文接下来将要提及的“末位淘汰制”所基于的唯一标准就是绩效考核数据。企业用于管理已经进入到组织中的人才的最有效的手段无非是两种。一是培养人才,二是绩效管理。培养人才的目的是为了获得好的绩效,绩效表现是检验人才培养效果的依据。这两点在人才管理中的重要性表现在:只有培养人才,才能帮助人才们建立足够的工作意愿和能力;只有人才们有了足够的工作意愿和能力,人才们才能为组织创造最大化的业绩;人才们只有为组织创造了最大化的业绩,其个人在组织中才能得到最大化的回报;人才们只有在组织中获得最大化的回报,他们才愿意留在组织中,并愿意在组织中通过不断提升能力而创造出更大的业绩。绝大多数民营企业在这两点上也有所作为,但力度和效果往往不佳,原因有二。一是,没有找到更为有效的培养人才和管理绩效的方法;二是,缺乏有效的吸引人才的手段和淘汰劣才的机制。后者显然是前提条件,因为不具备这个前提条件,培养人才和管理绩效的手段便一定是软弱的。关注和思考5:华为淘汰劣才的“筛子”与众多的民营企业不敢淘汰或没有条件淘汰劣才相比,华为是敢于使用“筛子”来不断淘汰劣才的为数较少的公司。最著名的是华为采取的“末位淘汰制”。众所周知,末位淘汰制是公司依据本企业实行的绩效指标体系对员工的工作绩效进行考核,并根据考核的结果把得分靠后的员工淘汰出局的管理制度。任正非在华为推行末位淘汰制,基本上遵循了GE的前CEO杰克·韦尔奇推崇的“活力曲线”——2-7-1法则。即:把20%的绩优员工定义为A类员工,把70%的业绩中等的员工定义为B类员工,把余下10%的业绩较差的员工定义为C类员工。“C类员工必须走人”。同CEO杰克·韦尔奇推行末位淘汰制面临了大量的诟病一样,任正非在华为推行末位淘汰制,也遭受到了来自各个方面的人们的批评和质疑。但是,华为却一直坚持在这么做。对此,任正非曾这样说道:“有人问,末位淘汰制实行到什么时候为止?借用CEO杰克·韦尔奇的一句话来说就是,末位淘汰是永不停止的。只有淘汰不优秀的员工,才能把整个组织激活。GE活了100多年的长寿秘诀就是‘活力曲线’。活力曲线其实就是一条强制性的淘汰曲线,用CEO杰克·韦尔奇的话讲,活力曲线能够使一个大公司保持着小公司的活力。GE能够活到今天得益于这个方法,我们公司在这个问题上也不是一个三五年的短期行为……我们在这个事情上要耐着性子做下去。”但是请注意一点,华为是有条件这么做的,因为它向人才提供的“桃子”足够大、足够多,它捆绑人才的“绳子”和抽打人才的“鞭子”足够有力,有许许多多的人才挤破脑袋想要到华为求得一席之地,这是其他大多数民营企业做不到的。由此可见,人才管理是一项系统工程,单纯使用一种策略往往行不通或效果不佳。2007年年底,华为 “7000人辞职事件”和该事件之后华为采取的主动“瓦解工号文化”的行为,也是在相似的背景和管理思维下发生的。企业如果不能在组织内部推行优胜劣汰的人才管理机制,便一定会逐渐失去活力,最终衰退下去。有许许多多的民营企业家也试图在本公司推行类似于“末位淘汰制”的人才管理机制,但是最终却没有推行或者推行不下去,一个重要的原因就是,这些企业不具备推行的条件。因为,运用好 “筛子”的前提条件是,要有高度配套的“桃子”、“绳子”和“鞭子”。由此可见,这一机制有必要推行,但在推行之前,需要系统地规划和设计全盘的人才管理手段。最后我想说,我的观察和研究表明,上述“道理”几乎所有的民营企业家都是大致懂得的,并且他们也一直都在努力采取类似的“桃子”、“绳子”、“鞭子”和“筛子”来管理人才,但为什么就不能产生像华为那样的人才管理效果呢?这是因为,在人才管理方面,有效地使用“桃子”、“绳子”、“鞭子”和“筛子”,需要依赖于两个前提性条件。第一个前提性条件是,设计怎样的“桃子”、“绳子”、“鞭子”和“筛子”以及如何使用它们?许多企业虽然也在运用这四大工具来管理人才(员工),但效果却不佳,其中的直接原因就是,它们没有设计好这个前提性条件。比如,薪酬待遇和职业机会是两个“桃子”,但是,针对不同人才的不同关切,企业到底应该怎样设计具体的薪酬和职业晋升体系呢?这就是一个大问题。另一个前提性条件是,要有有效的评估人才的标准。没有人才评估标准,你便不能对人才进行有效评估;不能有效评估,便不知道用怎样的“桃子”、“绳子”、“鞭子”和“筛子”来对人才实施有效管理。现实中的许多企业也有自己的人才评估“标准”,但是据我所知,绝大多数企业的人才评估“标准”是纯粹站在企业利益的立场上炮制出来的,并不完全为人才们所认同。不为人才所认同的评估标准不仅不能产生效用,反倒会产生负面作用。
(下载iPhone或Android应用“经理人分享”,一个只为职业精英人群提供优质知识服务的分享平台。不做单纯的资讯推送,致力于成为你的私人智库。)
作者:张诗信
文章相关知识点
评论&&|&& 条评论
畅阅·猜你喜欢Java程序设计(15)
第3章 流程控制
?掌握三种流程控制
?掌握简单的输入输出
?了解三种循环设计方法
?掌握数组、字符串和枚举类型
3.1 面向过程介绍
面向过程的程序设计,每个程序完成一个特定的功能,是通过对数据一系列的加工而实现的。面向过程编程包括两部分:数据结构设计和算法设计。 Pascal之父Nicklaus Wirth提出一个著名公式“算法+数据结构=程序”而获得图灵奖。数据结构是程序处理的对象、数据的表示和组成形式,数组、结构体变量是数据的重要表现形式。算法是对数据进行操作的方法和操作步骤。主要操作有算术运算、逻辑运算、关系运算、函数运算、位运算等操作,在第2章已经介绍。
流程是程序执行的顺序,流程控制有3种基本结构,分别是顺序结构、选择结构和循环结构。1966年Bohm和Jacopini证明:顺序、选择、循环三种结构可以构成任何的算法。面向过程编程方法要求:一个程序只能由三种基本控制结构组成。也就是说,三种基本结构可以有限次组成任何程序,解决任何可以解决的问题。
我们熟悉的C语言就是面向过程的程序设计语言。面向对象程序设计不是对面向过程的程序设计的否定,而是继承与推广。我们学习面向对象程序设计之前,需要掌握面向过程的程序设计。面向对象程序设计的具体算法实现还是要借助面向过程的思想;或者说在微观上,面向对象编程的细节就是面向过程的程序设计,在宏观上是面向对象的思想。所以学习Java面向对象程序设计之前,还是要再温习一下面向过程的程序设计部分。
3.2 数据的输入和输出
一般而言,任何程序都要有输入和输出本部分,没有输入或输出的程序意义不大。
3.2.1 输入语句
在Java 5之前,要实现从标准输入设备(比如键盘)输入数据是不容易的,从Java 5开始引入了一个新类Scanner用于基本数据的输入操作。可以将Scanner看作一个新的复合数据类型,用该类创建一个变量:
Scanner cin=new Scanner(System.in);
然后使用cin变量可以调用方法nextXxx(),其中Xxx可以替换为Boolean、Byte、Short、Int、Long、Float、Double,从命令行接收一个对应的数据。比如cin.nextInt()即可从命令行接收一个整数数据。此外,要使用Scanner类时,需通过“import java.util.S”语句将类Scanner引入当前程序,作用类似于C语言的#include。
例3.1 a+b问题:输入两个整数,输出和。
jshell& Scanner cin=new Scanner(System.in);
cin ==& java.util.Scanner[delimiters=\p{javaWhitespace}+] ... \E][infinity string=\Q∞\E]
jshell& int x=cin.nextInt();
jshell& int y=cin.nextInt();
jshell& System.out.println(x+y)
本程序是国际大学生程序竞赛ACM训练题,请参见北京大学ACM Online Judge:http://poj.org/problem?id=1000。本程序看似简单,却隐含着计算机的基本组成原理和基本工作原理(请参加第0章):cin.nextInt()语句体现了数据输入;System.out.printf(参数)语句体现数据输出;整型变量x和y表示存储数据,x+y进行数据运算,每个语句执行的次序需要流程控制。
[root@centos ~]
Welcome to JShell -- Version 9.0.1
For an introduction type: /help intro
jshell& import java.util.S
jshell& Scanner cin=new Scanner(System.in);
cin ==& java.util.Scanner[delimiters=\p{javaWhitespace}+] ... \E][infinity string=\Q∞\E]
jshell& int x=cin.nextInt(); //输入一个整数
jshell& double y=cin.nextDouble(); //输入一个浮点数
y ==& 3.1415926
3.2.2 输出语句
System.out提供了三种标准输出:换行输出println(),不换行输出print,格式输出printf(),其中printf()是Java5新增的操作,用于与C语言的printf()函数一致,输出格式如表2.5所示。
表3.1 输出格式
格式控制符
输出int类型数据
输出char型数据
输出浮点型数据,小数部分保留6位
输出字符串
输出的int型数据占m列
输出的浮点型数据占m列,其中小数占n位
例3.2 格式化输出。
jshell& import java.util.Scanner
jshell& Scanner cin=new Scanner(System.in)
cin ==& java.util.Scanner[delimiters=\p{javaWhitespace}+] ... \E][infinity string=\Q∞\E]
jshell& double y=cin.nextDouble()
y ==& 3.1415926
jshell& System.out.printf("%f\n",y)
$14 ==& java.io.PrintStream@5025a98f
jshell& System.out.printf("%4.2f\n",y)
$13 ==& java.io.PrintStream@5025a98f
3.3 顺序结构
顺序结构,是程序语句书写的先后顺序,是流程控制语句最简单的一类。上面的两个输入输出程序就是顺序结构。从宏观上看,选择结构和循环结构,甚至是方法(函数),都属于顺序结构。
3.4 选择结构
选择结构也称为分支结构,Java中的选择结构与C语言选择结构类似,可以分为if分支语句和switch分支语句。if语句又可以分为如下3种形式:单if语句、if-else语句、if-else if-else语句,其中if-else if-else语句是if-else语句的推广形式。
3.4.1 if语句
单if语句也称单路分支语句,格式如下:
if(条件表达式)
注意,if后的小括号( )内的条件表达式的值必须是boolean型,与C语言不同。单if分支语句的流程图如图3.1所示。
A(开始)--&B{条件}
B--& |true| D(语句)
D--& E(结束)
B--& |false| E
图3.1 单if流程图
例3.3:通过单if语句实现计算一个数的绝对值。
jshell& import java.util.S
jshell& Scanner cin=new Scanner(System.in);
cin ==& java.util.Scanner[delimiters=\p{javaWhitespace}+] ... \E][infinity string=\Q∞\E]
jshell& double x=cin.nextDouble();
//输入一个数
x ==& -3.14
jshell& if(x&0.0)
jshell& System.out.println("|x|="+x);
3.4.2 if-else语句
if-else语句也称为二路分支语句,格式如下:
(条件表达式){
A(开始)--&B{条件}
B--& |true| D(语句1)
B--& |false| E(语句2)
D--& F(结束)
图3.2 if-else流程图
if-else语句的流程图如图3.2所示。如果if分支或else分支的语句只有一条语句时,可以省略大括号{}。为了提高程序可读性,大括号{}最好不要省略(本书为了节约篇幅,只有一条语句时省去{})。
例3.4:通过if-else语句求解两数最大值问题。
jshell& int x=5,y=3;
jshell& if(x&y){
System.out.println("max="+y);
...& }else{
System.out.println("max="+x);
两数求最大值问题也可以通过三目运算符来实现。
3.4.3 if-else if-else语句
if-else if-else语句并不是新的语句,而是if-else语句嵌套形式,比如:
if(条件1){
//嵌套格式,将else条件又细分为2个条件
if(条件2){
嵌套形式的if-else语句可以直接写成if-else if-else形式:
if(条件1){
}else if(条件2){
}else{//其他条件
上面的结构很容易看出三路分支结构,可以添加若干个else if分支,形成if-else if-else的多路分支结构,流程图如图2.20所示。
图2.20 if-else if-else流程图
例3-5:输入一个年龄数据,判定年龄的不同范围,输出对应的内容。
jshell& Scanner cin=new Scanner(System.in);
cin ==& java.util.Scanner[delimiters=\p{javaWhitespace}+] ... \E][infinity string=\Q∞\E]
jshell& int age=cin.nextInt();
age ==& 20
jshell& if(age&0 && age &18){
//条件1:0~18
System.out.println("小孩");
...& }else if(age&=18 && age&28){
//条件2:18~28
System.out.println("青春十年");
...& }else if(age&=28){
//条件3:大于28岁
System.out.println("老了");
...& }else{
System.out.println("其他");
例3-6:阶梯电价问题。
居民月用电量分为三个档次:第一档为230度,0.5283元/度;第二档为231-400度,在第一档电价的基础上,每度加价0.05元;第三档为高于400度,在第一档电价的基础上,每度加价0.3元。如果本月用电450度,需要支付多少电费?
jshell& double x=450;
x ==& 450.0
jshell& if(x&0){
...& }else if(x&=230){
y=x*0.5283;
...& }else if(x&=400){
y=x*0.5283+(x-230)*0.05;
...& }else{
y=x*0.5283+170*0.05+(x-400)*0.3;
jshell& System.out.println(y);
3.4.4 swith语句
switch语句的格式如下,其中switch语句中的“表达式”的值和“常量i”必须是byte、short、int、char、枚举型中之一。从Java 7开始,switch增加支持String类型数据。
switch(表达式){
case 常量1:
. . . . . .
case 常量n:
例3-7:请根据一个年份和月份,求出该月的天数。
jshell& int year=2020,month=2;
year ==& 2020
month ==& 2
jshell& switch (month){
//2月份,需要进行闰年判定
if((year%4==0&&year%100!=0)||(year%400==0)){
System.out.println("29");
System.out.println("28");
}case 4: case 6: case 9: case 11:{
System.out.println("30");
}default:{
System.out.println("31");
程序说明如下:
1)break语句跳出switch语句;
2)多个case可以共享同一个break语句;
3)每个case后面的语句是一个代码块,不需要{}括起来;
判定闰年的条件 if((year%4==0&&year%100!=0)||(year%400==0)) 。
3.5 循环结构
C语言具有while、do-while和for 3种循环结构,Java语言继承了这3种循环结构。
3.5.1 while循环
while循环语法结构格式:
(循环条件){
循环体语句;
while语句执行流程如图2.23所示,执行规则如下:
1)判断循环条件值,如果为true,则执行第2)步,否则执行第3)步;
2)执行循环体语句,完成后再回到第1)步;
3)结束while语句执行。
例3-8:求1+2+3+…+n的和。
可以使用while循环语句来求解,定义一个变量sum保存和(初始值为0),然后通过循环语句把1到n的整数加到sum里即可,编写代码如下
jshell& int i=1,n=100,sum=0;//求和sum存0
jshell& while(i&=n){
jshell& System.out.println(sum);
需要注意的是:while循环中,对条件表达式的计算要比循环体多执行一次,最后一次循环执行循环条件不满足而退出循环。
3.5.2 do-while循环
do-while循环语法格式:
循环体语句;
}while(条件);
do-while执行流程如图2.24所示。当执行到do时,立即执行循环体一次,然后再判定循环条件。如果条件不成立(false),则循环结束;则如果条件成立(true),则继续执行循环体,然后再判断循环条件。do-while循环与while循环的区别:do-while循环至少执行一次循环体。
例3-9:求n!阶乘。
该问题可以化为求解1*2*…*n连乘积。下面使用do-while循环来求解,定义一个变量sum用于保存乘积值(初始值为1),然后通过循环语句把1到n每个数字乘到sum中,代码如下。
jshell& int i=1,n=10,sum=1;//求积sum存1
jshell& do{
sum*=i;i++;
...& }while(i&=n);
jshell& System.out.println(sum);
程序说明:保存乘积的变量sum初始值为1;阶乘值增长速度很快,一般int型变量保存12以内的阶乘值。
3.5.3 for循环
for循环语法格式:
(初始化语句; 循环条件; 迭代语句){
循环体语句;
for循环语句的流程如图2.27所示,执行规则如下:
1)执行初始化语句,整个循环只执行一次;
2)判断循环条件,如果结果true,则执行第3)步,否则循环结束;
3)执行循环体语句;
4)执行迭代语句,跳转到第2)步重复执行。
其中,初始化语句可以定义for循环的循环变量。比如下面代码:
int sum=0;
for(int i=1;i&=100;i++)
循环变量i属于for循环,属于局部变量,在for循环以外不可见。C语言在C99标准下才支持这种形式。
相对while和do-while循环,for循环使用的频率最高,for循环可以替代while和do-while循环。在现在的软件代码中do-while循环使用越来越少,建议多使用for循环。
例3-10:求1+2!+3!+…+20!的值。该问题相当于求1+2+3+…+20之和和n!阶乘问题的复合。下面使用for循环来解决这个问题。很自然地我们想到先求前i项之和,再计算第i+1的阶乘;然后把第i+1的项加到前i 项和中。这样需要写成双重循环,效率低下。通过分析发现在求第i+1项阶乘时,其实上一步已经得知i项的阶乘,所以得到公式:
每项公式:ti+1=ti*(i+1)
求和公式:Si+1=Si+ti
编写程序如下,由于20!值很大,定义double型变量保持每项值和前i项之和。
jshell& double s=0,t=1;
//和0,积1
jshell& for(i=1;i&=n;i++){
//第i项的值
//前i项的和
jshell& System.out.println(s);
3.5.4 多层循环
对于一些复杂的问题需要用多重循环来解决。
例3-11:打印九九乘法表。
九九乘法表是个二维图形,需要双层循环来实现。一共九行,需要一个循环结构控制九行的输出;其中每一行(比如第i行),又可以通过一个内层循环实现“输出第i行”。编写程序,代码如下。
jshell& for(int i=1;i&=9;i++){//一共9行
for(int j=1;j&=i;j++) //打印第i行
System.out.print(j+"*"+i+"="+j*i+" ");
System.out.println();//打印完第i行,换行
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
读者可能发现上面结果输出有点小缺陷,第4行与第5行没有对齐,大家可以通过System.out.printf()格式输出来解决。
例3-12:打印出以下图形:
*******************
*****************
***************
*************
***********
分析上面图形,发现一共10行;然后分析每一行,先输出一定量空格,再输出一定量的“*”号。可以得到外层循环结构:
for(int i=1;i&10;i++){
输出一定量空格;
输出一定量“*”号;
对于第i行,空格与“”的数量关系是:空格i-1个,“”号19-2i个。可以通过2个循环实现输出。
根据上面思路编写程序如下:
jshell& for(int i=1;i&10;i++){//一共10行
for(int j=0;j&i-1;j++)
//输出i-1个空格
System.out.print(" ");
for(int k=0;k&19-2*i;k++)
//输出19-2i个“*”号
System.out.print("*");
System.out.println();
//完成第i行,换行
*****************
***************
*************
***********
3.6 控制转移
控制转移语句有return语言、break语句、continue语句以及标号,其中ruturn语句用于方法的返回,下面重点介绍其他三个。
3.6.1 break语句
在switch语句中,break用来跳出switch,前面已经演示过了。break语句也可以在循环语句for、while、do-while中使用,表示跳出当前循环。
例3-13:素数判定。
素数又称质数,是一个大于1的自然数,除了1和它本身外没有其他的因子,素数在数论和密码学中有着很重要的地位。对于一个自然数n,最为简单的素数判定算法就是在2~ n-1中查找是否有一个数能整除n;若存在则说明n不是素数;若不存在这样的数,则n就是素数。
根据这个思路,使用循环结构和break语句即可完成素数判定算法,编写程序Prime1.java,代码如下。
jshell& int n=97;
jshell& for(int i=2;i&n;i++){//循环查找因子
if(n%i==0){
//找到因子,说明n不是素数
jshell& System.out.println(flag)
例3-14:素数判定优化算法。
上面程序时间复杂度是O(n)。进一步分析素数,大于1的自然数n可能的因子:
\sqrt{n} \sqrt{n}
读者朋友可以发现,因子是成对出现的,如果出现因子2,那一定有因子n/2。所以只需要验证2~之间是否存在因子即可,如果存在一个数i满足条件n%i==0,则说明i是因子,可以判定n不是素数。优化素数判定算法代码如下。
jshell& int n=97;
jshell& for(int i=2;i&=Math.sqrt(n);i++) {
if(n%i==0){
jshell& System.out.println(flag);
优化后的素数判定算法的时间复杂度降为O(n1/2)。
3.6.2 continue语句
continue语句用在循环语句中,可以结束本次循环,进入当前循环的下一次循环。
例3-15:求1到100不能被7整除的数之和。可以通过循环语句与continue语句实现,当i%7 = = 0时,说明i被7整除,结束本次循环当,进入i+1次循环。根据这个思路编写程序代码如下。
jshell& int sum=0;
jshell& for(int i=1;i&=100;i++){
if(i%7==0)
//被7整除,跳过
jshell& System.out.println(sum)
3.6.3 标记
相对C语言,Java的break和continue语句功能增强。单独是break或continue时,只能跳出一层循环,只能从循环体内向外跳转;当break或continue和标记结合使用时,可以跳到标记所处位置。标记是用户自定义的标识符,标记语句必须和某一循环体匹配使用,且在该循环体上方。
例3-16:求解n~m之间的素数,n
jshell& int n=10,m=20,r;
jshell& next:
//标号,外层循环
...& for(int i=n;i&=m;i++){
for(int j=2;j&=r;j++)
if(i%j==0) continue next; //i不是素数,进入下次循环验证i+1
System.out.print(i+"
//以字符串形式输出素数
程序说明:当遇到i%j==0时,执行“”语句,跳转到“next:”标号标记的外层循环,也就是结束外层循环的当次循环,进入外层循环的下一次循环。如果是“”语句,则跳转到next标记的外层循环,结束外层循环。
3.7 循环设计
循环设计是计算机解决问题的一个重要特征。对人来说,循环结构是三种流程控制中最复杂的语句,复杂的程序算法一般都离不开循环结构,人们对于周而复始的动作会产生严重的疲惫感,缺乏激情。对计算机来说,循环结构是强项,可以高效率不厌其烦的重复做某件事。在程序设计中,人们习惯于将复杂的难以解决的问题求解过程转化为易于理解的操作的多次重复。
在循环算法设计中,比较常见的方法有穷举法、迭代法和递推法。
3.7.1穷举法
穷举法就是对问题的所有可能状态进行一一测试,直到找到问题的解或者全部可能状态测试完为止(无解)。也就是,通过循环语句遍历(穷举)所有可能的情况,通过选择结构语句判定当前循环条件是否为所求问题的解。
例3-17:爱因斯坦阶梯问题。
大物理学家爱因斯坦曾给他的朋友出了这样一道题:有一个阶梯,若每步跨2阶,最后余1阶;若每步跨3阶,最后余2阶;若每步跨5阶,最后余4阶;若每步跨6阶,最后余5阶。当每步跨7阶时,刚好达到阶梯顶。问共有多少阶梯。
算法设计:设变量ladders表示阶梯数,根据已知条件有:
由5)条件知阶梯数是7的倍数,可知阶梯数是7,14,21,28,…数列中的某个项,并且阶梯数满足条件是“ladder%2= =1 && ladder%3= =2 && ladder%5= =4 &&ladder%6= =5”,可以进行穷举测试。由于不知道循环的次数,可以将循环条件设置为true进行“永真循环”;当阶梯判定条件满足时,使用break结束循环即可。
按照这个思路编写程序Ladders1如下,编译执行结果如图2.35所示。
jshell& for(int ladder=7;ladder+=7){ //永真循环,穷举测试
//满足阶梯条件,结束循环
if(ladder%2==1 && ladder%3==2 && ladder%5==4 &&ladder%6==5){
System.out.println("ladders="+ladder);
ladders=119
可以对上面程序进一步优化,由条件1)知道阶梯数一定为奇数,可以将7,14,21,28,…数列中的数去掉一半,那么算法执行时间减半,优化后的代码如下。
jshell& int ladder=7;
ladder ==& 7
jshell& while(ladder%3!=2 || ladder%5!=4 ||ladder%6!=5){
//不是阶梯数的条件
ladder+=14;
//每次递增14,执行时间减半
jshell& System.out.println("ladders="+ladder);
ladders=119
判定条件“ladder%3!=2 || ladder%5!=4 ||ladder%6!=5”表示不是阶梯数的条件。
3.7.2 递推法
对于一个数列,如果已知它通项公式,那么求出数列的某项的值是很容易的。但是许多情况下,数列的通项公式是难以得到的,甚至无法得到。对于一些数列,虽然通项公式难以找到,但可以找到相邻的若干项之间的关系。由已知项,再借助这个特定的关系可以逐项推算出后继项或前驱项的值,这种关系即是递推公式。递推公式又可以分为顺推和逆推两种方式。递推法关键是找到起点(已知项)和递推公式。
由已知项和递推公式,逐项求出后继项,称为顺推。比如著名的Fibonacci数列(也称黄金分割数列)的递推公式就可以由已知项逐项推出后继项。
例3-18:数学家Fibonacci在《算盘全集》中提出一个兔子繁殖的问题:设有一对新生兔子,从第三个月开始它们每月都生产一对小兔子。假设兔子没有死亡,按此规律一年后共有多少只兔子。其中,每对兔子均是一公和一母。
先列举出前面若干月兔子数:
第一个月,1对小兔子;
第二个月,1对小兔子,就是上个月的小兔子;
第三个月,这一对老兔子生成一对小兔子,老兔子数加上小兔子数一共2对;
第四个月,第一对老兔子又生了一对小兔子,共有3对(1+2=3)兔子;
第五个月,第一对老兔子又生了一对小兔,第三个月出生的小兔成熟也生下了一对小兔,所以新生兔2对;再加上老兔子数,也就是上个月的兔子数,本月5(2+3=5)对兔子。
第六个月,第一对兔子以及第三、四月生下的兔子也都各生下了一对小兔,新生兔3只;再加上这个月和原先的5对兔子共有8对(3+5=8)兔子。
分析这个数列:1,1,2,3,5,8,……。可以发现从第三个月开始每个月的兔子数是两部分组成,老兔子数加上本月新兔子数。老兔子数即是上个月的兔子数;本月新生兔子数为上上月兔子数,因为上上月的兔子在本月均可生成一对小兔子,而上个月新生兔子在本月还不能生产小兔子。可以得到该数列的递推公式:
fib_{1}=fib_{2}=1
fib_{n}=fib_{n-1}+fib_{n-2} , n&=3
有了起点和递推公式很容易写出求解Fibonacci数列的程序,代码如下。
jshell& int f1,f2,f;
jshell& f1=f2=1;
jshell& for(int i=3;i&=12;i++){
//从第三项开始,递推求出下一项的值
//第i项的值
System.out.print(" "+f);
2 3 5 8 13 21 34 55 89 144
由已知项和递推公式,逐项求出前驱项,称为逆推。比如猴子吃桃问题就是逆推。
例3-19:猴子吃桃问题。有一堆桃子,第一天猴子吃了一半,还嫌不够又多吃了一个;第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求最初这堆桃子有多少个?
分析: 设xn 表示某一天桃子数,则这天的前一天桃子数为
x_{n-1}=(x_{n}+1)*2
获得递推公式;又知第十天桃子数x10=1 ,即是起点值。
按照这个思路编写程序代码如下
jshell& int i,a=1;
jshell& for(i=9;i&=1;i--)
a=(a+1)*2;
jshell& System.out.println(a);
3.7.3迭代法
在《数值分析》中,迭代是重要的算法基础。许多数学问题都可以转化为解方程F(x)=0的实数根的问题。求根可以直接从方程出发,逐步缩小根所在的区间,把根的近似值逐步精确到指定的精度为止,这就是迭代算法。
(1)二分迭代法
二分迭代法是一种简单的迭代法,基本思想如图2.39所示。对于方程y=f(x),先确定一个范围(x1,x2),使得f(x1)与f(x2)的符号相反,则方程f(x)=0在(x1,x2)内至少存在一个根。取
x_3=\frac{1}{2}(x_1+x_2)
作为近似根。然后在x1 与x2中舍去函数值与f(x3)同号者,比如图中x2的函数值与f(x3)同符号,舍去x2,则根必然存在于(x1,x3)区间内。然后重复上面过程,当xn与xn+1差距小于给定的误差时,可以认为xn 就是所求方程的一个逼近根。
显然二分迭代法的迭代公式就是:
x_{n+1}=\frac{1}{2}(x_n+x_{n-1})
例3-20:用二分迭代法求解方法2x3- 4x2 +3x- 6=0在(-10,10)之间的根。
f(x)=2x3- 4x2 +3x- 6的图像如图2.40所示。f(-10)= -2436,f(10)=1624,f(-10)与f(10)符号相反,则说明在(-10,10)区间内必然存在一个根。运用二分迭代法,编写程如下。
jshell& double x0,x1,x2,f0,f1,f2;
x0 ==& 0.0
x1 ==& 0.0
x2 ==& 0.0
f0 ==& 0.0
f1 ==& 0.0
f2 ==& 0.0
jshell& x1=-10;x2=10;
//输入2个区间
x1 ==& -10.0
x2 ==& 10.0
jshell& f1=((2*x1-4)*x1+3)*x1-6;
f1 ==& -2436.0
jshell& f2=((2*x2-4)*x2+3)*x2-6;
f2 ==& 1624.0
jshell& do{
//求二分点(x0 , f0)
x0=(x1+x2)/2;
f0=((2*x0-4)*x0+3)*x0-6;
if(f0*f1&0){
//二分点f0与f1异号,根存在于(x1,x0)内
//f0与f同号号,根存在于(x0,x2)内
...& }while(Math.abs(f0)&=1e-6);
//根的函数值的精度是0.000001
jshell& System.out.printf("x=%6.2f\n",x0);
$12 ==& java.io.PrintStream@3bfdc050
(2)牛顿切线法
牛顿切线法也称为切线迭代法,这是一种比一般迭代法(比如二分迭代法)收敛速度更快的迭代法,其基本思想如图2.42所示。
设xn是方程f(x)=0的根x0附近的一个猜测根,通过点(xn,f(xn))做f(x)的切线。切线方程为:
y = f(x_n)+{f(x_n)}'(x-x_n)
它与x轴的交点是方程
f(x_n)+{f(x_n)}'(x-x_n)=0
x_{n+1}=x_n-\frac{f(x_n)}{{f(x_n)}'}
这就是牛顿迭代法的迭代公式。
例3-21:用牛顿迭代法求解方法2x3- 4x2 +3x- 6=0在1.5附近的根。
f(x)=2x^{3}-4x^{2}-6=((2x-4)x+3)x-6
{f(x)}'=6x^{2}-8x+3=(6x-8)x+3
即可使用牛顿迭代公式求解,编写程序如下。
jshell& double x0,x=1.5,f,f1;
x0 ==& 0.0
f1 ==& 0.0
jshell& do{
f=((2*x0-4)*x0+3)*x0-6;
//函数值f(x0)
f1=(6*x0-8)*x0+3;
//导数值f'(x0)
x=x0-f/f1;
...& }while(Math.abs(x-x0)&=1e-6);
//根的精度是0.000001
jshell& System.out.printf("x=%6.2f\n",x);
$6 ==& java.io.PrintStream@3e6fa38a
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:140867次
积分:3334
积分:3334
排名:第11140名
原创:195篇
评论:55条
阅读:1326
文章:18篇
阅读:5619
文章:76篇
阅读:38667
(14)(19)(17)(22)(13)(10)(34)(16)(19)(13)(13)(7)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'}

我要回帖

更多关于 锦衣卫大人桃子君君 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信