作者game0416 (凤狼)
看板NTUE-CS102
标题Re: [闲聊] 程设作业
时间Fri Dec 25 00:21:25 2009
嗯...所以我还是被说服写下去了
我只是觉得写这串有种没人看跟变成"都是我在写"的感觉Orz
好吧,这次两项作业...第一项作业草草带过,第二项作业我不知道会写多少
所以送出时间在死线边缘就不好意思了...(远目)
: 反正我自己的code我没优化到底,有这样的交换条件,就不要在意了(拖走)
然後这次我没有看其他人的code,有哪边能改进或加上的还请多告知<(_ _)>
有问题也问出来没关系,至少比乱用乱写好
因为第一项作业大部分人应该都写完了,所以就不防雷
顺便说明一下阵列内容好了...
首先,题目要求是 输入一串数字到阵列、反转并复制到另外一串阵列
然後输出该反转之阵列
嗯...我不知道大家怎麽想的,总觉得好像很多人想的很复杂
看着题目,就把它直接先拆成
1.输入到阵列
2.反转到另外一个阵列
3.输出阵列
这样三步去做就好
1. 3. 应该都不是太大的问题,问题会出在2.怎麽写
不过就算这样,还是多说明一次如何利用回圈处理阵列,这边只提出怎麽输入
输出用类似方法比照,举一反三各位应该没问题qq
先来宣告一个
int a[
10];
┌—┬—┬—┬—┬—┬—┬—┬—┬—┬—┐
|0|1|2|3|4|5|6|7|8|9|
├—┼—┼—┼—┼—┼—┼—┼—┼—┼—┤
|?|?|?|?|?|?|?|?|?|?|
└—┴—┴—┴—┴—┴—┴—┴—┴—┴—┘
这应该不是问题..
以使用阵列来说,我是建议不要像哪边写的浪费空间多宣告一个方面人脑直观使用..
就从
0开始用比较好
下面是一小段范例输入写法
for (
int i=
0;i<
10;i++)
cin >>a[i];
这样可以做到每输入一个数字後,结束该次回圏、进入下一次回圈
顺便提一下有人问的问题:「彦廷为什麽可以一次输入一排数字?」
当时彦廷是这样输入、程式这样输出的
输入:1 2 3 4 5 6 7 8 9 10
输出:10 9 8 7 6 5 4 3 2 1
大部分同学会是
1 嗯...排版方便写这边(拖走)
2 cin分隔输入的方式,是判断有没有
3 换行字元(\n、\r..吧,我记得有两个)
4 还有空白,所以可以直接用空白分隔输入
5 大量数值..此外,妥善利用复制贴上
6 也能简化测试过程,这个下次谈(滚走)
7
8
9
10
10 9 8 7 6 5 4 3 2 1
嗯,不是大问题的地方这样就好
再来是最容易出现问题的地方:「要怎麽反转阵列?」
比较可惜之前没有做过印星星的练习,这样突然冒出来要用的小技巧可能不好想
所以先讲用两个变数来做的方法...
假订a[
10]的内容是
┌—┬—┬—┬—┬—┬—┬—┬—┬—┬—┐
|0|1|2|3|4|5|6|7|8|9|
├—┼—┼—┼—┼—┼—┼—┼—┼—┼—┤
|0|1|2|3|4|5|6|7|8|9|
└—┴—┴—┴—┴—┴—┴—┴—┴—┴—┘
b[
10]我们会期待长成
┌—┬—┬—┬—┬—┬—┬—┬—┬—┬—┐
|0|1|2|3|4|5|6|7|8|9|
├—┼—┼—┼—┼—┼—┼—┼—┼—┼—┤
|9|8|7|6|5|4|3|2|1|0|
└—┴—┴—┴—┴—┴—┴—┴—┴—┴—┘
因为是两个变数
这里用点技巧...一个变数i控制a[i],一个变数控制b[j]
然後让a[i]传值进b[j]这样
基本上两个变数都跟着for回圈走...这里分两种写法,後者应该算少见
int i=
9,j=
0;
for (i;i>=
0;i--)
b[j++]=a[i];
这算是比较简单的作法,也可以颠倒或用while做类似效果
後面这个原则上看看就好,不要在意...除非真的很想做什麽特殊效果等等
不然我是建议不要学(汗)
for (
int i=
9,j=
0;i>=
0;i--,j++)
b[j]=a[i];
此外,也可以只用一个变数来做到这件事
这里不说明这个想法...至少稍微想想吧
for (
int i=0;i<
10;i++)
b[i]=a[
9-i];
第一项作业大概到这边就差不多
剩下的部分应该都变得出来
另外出个延伸基础练习
如何可以任意印出N层星星?
分别有以下三种方式的星星印法:
* * *
** ** ***
*** *** *****
**** **** *******
***** ***** *********
欢迎来到第二项作业
首先我还是要黑特一下出题就出题,好好设定标准输出入格式是不好吗!
出题不清不楚,得到的答案本来就会不清不楚嘛!
正所谓Junk In, Junk Out ...... (被打昏拖走)
总之题目要求是:
给人输入一个最高10次的多项式f(x)各项系数,以及g(x)各项系数
然後输出f(x)+g(x)的结果
原则上只知道输出时用 x^n 表示n次项
嗯...所以这题就这样拆解,介面不论
1.输入f(x)
2.输入g(x)
3.f(x)+g(x)
4.输出f(x)+g(x)
前两个应该算一样的
一起来...
输入方式可以很简单:
照降幂依序要求输入,或给予指定输入的机会
前者是大部分直观作法,因为就只是单纯延伸上一题的输入方法
因为要顾虑使用者可能不是从x^10 (吧?还^9来着..)输入
我看到的大多数人选择先让人输入一个最高次,然後从最高次开始进行回圈
讲到这里,应该可以猜的出来这样做需要些什麽了
1.一个用来记录系数的阵列
2.一个给人输入最高项的变数
3.一个用来输入的回圈
所以就比照前一项作业去写,然後加点变化就好
换页前先想想怎麽做._.
int m;
cin >>m;
for (
int i=
0;i<m;i++)
cin >>f[i];
这样是从0次项开始输入,降幂的话则把0跟m对调就好
其次,是让人指定输入特定项次
所以使用者来说做的事情是:1.指定项次 2.输入系数
要这样做,基本上我建议用
while做...
然後输入特定项次时视为跳出指令,比如说超过范围
要这样做就需要
1.还是用来装系数的阵列
2.一个用来装指定项次的变数
3.一个无穷回圈
行数不够,见下页
int m;
while (cin >>m)
if (m>10 || m<0)
break;
else
cin >> f[m];
用法记得都说明过,所以(略)
跳出输入回圈後面看你想接什麽,决定程式内容长怎样这样
做完1. 2.的输入再来是要做f(x) g(x)系数总和
这边的话...这题可以省空间,把总和塞回f(x)或g(x)其中一个阵列
这里就先另外设一个fg[
10]来存放,希望这样会比较简单理解
写这段可能复杂可能简单,重点是想法有没有出来
我没想到除了这样写以外的方法...有其他方法请提出来看看<(_ _)>
这里就防个雷
先来看f(x)跟g(x)的阵列,这里是用第N项放在阵列第N-1格上
f(x)
┌—┬—┬—┬—┬—┬—┬—┬—┬—┬—┐
|0|1|2|3|4|5|6|7|8|9|
├—┼—┼—┼—┼—┼—┼—┼—┼—┼—┤
|5|5|8|1|3|2|8|4|3|1|
└—┴—┴—┴—┴—┴—┴—┴—┴—┴—┘
g(x)
┌—┬—┬—┬—┬—┬—┬—┬—┬—┬—┐
|0|1|2|3|4|5|6|7|8|9|
├—┼—┼—┼—┼—┼—┼—┼—┼—┼—┤
|9|8|6|7|5|4|2|3|8|2|
└—┴—┴—┴—┴—┴—┴—┴—┴—┴—┘
嗯..你会注意到每一项都是对照在一起的
所以我们的fg(x)系数可以看成
┌—┬—┬—┬—┬—┬—┬—┬—┬—┬—┐
|0|1|2|3|4|5|6|7|8|9|
├—┼—┼—┼—┼—┼—┼—┼—┼—┼—┤
|14|13|14|8|8|6|10|7|11|3|
└—┴—┴—┴—┴—┴—┴—┴—┴—┴—┘
这样看不知道有没有想法?
其实就是可以这麽乾脆的写个回圈把每一个都刷过去全部一起加一加
fg[x]=f[x]+g[x]就过去了
然後讨论...遇到两边最高项次不同该怎麽做?
答案也是:不要想太多,刷下去就对了
比如说,g(x)的最高项是4,我们会认为阵列内容是
f(x)
┌—┬—┬—┬—┬—┬—┬—┬—┬—┬—┐
|0|1|2|3|4|5|6|7|8|9|
├—┼—┼—┼—┼—┼—┼—┼—┼—┼—┤
|5|5|8|1|3|2|8|4|3|1|
└—┴—┴—┴—┴—┴—┴—┴—┴—┴—┘
g(x)
┌—┬—┬—┬—┬—┬—┬—┬—┬—┬—┐
|0|1|2|3|4|5|6|7|8|9|
├—┼—┼—┼—┼—┼—┼—┼—┼—┼—┤
|9|8|6|7|5|X|X|X|X|X|
└—┴—┴—┴—┴—┴—┴—┴—┴—┴—┘
然後我们期待处理後的结果是长这样
┌—┬—┬—┬—┬—┬—┬—┬—┬—┬—┐
|0|1|2|3|4|5|6|7|8|9|
├—┼—┼—┼—┼—┼—┼—┼—┼—┼—┤
|14|13|14|8|8|2|8|4|3|1|
└—┴—┴—┴—┴—┴—┴—┴—┴—┴—┘
嗯,编译、执行这样的code後我们会发现并不会如我们所期望
结果是堆乱七八糟的数字...因为那些X并没有预设值,是记忆体中不明的数值
避免这样的问题,我们在宣告三个阵列时,就将每个位置预设为0避免出问题
f[
11]={0,0,0,0,0,0,0,0,0,0,0};
g[
11]={0,0,0,0,0,0,0,0,0,0,0};
fg[
11]={0,0,0,0,0,0,0,0,0,0,0};
这样写某种角度来说很麻烦,所以这里用个手段:回圈
用回圈全部暴力刷成0就好了,这招也可以用在其他时候进行归零等作业
for (
int i=
0;i<
11;i++)
f[i]=g[i]=fg[i]=
0;
嗯...所以我想大概到这完成加总
再来是(中略)的输出部分
因为什麽都不知道,所以这边讲讲有听说在注意的事情...是说我的都还没改上-____-
: 现在是23:48,我不想改了Orz 没时间改(滚动)
1.最後面多出来的+号
2.最前面多出来的+号
3.系数为0跳过
4.系数为负时多出来的+号
5.…我忘记我想讲什麽了Orz
不管怎样,这里我是直接从最高次项刷
不想这样做的话前面做个判断,决定最高项在哪,从最高项开始做
全部就是利用if跟else if处理...
前两者是输出方式的问题,可能是把输出+直接放项次前面或後面
这里就判断 1.这是不是最後一项 2.这是不是最高项
: ...为什麽我觉得讲解起来发现这越来越ㄊㄇ的难写完
所以说...直观就是在输出前多一个回圈检查
1.最高项在哪
2.最後项在哪
可以做出这样的设定...这应该不算太单纯的想法-____-
预设最後项在10、最末项在0,确保"两者一定会被改掉"
int max=
0,min=
10;
for (
int i=
0;i<
11;i++){
if (fg[i]!=
0 && i<min)
min=i;
if (fg[i]!=
0 && i>max)
max=i;
}
所以就能做出输出回圈由最高项刚好输出到最末项
其中利用if判断是否在最高项、最末项就能避免掉多出来的+号
中间这个为0时跳掉...if判断解就好,没什麽好讲的
系数为负...就与前面一起并立去判断就好
以下就附上这段大致的样子...因为我想不到怎样可以明确讲解-_____-
for (
int i=max;i>=min;i--)
if (i==max)
cout <<fg[i] <<
"x^" <<i;
else if (fg[i]<
0 && i==min)
cout <<' ' <<fg[i] <<
"x^" <<i <<endl;
else if (fg[i]<
0)
cout <<' ' <<fg[i] <<
"x^" <<i;
else if (fg[i]>
0 && i==min)
cout <<
" + " <<fg[i] <<
"x^" <<i <<endl;
else if (fg[i]>
0)
cout <<
" + " <<fg[i] <<
"x^" <<i;
...印象中还有什麽问题可以顾虑到...
这段else if的理解各自努力看看..至少当作学习理解程式流程去理解看看吧
反正就是利用if else的关系,去调整判断顺序进行输出的调整
就像老师当时讲的...有联集者,集合越大的摆越後面就是了
这里输出都不使用>=0 <=0,刚好==0时就会跳过该次回圏这样
--
红白本命
○楽园の巫女
博丽 霊梦 职业:博丽神社の巫女さん
Hakurei Reimu 能力:主に空を飞ぶ程度の能力
@东方project系列
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 115.43.35.33
1F:→ game0416:时间总是过的很快(远目) 12/25 00:23
※ 编辑: game0416 来自: 120.127.47.200 (12/25 10:04)
2F:推 Arashinoon:辛苦了 另外 f[i]=g[i]=fg[i];应该要=0 是吧? 12/26 01:18
※ 编辑: game0416 来自: 58.114.67.71 (12/26 10:01)
3F:→ game0416:对<(_ _)> 12/26 10:02
4F:→ gcobc12632:不知道如果把x项系数设为0的时候还会显示出来 12/26 11:28
5F:→ gcobc12632:这样的作业能拿几分呢( ̄ー ̄;) 12/26 11:28
6F:→ game0416:没有问题的(啥 12/26 12:06