作者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
→ game0416:時間總是過的很快(遠目) 12/25 00:23
※ 編輯: game0416 來自: 120.127.47.200 (12/25 10:04)
推 Arashinoon:辛苦了 另外 f[i]=g[i]=fg[i];應該要=0 是吧? 12/26 01:18
※ 編輯: game0416 來自: 58.114.67.71 (12/26 10:01)
→ game0416:對<(_ _)> 12/26 10:02
→ gcobc12632:不知道如果把x項係數設為0的時候還會顯示出來 12/26 11:28
→ gcobc12632:這樣的作業能拿幾分呢( ̄ー ̄;) 12/26 11:28
→ game0416:沒有問題的(啥 12/26 12:06