作者yantchen (球童Yanting)
看板NTUE-CS102
標題[閒聊] 希加佳
時間Sun Jan 17 21:21:45 2010
鳳狼大大前面PO過一篇了
這篇就簡單講 如果是我改的話 我會注意的點
跟我看到的問題好了
---
第一題 解ax^2+bx+c=0的x
我想應該沒有人用 因式分解 來解題吧
有的話請受小弟一拜 XD
公式解
-b ±√(b^2-4ac)
x = --------------------
2a
這題考的地方有兩個
1. 會不會把數學式子轉成程式
2. 會不會注意負數開根號 除以零 之類的問題
開根號 請看課本6-30頁 ( sqrt 要 #include<cmath> )
大部分的人都做到 1 了 但是 2 卻沒有注意到
先看一下下面的程式
double a, b, c, d;
cout<<"請輸入 a,b,c 程式將解出 ax^2+bx+c=0 的 x :";
cin>>a>>b>>c;
d=sqrt(b*b-4.0*a*c);
if(b*b-4.0*a*c<0)
{
cout<<"無實數解";
}
else
{
cout<<"x= " << (-b+d)/(2*a) <<" or "<< (-b-d)/(2*a);
}
再看程式2
double a, b, c, d;
cout<<"請輸入 a,b,c 程式將解出 ax^2+bx+c=0 的 x :";
cin>>a>>b>>c;
d=b*b-4.0*a*c;
if(d<0)
{
cout<<"無實數解";
}
else
{
d=sqrt(d);
cout<<"x= " << (-b+d)/(2*a) <<" or "<< (-b-d)/(2*a);
}
有看出差異嗎?
在於 sqrt 使用的時機
因為 sqrt 只能開正的 ( 虛數內建的 sqrt 不支援 課本有說 )
所以 必須在 sqrt 之前 先檢查 再開根號
類似的例子例如
double h, w;
cout<<"請輸入身高(公尺) 體重 計算BMI :"
cin>>h>>w;
cout<<"你的BMI是"<<w/h/h;
要是哪個傢伙他把身高打成0
你就得去跟微軟回報了
比較好的作法是
cin>>h>>w;
if(h==0) cout<<"除出來是無限大耶 你一定比神豬還胖";
else cout<<"你的BMI是"<<w/h/h;
---
第二題 字串排序
字典順序: 比較兩字串的第一個字 若有大小差異就是這兩字串的大小差異
若相同 則比較第二個字 以此類推
字的大小怎麼比較?
電腦裡面 每個字都有個代碼 英文的部份叫做 ascii
例如 A=65, B=66, a=96, d=100
所以比較字元的時候
char c1='a', c2='d'
if(c1>c2) // 他會自動轉成 96>100 = false
所以字典順序是這樣
char s1[]="june", s2[]="july", s3[]="may", s4[]="may";
去比較 s1跟s3的話
先比較第一個字 s1是j, s3是m, j<m 所以 s1<s3
比較 s1跟s2的話
第一個字 s1是j s2是j j=j 所以要比較第二個字
第二個字 s1是u s2是u u=u 好衰 還要比第三個
第三個字 s1是n s2是l n<l 所以 s1<s2
這樣字典順序懂了吧~
但要是兩個字串根本一樣勒
比較 s3跟s4
第一個字 s3=m s4=m 比下一個
第二個字 s3=a s4=a 比下一個
第三個字 s3=y s4=y 比玩了 所以 s3==s4
但是 這題根本不用這樣做= =+
請看課本 7-19
字典順序只是個幌子
課本 7-19 有提到 C++ 提供的 strcmp 函數的功能
"函式會取兩字串的第一個字元相減, 如果為0則比較下一個字元
直到差不為零便傳回差值"
這不就是上面提到的作法嗎 XD
回來看題目
排序 -> 請回想兩個迴圈的氣泡排序
先看排序數字
int i,j,n,t;
int a[
1000]; // 最多可存
1000個數字
cout<<"有幾個數字?";
cin>>n;
for(i=0;i<n;i++) cin>>a[i];
for(i=0;i<n;i++){
for(j=0;j<n-1;j++){
if(
a[j]>a[j+1]){
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
換成字串 看結果你就會發現根本是一樣的作法
int i,j,n;
char a[
1000][
100]; // 最多可存
1000個名子 每個名子
100個空間
char t[
100]; // 交換用
cout<<"有幾個名子?";
cin>>n;
for(i=0;i<n;i++)
cin>>a[i];
for(i=0;i<n;i++){
for(j=0;j<n-1;j++){
if(
strcmp(a[j],a[j+1])>0){
strcpy(t,a[j]);
strcpy(a[j],a[j+1]);
strcpy(a[j+1],t);
}
}
}
請看我標色的地方
概念 作法 都是類似的
只是語法需要因地事宜一下
另外請記得 要 #include<cstring>
---
第三題 求數列
他有兩個變數
如果先遮掉一個 x, 帶數字進去
x=2
1
Σ a[i]*a[1-i]
i=0
這樣就會算了吧?
int i, s=0; // 算加總 先設0 ( 連乘設1 )
int a[12];
a[0]=1;
a[1]=1;
for(i=0;i<2;i++)
s+=a[i]*a[1-i];
a[2]=s;
然後 把s替換成a[2]
int i;
int a[12];
a[0]=1;
a[1]=1;
a[2]=0;
for(i=0;i<2;i++)
a[2]+=a[i]*a[1-i];
接下來把 x 拿回來看
現在a裡面有0~11
每個元素都跟a[2]一樣算法
當然你可以
a[2]=0;
for(i=0;i<2;i++)
a[2]+=a[i]*a[1-i];
a[3]=0;
for(i=0;i<3;i++)
a[3]+=a[i]*a[2-i];
a[4]=0;
for(i=0;i<4;i++)
a[4]+=a[i]*a[3-i];
...
但你有發現嗎 她們都是一樣的程式碼 為什麼不用迴圈呢?
int i, x;
int a[12];
a[0]=1;
a[1]=1;
for(x=2;x<12;x++)
{
a[x]=0;
for(i=0;i<x;i++)
a[x]+=a[i]*a[x-i-1];
}
一步一步改成這樣
應該了解要怎麼做了吧XD
---
第四題 成績單
輸入跟排序的部份 就不再解釋了
直接切到重複排名的部份
如果分數長這樣
a 50
b 30
c 30
d 70
e 20
那麼排出來 就會變成
1 d 70
2 a 50
3 b 30
3 c 30
5 e 20
我一樣用前面一步一步做的方法 來看怎麼解
首先 如果你已經排好了 你應該會這樣cow
for(i=0;i<n;i++)
cout<<"第"<<i+1<<"名"<<'\t'<<name[i]<<'\t'<<ch[i] ... // 輸出每科成績 略
這樣排出來會變成
1 d 70
2 a 50
3 b 30
4 c 30
5 e 20
現在引入新的變數 j 計算名次
int j=1;
for(i=0;i<n;i++)
{
cout<<"第"<<j<<"名"<<'\t'<<name[i]<<'\t'<<ch[i] ... // 輸出每科成績 略
j++;
}
排出來的結果 ...
1 d 70
2 a 50
3 b 30
4 c 30
5 e 20
嗯 還是一樣 但是如果我動點手腳
int j=1;
for(i=0;i<n;i++)
{
cout<<"第"<<j<<"名"<<'\t'<<name[i]<<'\t'<<ch[i] ... // 輸出每科成績 略
if(sum[i]!=sum[i+1]) j++;
}
齁齁 這時候就有不一樣囉
1 d 70
2 a 50
3 b 30
3 c 30
4 e 20
但是這還不是我們想要的
因為重複排名後 e 應該是第五名
請再觀察正確的成績單
1 d 70
2 a 50
3 b 30
3 c 30
5 e 20
有沒有發現 其實 不看重複的部份 排名(j)就等於i+1
所以
再改一下就完成囉
int j=1;
for(i=0;i<n;i++)
{
cout<<"第"<<j<<"名"<<'\t'<<name[i]<<'\t'<<ch[i] ... // 輸出每科成績 略
if(sum[i]!=sum[i+1]) j=i+2; // 因為 i+1 是現在這個人的排名 i+2是下一個人
}
大功告成
---
大概是這樣
快點動工寫一寫吧
作業建議還是自己寫
交別人的程式 大二還是得拿人家的程式
有問題
可以打下面這支MSN:
yantchen@yahoo.com.tw
會有專人幫你看程式碼
但你要先知道你大概bug在哪 或是有bug找不到
我會幫你看程式碼 跟你說的bug要怎麼改
如果你是改好了 請自己測試
看程式碼找bug那個是打分數的時候才要做的事
寒假來囉 大家加油嘿
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 120.127.36.183
※ 編輯: yantchen 來自: 120.127.36.183 (01/18 01:24)
※ 編輯: yantchen 來自: 120.127.36.183 (01/18 01:41)
推 pk873:那個MSN是人工智慧機器人 跟OPEN小將一樣 輸入不同的關鍵字 01/18 02:06
→ pk873:會回答你不同的話喔 揪咪 ^-< ~* 01/18 02:07