The words you are searching are inside this book. To get more targeted content, please make full-text search by clicking here.
Discover the best professional documents and content resources in AnyFlip Document Base.
Search
Published by ttacademic9, 2020-03-06 04:21:49

2301170-Dittaya-ebook

2301170-Dittaya-ebook

A.2. ภาษีและเงินเดอื น 133

A.2 ภาษแี ละเงินเดือน

A.2.1 ภาษีเงินได้

อัตราภาษีเงินไดบ้ คุ คลธรรมดา เม่ือไดย้ อดเงินได้สุทธแิ ลว้ นำไปคำนวณภาษีตามอตั ราภาษี ดงั นี้

ตารางที่ A.1: อัตราภาษเี งินได้บุคคลธรรมดา

เงินได้สทุ ธิ อัตราภาษรี ้อยละ

1 – 150,000 บาท 0

150,001 – 300,000 บาท 5

300,001 – 500,000 บาท 10

500,001 – 750,000 บาท 15

750,001 – 1,000,000 บาท 20

1,000,001 – 2,000,000 บาท 25

2,000,001 – 4,000,000 บาท 30

4,000,001 บาทข้ึนไป 35

จงเขยี นผงั งานเพอ่ื รบั ค่าเงินได้สุทธิ แลว้ คำนวณเงนิ ภาษที ีต่ อ้ งจา่ ย

A.2.2 เงินหกั รายเดอื น

หนว่ ยงานสว่ นมากจะมกี ารหกั ภาษี ณ ทจี่ ่ายเมื่อจะจ่ายเงินเดอื นพนักงาน โดยคำนวณเงินไดส้ ทุ ธคิ รา่ ว ๆ
จากเงินได้พึงประเมิน ซง่ึ คิดจากเงินเดอื นของพนกั งานตลอดปี แลว้ หกั ค่าลดหย่อนและค่ายกเว้นเบ้ืองตน้
ดังรายการต่อไปน้ี

• ลดหย่อนสว่ นบุคคล 30,000 บาท
• ค่าใช้จ่ายส่วนตวั ร้อยละ 40 ของเงินไดพ้ ึงประเมิน แต่ไมเ่ กิน 60,000 บาท
• เงินประกนั สงั คม หักลดหย่อนตามจริงแต่ไม่เกิน 9,000 บาท อัตราจา่ ยเข้ากองทุนประกันสังคม

คือร้อยละ 5 ของเงินเดอื น แตไ่ มเ่ กิน 750 บาทตอ่ เดอื น
• เงนิ กองทุนสำรองเล้ยี งชีพ หักลดหย่อนตามจริงได้ไม่เกินร้อยละ 15 ของเงนิ ได้พงึ ประเมนิ หรือไม่

เกิน 500,000 บาท สมมติให้อตั ราจา่ ยเขา้ กองทนุ สำรองเลยี้ งชีพคือร้อยละ 3 ของเงินเดือน

หากใหเ้ งินไดพ้ ึงประเมินของพนกั งานเป็นเงนิ เดอื นเท่าน้นั เมอื่ ป้อนข้อมูลเขา้ เปน็ เงินเดอื นของพนกั งาน
และสมมติว่าพนกั งานไดเ้ งนิ เดอื นเท่าเดมิ ทกุ เดอื นตลอดปี จงเขยี นผังงานและโปรแกรมภาษาซีเพื่อ
คำนวณเงินได้สทุ ธิตอ่ ปเี บอื้ งต้นของพนักงานคนน้ีแล้วแสดงผล

134 ภาคผนวก A. แบบฝึกหัด

A.2.3 ภาษี ณ ทีจ่ ่าย

หน่วยงานตา่ งๆ ท่จี ่ายค่าจา้ งมีหนา้ ท่ีหักภาษี ณ ทีจ่ า่ ยเพ่ือนำสง่ สรรพากร ในกรณีของการจา่ ยเงินเดือน
หนว่ ยงานมักจะคำนวณคา่ ลดหยอ่ นต่างๆ และคำนวณภาษีให้พนกั งาน แลว้ แบง่ ภาษที ีต่ อ้ งจ่ายของทง้ั ปี
ออกเปน็ 12 สว่ น เพื่อหักรายเดอื นแทน จงคำนวณเงินเดอื นสุทธขิ องพนักงานที่จะได้เม่อื หกั เงินประกนั
สงั คม เงนิ กองทุนสำรองเล้ยี งชีพ และภาษี ณ ท่ีจา่ ยไปแลว้

A.3. สามเหล่ยี มปาสกาล 135

A.3 สามเหลีย่ มปาสกาล

จงเขยี นโปรแกรมภาษาซเี พ่ือพิมพต์ ัวเลขในสามเหล่ียมปาสกาล ให้ผู้ใช้เปน็ ผูป้ ้อนจำนวนแถวทีต่ อ้ งการ
ซึง่ ไมเ่ กิน 15 และใหผ้ ลลัพธ์มีลักษณะดงั น้ี

1 Input: 5
21
3 11
4 121
5 1331
61 4 6 4 1
7 Input: 8
81
9 11
10 1 2 1
11 1 3 3 1
12 1 4 6 4 1
13 1 5 10 10 5 1
14 1 6 15 20 15 6 1
15 1 7 21 35 35 21 7 1

A.3.1 วเิ คราะห์การทำงาน

การพมิ พต์ ัวเลขในสามเหลย่ี มปาสกาลเปน็ การทำซำ้ โดยงานทต่ี อ้ งทำซ้ำแบ่งยอ่ ยออกเปน็ 2 สว่ น ไดแ้ ก่

1. การพมิ พช์ ่องว่างนำหนา้ เพ่อื ให้ออกมาเป็นสามเหลย่ี มหนา้ จ่ัว
2. การพิมพค์ ่าตวั เลขในสามเหลย่ี มปาสกาล

สว่ นเงือ่ นไขในการทำซำ้ คือจำนวนบรรทัดในการพมิ พ์ ซึง่ เทา่ กับจำนวนแถวที่ผูใ้ ชป้ ้อน จงึ มีตวั แปร line
เพ่อื เก็บจำนวนแถว ดังน้ี

ช่อื ตัวแปร ชนิด คำอธบิ าย
line int เลขแถวท่พี มิ พ์
n int จำนวนแถวท่ีพิมพ์

และเขยี นเปน็ โครงของผังงานได้ดงั นี้

136 ภาคผนวก A. แบบฝึกหัด
START
line = 1
line <= n F STOP
T

1 พิมพ์ชอ่ งวา่ งนำหน้า
2 พมิ พค์ า่ ตัวเลข
line = line+1

ตัวเลขนน้ั มีทัง้ หลกั เดยี ว สองหลกั และสามหลกั เพ่ือความสะดวกในการนับชอ่ งว่าง จึงมองการพมิ พ์
ตวั เลขเปน็ block และการพมิ พบ์ รรทดั คอื การพมิ พ์บลอ็ กวางต่อๆ กนั โดยให้ทกุ บล็อกกว้างเทา่ กนั ไม่
ว่าจะเปน็ บล็อกของตวั เลขหรือช่องว่าง

n/2
line/2

จากการสังเกต เมอื่ พิมพ์ตัวเลขจำนวน 5 บรรทัด จะพบว่า จำนวนบล็อกในแต่ละบรรทดั เปน็ ดงั นี้

A.3. สามเหล่ยี มปาสกาล 137

บรรทดั ที่ บลอ็ กช่องวา่ ง บลอ็ กตวั เลข

1 21

2 1.5 2

3 13

4 0.5 4

5 05

n n/2-line/2 line

ดงั นัน้ ในงานยอ่ ยการพิมพ์ชอ่ งวา่ งกอ่ นตวั เลข จงึ เป็นการวนซ้ำเพ่อื พิมพ์ช่องว่างเปน็ จำนวน
n/2-line/2 บลอ็ ก

ปญั หาถัดมาคอื ความกวา้ งของบลอ็ ก เน่อื งจากบลอ็ กหน่ึงจะบรรจตุ ัวเลขเอาไว้ รวมถึงการเคาะวรรค
เพ่อื ความสวยงามระหวา่ งตัวเลขด้วย นอกจากน้ี ความกวา้ งของบลอ็ กควรเป็นเลขคู่ เน่อื งจากเม่อื พิมพ์
ช่องว่าง บางครั้งเราตอ้ งพมิ พช์ อ่ งว่างขนาดครง่ึ บลอ็ ก จากการคำนวณ เลขสงู สุดทเ่ี ป็นไปได้สำหรับ
สามเหล่ยี มปาสกาลทจี่ ำนวนบรรทัดไมเ่ กิน 15 คอื 4 หลกั เม่อื นบั ช่องวา่ งหน้าและหลังอย่างละช่องแลว้
จะได้ความยาวบลอ็ กรวม 6 อกั ขระ (␣dddd␣)

จากนั้น จึงคำนวณจำนวนช่องวา่ งจริงๆ ที่ตอ้ งพมิ พจ์ ำนวน ชอ่ ง ซ่งึ หาไดจ้ าก

nc = n − line ∗ blockSize
(2 2)

เมอ่ื n เป็นจำนวนบรรทดั line เป็นเลขบรรทัด และ blockSize เป็นความยาวบล็อกซึง่ ในที่นค้ี ือ 6
อักขระ

สว่ นของผงั งาน

1 พมิ พช์ ่องว่างนำหน้า

จึงแยกออกมาเขียนไดเ้ ปน็

138 ภาคผนวก A. แบบฝึกหดั

nc = (n/2-line/2) * blockSize
c=0

c < nc F

T
print ‘␣’

c = c+1

สว่ นถดั มาเป็นการพมิ พ์ตัวเลขในสามเหลย่ี มปาสกาล จากการสังเกต เม่ือกำหนดให้ตวั เลขในแตล่ ะ
บรรทดั เก็บในแถวลำดบั จะพบว่าค่าในแตล่ ะช่องของสามเหลย่ี มมคี วามสัมพันธเ์ ปน็ ดังน้ี

1. ช่องแรกสดุ ของทุกบรรทัดเปน็ 1 เสมอ
cur[0] = 1

2. ชอ่ งสุดทา้ ยของทกุ บรรทัดเป็น 1 เสมอ
cur[line-1] = 1

3. หาก cur แทนแถวลำดบั ของจำนวนในบรรทดั ปัจจบุ ัน และ prev แทนแถวลำดบั ของจำนวนใน
บรรทดั ก่อนหนา้ ให้ i แทนดชั นีของชอ่ งปจั จบุ นั
cur[i] = prev[i-1] + prev[i]

1

prev 1 1 [i-1] [i]
cur 1 2 1 [i]
1 331

14641

เมือ่ คำนวณและพมิ พเ์ ลขทุกตัวของแถวปัจจบุ นั ได้แล้ว ตอ้ งกำหนดคา่ แถวลำดบั prev ใหมเ่ ม่อื ทำงานจบ
บรรทดั เพอื่ นำไปใชใ้ นการคำนวณบรรทัดถดั ไป ดงั น้ี

A.3. สามเหลีย่ มปาสกาล 139

cur[0] = 1
i=1

i <= line-2 F

T
cur[i] = prev[i-1] + prev[i]

i = i+1

cur[line-1] = 1
print cur
prev = cur

ในผังงานนั้นเรากำหนดใหแ้ ถวลำดบั prev มคี ่าเท่ากับแถวลำดบั cur ได้ แตห่ ากเป็นโปรแกรมภาษา
ซี หากจะใชก้ ารกำหนดคา่ ให้แถวลำดบั แบบนี้ ต้องวนซำ้ สำเนาค่าในแถวลำดบั หรือคืนพื้นทข่ี อง prev
ก่อนและจองพ้นื ทใ่ี หมส่ ำหรับ cur ในบรรทัดถดั ไป

การพิมพ์ตัวเลข นอกจากจะตอ้ งพิมพค์ ่าของตัวเลขแลว้ ยังต้องจดั ตวั เลขใหอ้ ยกู่ งึ่ กลางของบล็อก
ด้วย ซ่ึงทำได้โดยเคาะวรรคหนา้ และหลังตวั เลขเทา่ ๆ กนั อักขระทั้งหมดในบล็อกจะประกอบด้วย

1. ระยะเคาะกอ่ นตัวเลข (bd) คือความกว้างของบลอ็ ก (blockSize) ลบด้วยจำนวนหลกั ของตวั เลข
(d) แลว้ หารดว้ ย 2 ปัดเศษขึน้ จะเปน็ ระยะเคาะหนา้ ดงั นี้

bd = ⌊(blockSize − d + 1)/2⌋

2. ตัวเลข นับจำนวนหลักไดจ้ ากการหารดว้ ย 10d เม่อื d เป็นจำนวนหลกั ซึ่งทดลองเริ่มตน้ จาก 1 และ
เพ่ิม d ไปจนกวา่ ตวั เลข (cur[i]) จะมีค่ามากกวา่ หรือเทา่ กบั 10d

140 ภาคผนวก A. แบบฝึกหดั
3. ระยะเคาะหลังตวั เลข (ad) เท่ากบั อกั ขระท่เี หลือจนจบบลอ็ ก
ad = blockSize − bd − d

เมื่อรวมกันแลว้ การพมิ พ์ตัวเลขในแตล่ ะบลอ็ กจงึ เปน็

d=1

c=0 c=0

cur[i] >= 10d F

T c < bd F c < ad F
d = d+1
T T
print ‘␣’ print ‘␣’

bd = (blockSize - d + 1) DIV 2 c = c+1 c = c+1

print cur[i]

ad = blockSize - bd - d

เมือ่ นำไปแทนสว่ นการพิมพ์ตัวเลขของบรรทดั แลว้ รวมกบั สว่ นการพิมพ์ชอ่ งวา่ งนำหน้า ก็จะไดผ้ งั
งานทสี่ มบูรณ์

A.3.2 คำตอบ

รายการตวั แปรทง้ั หมดเปน็ ดงั ตารางที่ A.2 ข้ันตอนแสดงการทำงานเป็นดงั รปู ที่ A.1 และรหสั คำสง่ั ภาษา
ซอี ยูใ่ นรหัสคำส่งั ท่ี A.3

A.3. สามเหลย่ี มปาสกาล 141

ตารางที่ A.2: รายการตัวแปรสำหรับการพมิ พส์ ามเหลี่ยมปาสกาล

ช่ือตัวแปร ชนิด คำอธบิ าย
line int เลขแถวทพ่ี มิ พ์
n int จำนวนแถวท่พี ิมพ์
blockSize int จำนวนอักขระต่อหนึง่ บลอ็ ก
c int ตัวนบั จำนวนชอ่ งวา่ งทพี่ มิ พ์
nc int จำนวนช่องวา่ งทัง้ หมดก่อนเริ่มบลอ็ กตัวเลข
cur int[15] แถวลำดับเกบ็ ตวั เลขท่ีตอ้ งพิมพใ์ นบรรทัดปจั จุบัน
prev int[15] แถวลำดบั เก็บตัวเลขที่ต้องพิมพใ์ นบรรทัดก่อนหนา้
i int ดชั นีของตัวเลขทีก่ ำลงั จะพิมพ์
bd int จำนวนช่องวา่ งภายในบล็อกก่อนพิมพต์ วั เลข
d int จำนวนหลกั ของตัวเลขทจี่ ะพมิ พ์
ad int จำนวนชอ่ งวา่ งภายในบล็อกหลังพิมพต์ ัวเลข

142 ภาคผนวก A. แบบฝึกหัด

START
line = 1

line <= n F STOP

T c=0
nc = (n/2-line/2) * blockSize

c = c+1 c < nc F cur[0] = 1 i=1
print ‘␣’ T

i = i+1

line = line+1 cur[i] = prev[i-1] + prev[i] T i <= line-2

prev = cur i=0 F
print “\n” i = i+1 cur[line-1] = 1

F i < line c=0 c=0
T
d=1 c < bd F c < ad F
T
cur[i] >= 10d T print ‘␣’
T F print ‘␣’ c = c+1

d = d+1 c = c+1

print cur[i]

bd = (blockSize - d + 1) DIV 2 ad = blockSize - bd - d

รปู ที่ A.1: ผงั งานการพิมพ์สามเหลยี่ มปาสกาล

A.3. สามเหล่ยี มปาสกาล 143

1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <math.h>

4

5 int main()

6{

7 int line; // line counter

8 int n; // number of lines to be printed

9 int blockSize; // number of characters in a block

10 int c; // space counter

11 int nc; // number of spaces to be printed

12

13 int cur[15]; // int array for numbers in the current line

14 int prev[15]; // int array for numbers of the previous line

15

16 int i; // index in cur and prev

17

18 int bd; // number of spaces before the number in a block

19 int d; // number of digits to be printed

20 int ad; // number of spaces after the number in a block

21

22 // Read input

23 printf(”Input: ”);

24 scanf(”%d”, &n);

25

26 blockSize = 6;

27

28 // main loop for lines

29 for (line = 1; line <= n; line++)

30 {

31 // print space blocks

32 nc = (n - line) * blockSize / 2;

33 for (c = 0; c < nc; c++)

34 printf(” ”);

35

36 // print number blocks

37

38 // illing number in each block of the current line

39 cur[0] = 1;

40

41 // loop illing number in a block

42 for (i = 1; i <= line-2; i++)

144 ภาคผนวก A. แบบฝกึ หัด

43 {
44 cur[i] = prev[i-1] + prev[i];
45
46 }
47 cur[line-1] = 1;
48
49 // loop printing numbers in the line
50 for (i = 0; i < line; i ++)
51 {
52
53 // ind number of digits
54 for (d = 1; cur[i] >= pow(10,d); d++)
55
56 ;
57
58 // print leading spaces in a block
59 bd = (blockSize - d + 1) / 2;
60 for (c = 0; c < bd; c++)
61
62 printf(” ”);
63
64 // print number
65 printf(”%d”, cur[i]);
66
67 // print following spaces in a block
68 ad = blockSize - bd - d;
69 for (c = 0; c < ad; c++)
70
71 printf(” ”);
72 }
73
74 // Finishing printing a line with the newline character
75 printf(”\n”);
76
77 // set prev to cur
78 for (i = 0; i < 15; i++)
79 {
80 }
prev[i] = cur[i];
}
}

return 0;

รหัสคำสง่ั ที่ A.3: โปรแกรมการพิมพ์สามเหล่ียมปาสกาล

A.4. การหารากท่สี องด้วยการหารยาว 145

A.4 การหารากท่ีสองดว้ ยการหารยาว

จงหารากทส่ี องของจำนวนจรงิ ที่ผใู้ ชป้ อ้ นโดยใชว้ ธิ หี ารยาว (ทศนยิ ม 4 ตำแหนง่ )

A.4.1 วเิ คราะห์การทำงาน

ขัน้ ตอนการหารากทสี่ องด้วยมือเปน็ ดงั รูปท่ี A.2

2 = 1 ∗ 10 + 2
1 = 0 ∗ 10 + 1

012

0 ตัวตง้ั

0 ∗ 2 ∗ 10 + 1 2
1 ∗ 2 ∗ 10 + 2 0

0 00
( 0 ∗ 2 ∗ 10 + 1) 1

1 00
( 1 ∗ 2 ∗ 10 + 2) 2

2



รปู ที่ A.2: ตวั อยา่ งการหารากที่สอง

แยกเปน็ ข้ันตอนการทำงานได้ดังน้ี

1. หาจ⏟ำ⏟น⏟วนเต⏟⏟ม็ มากที่สุดท่ยี กกำลังสองแลว้ ไม่เกินตัวต้งั เกบ็ เปน็ ผลลัพธ์ ( )

0

2. หาผลตา่ งของตัวตัง้ กับ 2 ไดเ้ ปน็ เ⏟ศษ
0

0

3. เอาเศษคูณ 100 ได้เป็นตวั ตั้งของรอบต่อไป ( )

4. หาจำนวนเตม็ มากท่สี ดุ ท่ที ำให้

(( ∗ 2 ∗ 10) + ) ∗ < (A.1)

5. หาเศษคร้ังใหม่ ได้เป็น − ((20 + ) ∗ )
6. กลบั ไปทำข้อ 3. จนกว่าจะครบ⏟จำ⏟น⏟⏟ว⏟⏟น⏟⏟ห⏟⏟⏟ล⏟ักขอ⏟ง⏟⏟ท⏟⏟ศ⏟⏟น⏟⏟⏟ิย⏟มทีต่ ้องการ ในที่นโี้ จทยก์ ำหนด dec เปน็ 4

dec

146 ภาคผนวก A. แบบฝึกหดั

7. ปดั เศษทง้ิ ถ้า ตัวสุดทา้ ยน้อยกว่า 5 และปัดข้นึ ในกรณีอน่ื ๆ
8. ใส่ตำแหนง่ ทศนยิ มที่คำตอบ

งานท้ังชน้ิ ประกอบด้วยขน้ั ตอนทงั้ หมด 8 ขนั้ ตอน โดยขั้นตอนท่ี 6 เปน็ ตวั ควบคุมการทำซำ้ มเี งื่อนไข
การทำซำ้ คือจำนวนหลักยงั ไมค่ รบตามตอ้ งการ เม่ือกำหนดให้ i เป็นจำนวนเต็มนบั ตำแหนง่ ของทศนิยมท่ี
ได้ จะเขียนเปน็ โครงของผงั งานได้ดงั น้ี

START
หาผลลัพธต์ วั แรก: A

B = (ตวั ต้ัง - A2)
i=1

i = i+1 i <= dec F
B = B-(20*A+C)*C ปดั เศษ
T
B = B * 100 A = A / 10dec

หาผลลัพธต์ ัวตอ่ ไป: A, C STOP

หาผลลพั ธต์ ัวแรก (A = 0)

1. เริม่ จากให้ 0 เปน็ 1 2 ยงั นอ้ ยกว่าตัวต้งั
2. วนซำ้ เพมิ่ ค่า 0 ไปทลี ะ 1 หาก 0
3. หลังจากการวนซ้ำ ตรวจสอบคา่
0 อกี คร้งั

a) ถา้ 2 มากกวา่ ตวั ตง้ั ใหล้ ด 0 ลง 1
0
2
b) ถา้ 0 เท่ากับตัวตั้ง ไม่ต้องทำอะไร

เขยี นเป็นสว่ นของผงั งานได้ดังน้ี

A.4. การหารากท่ีสองดว้ ยการหารยาว 147

A=1

A2 < ตวั ต้ัง F A2 > ตวั ต้งั T A = A-1

T F
A = A+1

หาผลลพั ธ์ตวั ตอ่ ไป: C

C เปน็ จำนวนเตม็ มากที่สดุ ตามอสมการ (A.1) การหา C จงึ ใช้การวนซ้ำเพ่มิ C ไปเร่อื ยๆ จนกว่าจะไดค้ ่า
สูงสุดทเี่ ปน็ ไปได้ ในทำนองเดียวกับที่หา 0 เขยี นเป็นส่วนของผังงานไดด้ ังนี้

C=1

(20*A+C)*C < B F (20*A+C)*C > B T C = C-1

T F
C = C+1 A = A * 10 + C

ปดั เศษ
เงื่อนไขในการปัดเศษคือ ผลลพั ธ์หลักสดุ ท้าย (C) โดยจะ

• ปัดข้ึนหาก C >= 5
• ปัดท้ิงในกรณอี ื่นๆ

จึงเขียนเปน็ สว่ นของผังงานได้ดังนี้

148 ภาคผนวก A. แบบฝกึ หดั

T C >= 5 F

A=A-C+1 A=A-C

A.4.2 คำตอบ

รายการตวั แปรทัง้ หมดเปน็ ดังตารางที่ A.3 ข้นั ตอนแสดงการทำงานเปน็ ดงั รูปท่ี A.3

ตารางที่ A.3: รายการตวั แปรสำหรบั การหารากท่สี องด้วยการหารยาว

ชอ่ื ตวั แปร ชนดิ คำอธบิ าย
A int ผลลัพธแ์ ละผลลัพธ์ชั่วคราว
ตัวตงั้ float คา่ ของตวั ตงั้
C int ผลลพั ธ์ ณ ตำแหน่งท่ีกำลงั คำนวณ
B int เศษระหว่างการคำนวณ และตวั ตั้งช่วั คราว
i int ตัวนบั จำนวนหลกั ทศนยิ ม
dec int จำนวนหลักทศนยิ มท่ตี อ้ งการ

A.4. การหารากที่สองดว้ ยการหารยาว 149

START
A=1

A2 < ตัวต้ัง F A2 > ตัวตั้ง T A = A-1
F
T
A = A+1 B = (ตัวต้งั - A2)

i=1

i = i+1 i <= dec F C >= 5 F
B = B-(20*A+C)*C A=A-C
T T
B = B * 100 A=A-C+1

A = A * 10 + C C=1

F A = A / 10dec
C = C-1 T (20*A+C)*C > B F (20*A+C)*C < B STOP

T
C = C+1

รปู ท่ี A.3: ผงั งานการหารากทส่ี องด้วยวิธกี ารหารยาว



A.5. การคิดค่าโดยสารรถไฟฟ้า 151

A.5 การคดิ ค่าโดยสารรถไฟฟา้

เมื่อผู้ใช้ป้อนขอ้ มูลเขา้ เปน็ รหัสถานตี น้ ทางและรหัสสถานีปลายทาง จงคำนวณหาราคาโดยสารรถไฟฟ้าที่
ถูกทีส่ ุดในการเดินทางจากจุดเรม่ิ ตน้ ไปยงั ปลายทาง โดยการคดิ ราคาเป็นดงั น้ี

การคำนวณราคาโดยใชบ้ ตั รเติมเงนิ ของบุคคลธรรมดา คดิ ตามระยะห่างระหว่างสถานีเป็นดงั นี้

• สว่ นเดิม

– 0-1 สถานี 15 บาท
– 2-7 สถานี 22-37 บาท โดยเพ่มิ ขน้ึ สถานีละ 3 บาท
– 8 สถานขี นึ้ ไป 42 บาท
– หากเดินทางเฉพาะในช่วงสะพานตากสนิ (S6) ถงึ วงเวียนใหญ่ (S8) คิดราคา 15 บาท

• ส่วนตอ่ ขยาย

– อ่อนนุช (E9) - แบริง่ (E14) และ วงเวียนใหญ่ (S8) - บางหว้า (S12) คดิ ราคาเหมาจา่ ย
10 บาทตลอดช่วง

– หากใชส้ ่วนตอ่ ขยายท้งั สองฝงั่ จะเหมาจา่ ยในอัตรา 10 บาทเชน่ กัน เชน่ จากแบริ่ง (E14) ถึง
บางหว้า (S12) คดิ ราคา 10+42 = 52 บาท

และกำหนดรหัสสถานีดังนี้

• สยาม (C0) • ราชดำริ (S1) - วงเวียนใหญ่ (S8) - บางหว้า
• ราชเทวี (N1) - หมอชิต (N8) (S12)
• ชิดลม (E1) - ออ่ นนชุ (E9) - แบรงิ่ (E14)
• สนามกฬี าแหง่ ชาติ (W1)

A.5.1 วเิ คราะหก์ ารทำงาน

รับข้อมูลเขา้ สองค่า เปน็ สถานีตน้ ทางและสถานีปลายทาง ต้องการคำนวณระยะห่างเป็นจำนวนสถานี

• เม่ือสถานีอยู่ในสายเดียวกัน (N,S,E,W,C) ระยะห่างระหว่างสถานีคือเลขสถานีลบกนั
• เมอ่ื สถานอี ยู่ตา่ งสาย ระยะห่างระหว่างสถานคี ือเลขสถานบี วกกนั

ดังนน้ั ควรออกแบบการรับขอ้ มูลรหสั สถานแี ยกรหัสของสาย (อักขระ N S E W C) และเลขสถานี (0-14)
ออกจากกนั จงึ กำหนดใหร้ ับข้อมลู เขา้ เปน็ ตวั แปร 4 ตวั ดงั น้ี

152 ภาคผนวก A. แบบฝึกหัด

ชอื่ ตวั แปร ชนดิ คำอธบิ าย
c1 char รหสั สายสถานีต้นทาง
s1 int เลขสถานตี ้นทาง
c2 char รหัสสายสถานีปลายทาง
s2 int เลขสถานีปลายทาง

ส่วนของผังงานสำหรับการรบั ข้อมูลเปน็ ดงั น้ี

READ c1, s1, c2, s2

การเดินทางไมว่ ่าจากเลขสถานนี อ้ ยไปมาก หรอื จากเลขสถานมี ากไปน้อยนั้น ใหค้ ่าระยะทางระหวา่ ง
สถานเี ทา่ กัน เพื่อความสะดวกในการคำนวณ จึงต้ังตัวแปรใหม่ขึ้นอกี 4 ตวั กำหนดใหส้ ถานที ่ีมเี ลขน้อย
เป็นต้นทาง และสถานเี ลขมากเป็นปลายทาง ดงั น้ี

ช่อื ตัวแปร ชนดิ คำอธิบาย
startC char รหัสสายต้นทางสำหรบั คำนวณ
startS int เลขสถานีตน้ ทางสำหรับคำนวณ
endC char รหัสสายปลายทางสำหรบั คำนวณ
endS int เลขสถานีปลายทางสำหรบั คำนวณ

ซึ่งเขียนเป็นสว่ นของผังงานได้ดังน้ี

startC=c1 startS=s1 T s1 < s2 F startC=c2 startS=s2

endC=c2 endS=s2 endC=c1 endS=s1

ลกั ษณะการเดินทางแบง่ ออกเป็นสองรปู แบบ ไดแ้ ก่

1. มีเฉพาะการเดนิ ทางในสว่ นต่อขยาย คิดราคา 10 บาท
2. มีการเดนิ ทางในส่วนปกติ และอาจมีการเดินทางในสว่ นต่อขยายด้วย คิดราคาทง้ั สองส่วนรวมกัน

A.5. การคดิ ค่าโดยสารรถไฟฟา้ 153

จงึ ใหม้ ีตวั แปร 2 ตัว เก็บค่าโดยสารแยกส่วนกนั และตวั แปรอกี หนงึ่ ตัวเก็บคา่ โดยสารรวม เปน็
ผลลัพธ์ ดังนี้

ช่ือตวั แปร ชนดิ คำอธิบาย
ราคาในส่วนปกติ
normPrice int ราคาในส่วนต่อขยาย
ราคารวม
extPrice int

price int

เง่ือนไขทใี่ ช้ในการตดั สนิ ใจว่ามเี ฉพาะการเดินทางในส่วนตอ่ ขยายหรือไม่ เป็นอันใดอันหน่ึงดังต่อไปน้ี

• การเดินทางช่วง ออ่ นนชุ -แบริง่ รหัสสายเดยี วกันและเลขสถานีต้ังแต่ 9 เป็นต้นไป
– (startC == ‘E’ AND startC == endC) AND (startS >= 9 AND endS > 9)

• การเดนิ ทางชว่ ง วงเวยี นใหญ่-บางหว้า รหสั สายเดยี วกนั และเลขสถานีต้ังแต่ 8 เป็นตน้ ไป
– (startC == ‘S’ AND startC == endC) AND (startS >= 8 AND endS > 8)

เขยี นเป็นเงอื่ นไขในผงั งานไดด้ ังน้ี

T (startC == ‘E’ AND startC == endC) F
price=10 AND (startS >= 9 AND endS > 9)
การคิดราคาส่วน
OR ปกติรวมกับสว่ นต่อ
(startC == ‘S’ AND startC == endC) ขยาย
AND (startS >= 8 AND endS > 8)

กรณีท่ีมีการเดินทางในส่วนปกติ ซงึ่ อาจมีการเดนิ ทางในสว่ นต่อขยายรวมด้วย จึงแยกคดิ ราคาของสว่ น
ตอ่ ขยายออกมากอ่ น แลว้ ปรับสถานใี นการคำนวณให้เป็นจุดปลายของการเดินทางแบบปกติ เพ่ือนำไป
คำนวณราคาแบบปกติตอ่ ไป การเดนิ ทางในสว่ นตอ่ ขยายจะเกิดขึน้ เมอ่ื เลขสถานอี ยใู่ นส่วนตอ่ ขยาย ไมว่ า่

154 ภาคผนวก A. แบบฝึกหดั

จะเป็นสว่ นตน้ ทางหรือปลายทางกต็ าม หากต้นทางและปลายทางเปน็ ส่วนขยายต่างสายกนั จะคิดราคา
เพียงครัง้ เดยี ว

การคิดราคาหากมสี ว่ นตอ่ ขยายท่ีตน้ ทางเปน็ ดังน้ี

extPrice = 0

startC == ‘E’ startC == ‘S’
AND F AND F

startS > 9 startS > 8

T T
extPrice = 10 extPrice = 10

startS = 9 startS = 8

และการคดิ ราคาหากมสี ว่ นตอ่ ขยายท่ีปลายทางเปน็ ดงั น้ี

endC == ‘E’ endC == ‘S’
AND F AND F

endS > 9 endS > 8

T T
extPrice = 10 extPrice = 10

endS = 9 endS = 8

จากน้นั เปน็ การคดิ ค่าโดยสารในส่วนปกติ ในกรณีทก่ี ารเดนิ ทางอยู่ในชว่ งของสถานีสะพานตากสนิ (S6)
ถึงสถานวี งเวยี นใหญ่ (S8) เทา่ นนั้ ค่าโดยสารจะเป็น 15 บาท เขยี นเปน็ ผังงานไดด้ ังนี้

A.5. การคดิ ค่าโดยสารรถไฟฟ้า 155
การคดิ ราคาช่วง S6-S8
startC==’S’
AND

startS>=6
AND

endC==’S’
AND endS<=8

T
normPrice = 15

ส่วนสถานีปกติอนื่ ๆ คิดคา่ เดินทางจากจำนวนสถานีที่เดนิ ทาง กำหนดตวั แปรเพ่มิ สำหรบั เก็บระยะ
หา่ งสถานดี ังนี้

ช่ือตวั แปร ชนดิ คำอธบิ าย
diff int ระยะระหว่างสถานี

ระยะระหวา่ งสถานีแบง่ ออกเปน็ 2 กรณี ได้แก่

• ตน้ ทางและปลายทางมีรหัสสายเดียวกัน ระยะหา่ งระหว่างสถานคี ือเลขปลายทางลบเลขตน้ ทาง
– diff = endS - startS

• ตน้ ทางและปลายทางมรี หสั สายตา่ งกนั แสดงว่ามกี ารเปล่ียนสายท่ีสถานสี ยาม ระยะห่างระหว่าง
สถานีคอื ระยะระหว่างสถานตี น้ ทางมาถงึ สยาม รวมกับระยะระหวา่ งสถานีสยามไปถงึ ปลายทาง
– diff = (startS - 0) + (endS - 0) = startS + endS

เขยี นเปน็ ผังงานได้ดงั น้ี

T startC == endC F

diff = endS - startS diff = startS + endS

156 ภาคผนวก A. แบบฝกึ หดั

จากน้นั คิดราคาในการเดนิ ทางจากจำนวนสถานี โดย
• 0-1 สถานี คิดราคา 15 บาท
• 2-7 สถานี คิดราคา 22-37 บาท โดยเพ่มิ ขน้ึ สถานลี ะ 3 บาท
• 8 สถานขี น้ึ ไป คิดราคา 42 บาท
จึงเขียนเป็นผงั งงานไดด้ ังน้ี

T diff <= 1 F
diff <= 7
normPrice = 15 T F

normPrice = 16 + 3*diff normPrice = 42

ราคารวมจะเท่ากับราคาในสว่ นปกติรวมกบั ราคาในส่วนตอ่ ขยาย
• price = normPrice + extPrice
price = normPrice + extPrice

นำส่วนตา่ งๆของผงั งานท้งั หมดมารวมกนั จะไดเ้ ปน็ คำตอบ

A.5. การคดิ ค่าโดยสารรถไฟฟา้ 157

A.5.2 คำตอบ

รายการตวั แปรทง้ั หมดอยใู่ นตารางที่ A.4 ผงั งานการคดิ คา่ โดยสารเปน็ ดังรูปท่ี A.4 และรหสั คำส่งั ภาษา
ซอี ยู่ในรหสั คำส่ังที่ A.4

ตารางที่ A.4: รายการตัวแปรสำหรับการคิดคา่ โดยสาร BTS

ชื่อตัวแปร ชนิด คำอธิบาย
รหสั สายสถานีต้นทาง
c1 char เลขสถานตี ้นทาง
รหัสสายสถานีปลายทาง
s1 int เลขสถานปี ลายทาง
รหสั สายตน้ ทางสำหรบั คำนวณ
c2 char เลขสถานตี ้นทางสำหรบั คำนวณ
รหสั สายปลายทางสำหรบั คำนวณ
s2 int เลขสถานปี ลายทางสำหรับคำนวณ
ระยะระหวา่ งสถานี
startC char ราคาในส่วนปกติ
ราคาในส่วนตอ่ ขยาย
startS int ราคารวม

endC char

endS int

diff int

normPrice int

extPrice int

price int

158 ภาคผนวก A. แบบฝกึ หดั

START

READ c1, s1, c2, s2

startC=c1 startS=s1 T s1 < s2 F startC=c2 startS=s2

endC=c2 endS=s2 endC=c1 endS=s1

T (startC == ‘E’ AND startC == endC) F extPrice = 0
price=10 AND (startS >= 9 AND endS > 9)
startC == ‘E’
OR AND
(startC == ‘S’ AND startC == endC)
AND (startS >= 8 AND endS > 8) startS > 9

F T
extPrice = 10
extPrice = 10 T startC == ‘S’
startS = 8 AND startS = 9

startS > 8

F

endC == ‘E’ F endC == ‘S’ F

AND AND

endS > 9 endS > 8

T T
extPrice = 10 extPrice = 10

endS = 9 endS = 8

startC==’S’ F startC == endC T diff = endS - startS
AND
F
startS>=6 diff = startS + endS
AND
T diff <= 1 F
endC==’S’ diff <= 7
AND endS<=8

T

normPrice = 15

normPrice = 15 T F

normPrice = 16 + 3*diff normPrice = 42

price = normPrice + extPrice

STOP

รูปที่ A.4: ผงั งานการคดิ คา่ โดยสารรถไฟฟา้ BTS

A.5. การคิดค่าโดยสารรถไฟฟา้ 159

รูปที่ A.5: แผนภาพเสน้ ทางและสถานใี นระบบรถไฟฟ้า BTS: ภาพจาก www.bts.co.th

160 ภาคผนวก A. แบบฝกึ หดัตารางอตั ราคา โดยสารทีเ่ รยี กเก็บ Effective Fare หUนวnยit:: Bบaาhทt
รูปที่ A.6: ตารางค่าโดยสารรถไฟฟา้ BTS: ภาพจาก www.bts.co.th
Fตrนoทmาง Deปsลtiาnยaทtioาnง เร�ิม 6 ม.ค. 57 Effective from 6th January 2014
N8
N7
N6
N5
N4
N3
N2
N1
CEN
E1
E2
E3
E4
E5
E6
E7
E8
E9
E10
E11
E12
E13
E14
W1
S1
S2
S3
S4
S5
S6
S7
S8
S9
S10
S11
S12

หมอชติ /Mo Chit N8 421424453455551344534445442554444444522252272222222222222242252212222822 141244543552444444345545415434455424252522221222252222252722248222222222 414534545454155554234424234233445441227221222227822524222222552222272252 543325421243425414552554454343445314522247224212542225252272222222228225 552332542344534335444454514512123542512248722225222222125755221422222822 342554324544431255325145445152332223245222282524158122222227825221222875 543312125422454224351355535523434232227128725222248225552251142222525284 223253412225544315352454335155222333822225752252422872521224752252248211 235415542332132255524553431253131223182552442222258222575552721225122748 252555325252252344453122331423154333455522272222282822254225221524812771 422352535443444212342211354324342343254172255588257551777427282127722242 323232511444435524242434441452243334252224482127825222442584845512244127 132324344234214443445554344431352244252214121278222421155212751221512822 441233232234433343435215435514324444258424881282825227825852722224522222 412445342452423343444333551431332444552172222522552522227852425252522722 431445432144451545342434423243344344225222822722122222224222522525222222 244214425422351443442354424524441444252222255552222257225284212225222522 414454221144145412444313445534444144522222520224022571220222202822022222 553155515544351541551555352555551555227220254022122022202225022822022222 513515553155555145514253415555555555022022222252072025222122220202428222 555554554154551253555511355551535155222222501222024820222222722225000222 535555511555254155514551555145553355022222220222825222022012220247250222 155544555551552535551555455513153155222222027202225224120252002220228222 335252514523554324232435524314245233422825252422278227222422212855125217 322441244333525253315124224435442323222714772225225824148785572572212257 424435323514224431534445422323132524842724542212255541221584452722824522 554442223314445322534423444512332414442222125521818185712122852222221752 2413422442335334245344554514324185212227815254221722252222222425 543345454332113244344355443223324414754228152545222245722222255222225225 245244144154545432342433443512144224522252225522252228257225475222527122 242451454421344214444324535444442542122552222225525722224222282222525225 444442415544353444115111444145434442220224255272222022022252222202122582 545155115555255455255554553555155135254222222220222252072122202222020582 514155555551415555555455523525155553202222410222222200272222252220225582 555552355514555554155515552155154535220220222704252222200222225215222282 525555515555555542551554131551555453222502200202421522222722252220222282
สะพานควาย/Saphan Khwai N7 38
N6 38
เสนารว ม/Sena Ruam* N5 38
อารีย/ Ari N4 38
N3
สนามเปา /Sanam Pao N2
อนสุ าวรยี ช ยั สมรภมู /ิ Victory Monument N1
CEN
พญาไท/Phaya Thai E1
ราชเทว/ี Ratchathewi E2
E3
สยาม/Siam E4
ชดิ ลม/Chit Lom E5
เพลินจติ /Phloen Chit E6
E7
นานา/Nana E8
อโศก/Asok E9
พรอ มพงษ/Phrom Phong E10
ทองหลอ/Thong Lo E11
เอกมัย/Ekkamai E12
พระโขนง/Phra Khanong E13
ออนนุช/On Nut E14
บางจาก/Bang Chak W1
ปณุ ณวถิ ี/Punnawithi S1
อุดมสุข/Udom Suk S2
บางนา/Bang Na S3
แบร�งิ /Bearing S4
สนามกฬี าแหง ชาต/ิ National Stadium S5
ราชดำร/ิ Ratchadamri S6
ศาลาแดง/Sala Daeng S7
ชองนนทรี/Chong Nonsi S8
ศกึ ษาวทิ ยา/Suksa Witthaya* S9
สรุ ศักด/ิ์ Surasak S10
สะพานตากสนิ /Saphan Taksin S11
กรุงธนบุรี/Krung Thonburi S12
วงเวยี นใหญ/ Wongwian Yai
โพธิน์ มิ ิตร/Pho Nimit
ตลาดพล/ู Talat Phlu
วุฒากาศ/Wutthakat
บางหวา /Bang Wa

*สถานร� ถไฟฟาบที เี อสในอนาคต / Future BTS SkyTrain Station Location

A.5. การคดิ คา่ โดยสารรถไฟฟา้ 161

1 #include <stdio.h>
2 #include <stdlib.h>

3

4 int main()

5{

6 char depart[4]; // Departure station

7 char dest[4]; // Destination station

8 char c1; // Start line code

9 int s1; // Start station number

10 char c2; // End line code

11 int s2; // End station number

12 char startC; // Start line code for calculation

13 int startS; // Start station number for

calculation

14 char endC; // End line code for calculation

15 int endS; // End station number of calculation

16 int dif; // Distance between stations

17 int normPrice; // Price in normal zone

18 int extPrice; // Price in extension zone

19 int price; // Total price

20
21 // Read departure and destination station
22 printf(”Enter departure station: ”);
23 scanf(”%s”, depart);
24 printf(”Enter destination station: ”);
25 scanf(”%s”, dest);

26
27 c1 = depart[0];
28 s1 = atoi(depart+1);
29 c2 = dest[0];
30 s2 = atoi(dest+1);

31
32 // Set the station with smaller number to be the

departure station

162 ภาคผนวก A. แบบฝกึ หดั

33 if (s1 < s2)
34 {
35
36 startC = c1;
37 startS = s1;
38 endC = c2;
39 endS = s2;
40 }
41 else
42 {
43 startC = c2;
44 startS = s2;
45 endC = c1;
46 endS = s1;
47 }
48
49 // If the route is on the extension zone only
if ( (startC == ’E’ && startC == endC && startS
50 >= 9 && endS > 9)

51 || (startC == ’S’ && startC == endC &&
52 startS >= 8 && endS > 8)
53
54 )
55 price = 10;
56 else
57 {
58 // Find the extension price
59 extPrice = 0;
60
if (startC == ’E’ && startS > 9)
61 {
62
63 // Departure station is in the eastern
64 extension zone

extPrice = 10;
startS = 9;
}
else if (startC == ’S’ && startS > 8)

A.5. การคดิ ค่าโดยสารรถไฟฟา้ 163

65 {
66 // Departure station is in the southern

extension zone
67 extPrice = 10;
68 startS = 8;
69 }

70
71 if (endC == ’E’ && endS > 9)
72 {
73 // Destination station is in the eastern

extension zone
74 extPrice = 10;
75 endS = 9;
76 }
77 else if (endC == ’S’ && endS > 8)
78 {
79 // Destination station is in the southern

extension zone
80 extPrice = 10;
81 endS = 8;
82 }

83
84 // S6-S8 fare
85 if (startC == ’S’ && startS >= 6 && endC == ’S’

&& endS <= 8)
86 normPrice = 15;

87 else
88 {
89 // Route is in the same line
90 if (startC == endC)
91 dif = endS - startS;
92 // Route includes diferent lines

93 else
94 dif = startS + endS;

95

164 ภาคผนวก A. แบบฝกึ หัด

96 // Calculate the fare based on number of
traveling stations
97
98 if (dif <= 1)
99 normPrice = 15;
100 else if (dif <= 7)
101 normPrice = 16 + 3 * dif;
102 else
103 normPrice = 42;
104
105 }
106
107 // calculate total price
108 price = normPrice + extPrice;
109 }
110 printf(”Total price = %d\n”, price);
111
112 } return 0;

รหัสคำสั่งท่ี A.4: โปรแกรมการคดิ คา่ โดยสาร BTS

A.6. การพิมพ์ปฏทิ ิน 165

A.6 การพิมพ์ปฏทิ ิน

จงเขียนผังงานแบบทดสอบกอ่ นทำเพื่อพิมพ์ปฏทิ ินสำหรบั 1 เดือนออกทางหนา้ จอ โดยใหผ้ ใู้ ชป้ อ้ นวัน
ของวันที่ 1 ของเดอื นนน้ั ๆ ในรปู ตวั เลข 1-7 โดยท่วี ันจันทร์แทนด้วย 1 และจำนวนวนั ในเดอื นน้นั ๆ เช่น

1 3 31

ผ้ใู ช้ปอ้ นเลข 3 แสดงว่าวันท่ี 1 เป็นวนั พุธ และเลข 31 หมายถึงเดอื นนั้นมี 31 วนั ปฏิทนิ ควรจะมลี กั ษณะ
ดังน้ี

1 Mon Tue Wed Thu Fri Sat Sun
2 12345
3 6 7 8 9 10 11 12
4 13 14 15 16 17 18 19
5 20 21 22 23 24 25 26
6 27 28 29 30 31

A.6.1 วเิ คราะห์การทำงาน

โจทยก์ ำหนดใหร้ ับข้อมลู 2 จำนวน เปน็ วันเริม่ ตน้ ของเดอื น และจำนวนวันในหนึง่ เดือน เลอื กใช้ตวั แปร
และชนิดดังนี้

ช่อื ตวั แปร ชนิด คำอธิบาย
startDay int วนั แรกของเดือน
nDays int จำนวนวันในหนึ่งเดอื น

สว่ นของการรบั ข้อมูลเป็นดงั นี้

READ startDay, nDays

งานหลกั ของการพมิ พป์ ฏทิ นิ คอื การพิมพ์วนั ท่ีให้ครบตั้งแต่วนั ที่ 1 ถงึ จำนวนวันท่ีกำหนด ซึง่ พบวา่

• สง่ิ ทต่ี อ้ งทำกอ่ นการทำซำ้ คอื การต้ังวันที่เริม่ ตน้ ใหเ้ ป็น 1
• ส่งิ ที่ตอ้ งทำซำ้ คือ การพมิ พว์ ันที่ และเพ่มิ เลขวนั ท่ไี ปทลี ะ 1
• เง่ือนไขในการทำซ้ำ คือ หากยงั พมิ พ์วนั ทไ่ี ม่ครบจำนวนวันในหนึง่ เดอื น ให้พิมพ์ตอ่ ไป

166 ภาคผนวก A. แบบฝึกหดั

จึงมีตวั แปรเพิ่มขน้ึ 1 ตัว สำหรบั เก็บวันที่ ดังน้ี คำอธิบาย
วันท่ี
ชอื่ ตัวแปร ชนดิ
date int

จากนน้ั ร่างผังงานเฉพาะสว่ นพิมพว์ นั ท่ี จะได้เป็น

READ startDay, nDays
date = 1

date <= nDays F

T
PRINT date
date = date + 1

หาก nDays มคี า่ เปน็ 31 จะให้ผลลพั ธ์เปน็ เลข 1-31 ตดิ กันดังนี้
1 12345678910111213141516171819202122232425262728293031

เราต้องการใหม้ ชี อ่ งวา่ งระหวา่ งวันที่ในการแสดงผล ดังน้ัน ในเบื้องต้น อาจแกไ้ ขผงั งานโดยบงั คบั ให้
พมิ พช์ อ่ งว่าง (อกั ขระช่องว่าง ‘␣’) หลงั การพิมพ์วันทท่ี ุกครง้ั ได้เป็น

READ startDay, nDays
date = 1

date <= nDays F

T
PRINT date ,‘␣’

date = date + 1

A.6. การพิมพป์ ฏิทิน 167

หลังการแกไ้ ข หาก nDays มคี ่าเปน็ 31 จะให้ผลลพั ธเ์ ป็นเลข 1-31 โดยมกี ารเคาะวรรค 1 ครง้ั ระหวา่ ง
วนั ท่ี ดงั นี้

1 1␣2␣3␣4␣5␣6␣7␣8␣9␣10␣11␣12␣13␣14␣15␣16␣17␣18␣19␣20␣21␣22
␣23␣24␣25␣26␣27␣28␣29␣30␣31

งานถัดมาทต่ี ้องทำคอื ทำใหป้ ฏทิ ินพมิ พ์วนั ท่แี ถวละ 7 วนั ซึ่งทำได้โดยใหข้ ึ้นบรรทดั ใหมท่ กุ ๆ 7 วนั วิธี
การนับอยา่ งง่ายคือ ใหด้ เู ศษจากการหารด้วย 7 ซง่ึ จะมคี า่ เปน็

วันท่ี 1 2 3 4 5 6 7 8 9 ...
เศษ 1 2 3 4 5 6 0 1 2 ...

จะได้ว่า เศษจากการหารด้วย 7 จะนับครบ 7 ตวั เมอ่ื เศษเปน็ 0 จึงกำหนดเงื่อนไขของการขน้ึ บรรทัด
ใหมเ่ ป็น เมือ่ วนั ทีน่ ัน้ หารดว้ ย 7 แลว้ เหลอื เศษ 0 ดงั นี้

date MOD 7 == 0 F

T
PRINT ‘\n’

แลว้ เอาเง่ือนไขนไ้ี ปใส่ในส่วนการพิมพ์ กอ่ นจะนบั วนั ที่เพิม่ ได้เป็น

168 ภาคผนวก A. แบบฝกึ หดั

READ startDay, nDays
date = 1

date <= nDays F

T
PRINT date ,‘␣’

date MOD 7 == 0 F

T
PRINT ‘\n’

date = date + 1

หลงั การแก้ไข หาก nDays มคี ่าเปน็ 31 จะให้ผลลัพธ์ดังน้ี
1 1␣2␣3␣4␣5␣6␣7
2 8␣9␣10␣11␣12␣13␣14
3 15␣16␣17␣18␣19␣20␣21
4 22␣23␣24␣25␣26␣27␣28
5 29␣30␣31

ณ ตอนน้ี จะเห็นวา่ เราจะขนึ้ บรรทัดใหมท่ กุ คร้งั ทีว่ ันทน่ี ัน้ หารด้วย 7 ลงตวั ซึ่งจะถูกต้องก็ตอ่ เม่ือวนั
แรกของเดอื นเปน็ วนั จันทร์เทา่ น้ัน จากตัวอย่างในโจทย์ วนั แรกของเดือนเปน็ วนั พุธ ทำใหก้ ารขึ้นบรรทัด
ใหมค่ รงั้ แรกต้องขยับไปเป็นวันที่ 5 แทน

การเลอื่ นไปเป็นวนั ที่ 5 นัน้ เสมือนว่าเรานับวนั จันทร์และองั คารเป็นวันวา่ งไปก่อน 2 วนั และเรมิ่
พมิ พว์ นั ทแี่ รกในวันพุธ จากโจทยก์ ำหนดใหผ้ ู้ใช้ป้อนวนั แรกของเดอื น (startDay) มาให้ และกำหนดให้
วนั จนั ทร์แทนด้วย 1 วันอังคารแทนดว้ ย 2 ไปจนถึงวันอาทติ ยแ์ ทนดว้ ย 7 จากการพจิ ารณา input ท่เี ป็น
ไปได้แล้ว พบว่า

startDay 1 2 3 4 5 6 7

จำนวนวันว่าง 0 1 2 3 4 5 6

A.6. การพิมพ์ปฏทิ ิน 169

ความสัมพนั ธข์ องจำนวนวันวา่ งท่ีต้องนับรวมเขา้ ไปคือ startDay-1 จึงปรับเง่อื นไขของการขน้ึ
บรรทดั ใหม่ ใหร้ วมวันว่างเข้าไปดว้ ย ก่อนจะหาเศษหลือจากการหารดว้ ย 7

READ startDay, nDays
date = 1

date <= nDays F

T
PRINT date ,‘␣’

(date+startDay-1) F
MOD 7 == 0

T
PRINT ‘\n’

date = date + 1

หลงั การแก้ไข หาก startDay มคี า่ เปน็ 3 และ nDays มคี ่าเปน็ 31 จะให้ผลลัพธด์ ังน้ี
1 1␣2␣3␣4␣5
2 6␣7␣8␣9␣10␣11␣12
3 13␣14␣15␣16␣17␣18␣19
4 20␣21␣22␣23␣24␣25␣26
5 27␣28␣29␣30␣31

จากผลลัพธท์ ี่ได้ วันที่ 1 จะอยใู่ นคอลัมนแ์ รกซ่ึงเป็นวนั จนั ทร์เสมอ เราจงึ ตอ้ งเคาะวรรคก่อนจะเร่ิมพมิ พ์
วนั แรกด้วย เม่อื พจิ ารณาจากตัวอย่างในโจทย์ จะพบวา่ จำนวนวรรคท่ีตอ้ งเคาะ (space) จะเปลีย่ นไป
ตามวันแรกของเดือน (startDay) ดงั น้ี

startDay 1 2 3 4 5 6 7

space 1 5 9 13 17 21 25

170 ภาคผนวก A. แบบฝึกหัด

การเคาะวรรคน้ีเกิดก่อนพมิ พ์วันทว่ี ันแรก และทำครั้งเดยี ว จึงแทรกการเคาะวรรคนีไ้ วห้ ลังจากอ่าน
ค่าทีผ่ ้ใู ช้ปอ้ น เราสามารถใชก้ ารทำงานแบบเงื่อนไข 7 ทางเลือก (ทัง้ if และ switch) ก็ได้ หรอื

หาความสัมพนั ธข์ องจำนวนเคาะวรรคและวันแรกของเดือน ไดเ้ ปน็ สมการ

space = 1+(startDay-1)*4

แลว้ ใช้การวนซ้ำนับจำนวนการพิมพเ์ คาะวรรคจนกว่าจะครบก็ได้ ในทนี่ ้เี ลือกทำแบบหลัง จึงกำหนด
ตัวแปรจำนวนเคาะวรรคเพมิ่ ข้นึ ดังน้ี

ชอื่ ตัวแปร ชนดิ คำอธบิ าย
space int จำนวนการเคาะวรรค

พจิ ารณาการวนซำ้ เพ่มิ พิมพ์อกั ขระช่องวา่ ง จะไดว้ า่

• ส่งิ ท่ีต้องทำกอ่ นทำซำ้ คือ ตั้งค่าเริ่มต้นของจำนวนอักขระช่องว่างที่พิมพ์ไปแล้วใหเ้ ป็น 0 เน่อื งจาก
ยงั ไมเ่ ร่ิมพมิ พอ์ ักขระ

• สงิ่ ทีต่ ้องทำซ้ำ คอื การพิมพ์อักขระชอ่ งวา่ ง (‘␣’) 1 ตวั และเพ่ิมคา่ ในตัวนบั ไป 1
• เงอ่ื นไขในการทำซ้ำคอื จำนวนเคาะวรรคยงั ไมค่ รบตามจำนวนทตี่ ้องพิมพ์ (1+(startDay-1)*4

ตัว)

เขียนผังงานเฉพาะส่วนเคาะวรรคกอ่ นการพิมพว์ นั ที่ 1 ไดด้ งั นี้

space = 0

space < F
1+(startDay-1)*4

T
PRINT ‘␣’

space = space + 1

จากนัน้ เพมิ่ สว่ นการพิมพห์ วั ตารางวันจนั ทรถ์ งึ อาทติ ย์ ซ่งึ เป็นคา่ คงทสี่ ายอักขระธรรมดา

A.6. การพมิ พป์ ฏิทนิ 171
PRINT “Mon␣ Tue␣ Wed␣ Thu␣ Fri␣ Sat␣ Sun␣\n”

การพิมพ์หัวตารางทำคร้งั เดยี วก่อนการพมิ พช์ ่องวา่ งใดๆ จงึ อาจแทรกไว้ทนั ทลี งั จากรบั ข้อมูล ก่อนท่ีจะ
เคาะวรรค

เม่อื แทรกสว่ นการพมิ พ์หวั ตารางและการเคาะวรรคลงไปในผังงานเดิมที่ได้ก่อนท่ีจะเริ่มต้น จะได้เป็น

READ startDay, nDays
PRINT “Mon␣ Tue␣ Wed␣ Thu␣ Fri␣ Sat␣ Sun␣\n”

space = 0

space = space + 1 space <
PRINT ‘␣’ T 1+(startDay-1)*4

F
date = 1

date <= nDays F

T
PRINT date ,‘␣’

date = date + 1 (date+startDay-1) T PRINT ‘\n’
MOD 7 == 0

F

172 ภาคผนวก A. แบบฝึกหัด

หลังการแก้ไข หาก startDay มีคา่ เป็น 3 และ nDays มคี า่ เปน็ 31 จะให้ผลลัพธด์ ังน้ี
1 Mon␣Tue␣Wed␣Thu␣Fri␣Sat␣Sun
2 ␣␣␣␣␣␣␣␣␣1␣2␣3␣4␣5
3 6␣7␣8␣9␣10␣11␣12
4 13␣14␣15␣16␣17␣18␣19
5 20␣21␣22␣23␣24␣25␣26
6 27␣28␣29␣30␣31

ตำแหน่งของวันท่ี 1 นนั้ อยู่ตรงกับกง่ึ กลางคอลมั นว์ นั พุธตามท่ตี อ้ งการแล้ว แตก่ ารเคาะวรรคระหว่างวันที่
ตา่ งๆ ยงั ไมถ่ ูกต้อง และขาดการเคาะวรรคในตอนตน้ ของทุกแถวเชน่ เดยี วกนั

สำหรับชอ่ งว่างระหว่างวันทีน่ ้ัน หากมองใหเ้ ลขทกุ ตวั เสมอื นวา่ มีสองหลกั เราจะตอ้ งเคาะวรรค 1
ครั้งหากเลขวนั ทน่ี ้ันเป็นเลขโดด และจะทำให้ชอ่ งวา่ งระหวา่ งวันทเี่ ป็นการเคาะวรรค 2 ครัง้ เสมอทกุ ช่วง
สำหรบั ช่องของวันจันทร์นนั้ ถ้าวันทเี่ ปน็ เลขหลักเดยี ว การเคาะวรรคก่อน 1 ครัง้ กจ็ ะทำใหเ้ ลขวนั ท่อี ยู่ตรง
ก่ึงกลางพอดีไปในตวั แตก่ ารแกไ้ ขน้จี ะไปกระทบกบั การพมิ พ์วันท่ี 1 ด้วย จงึ ปรบั เงือ่ นไขของจำนวนการ
เคาะวรรคก่อนวนั ท่ี 1 ใหล้ ดลงเปน็ (startDay-1)*4 แทน

การปรับปรงุ เง่อื นไขการเคาะวรรคทง้ั ก่อนและหลงั พิมพ์เลขวันทเี่ ปน็ ดงั น้ี

date<10 F

T
PRINT ‘␣’

PRINT date,“␣␣”

เมื่อรวมเข้าไปในผังงานรวม และแกไ้ ขจำนวนการเคาะวรรคก่อนวันท่ี 1 แลว้ จะได้คำตอบ

A.6. การพมิ พ์ปฏทิ นิ 173

A.6.2 คำตอบ

เมอื่ รวมผงั งานเรยี บร้อยแล้ว หาก startDay มีค่าเปน็ 3 และ nDays มีค่าเป็น 31 จะใหผ้ ลลพั ธ์ดงั น้ี

1 Mon␣Tue␣Wed␣Thu␣Fri␣Sat␣Sun
2 ␣␣␣␣␣␣␣␣␣1␣␣␣2␣␣␣3␣␣␣4␣␣␣5
3 ␣6␣␣␣7␣␣␣8␣␣␣9␣␣10␣␣11␣␣12
4 13␣␣14␣␣15␣␣16␣␣17␣␣18␣␣19
5 20␣␣21␣␣22␣␣23␣␣24␣␣25␣␣26
6 27␣␣28␣␣29␣␣30␣␣31

ซ่ึงตรงตามทโี่ จทย์กำหนด
รายการตัวแปรทัง้ หมดเปน็ ตารางท่ี A.5 ขนั้ ตอนแสดงการทำงานเปน็ ดงั รูปท่ี A.7 และรหัสคำสงั่

ภาษาซอี ย่ใู นรหสั คำสัง่ ท่ี A.5

ตารางท่ี A.5: รายการตัวแปรสำหรบั การพิมพ์ปฏิทนิ

ช่อื ตวั แปร ชนดิ คำอธิบาย
startDay int วันแรกของเดอื น
nDays int จำนวนวนั ในหน่ึงเดอื น
date int วันท่ี
space int จำนวนการเคาะวรรค

174 ภาคผนวก A. แบบฝกึ หดั

START
READ startDay, nDays
PRINT “Mon␣ Tue␣ Wed␣ Thu␣ Fri␣ Sat␣ Sun␣\n”

space = 0

space < F
(startDay-1)*4

T
PRINT ‘␣’

space = space + 1

date = 1

date <= nDays F STOP

T F

date<10

T
print ‘␣’

PRINT date,“␣␣”

(date+startDay-1) F
MOD 7 == 0

T
PRINT ‘\n’

date = date + 1
รูปท่ี A.7: ผังงานการพิมพ์ปฏิทิน

A.6. การพิมพป์ ฏิทิน 175

1 #include <stdio.h>
2 #include <stdlib.h>

3
4 int main()
5{
6 int startDay, nDays, date, space;

7
8 scanf(”%d %d”, &startDay, &nDays);
9 printf(”Mon Tue Wed Thu Fri Sat Sun\n”);

10 space = 0;
11 while (space < (startDay-1)*4)
12 {
13
14 printf(” ”);
15 space = space + 1;
16 }
17 date = 1;
18 while (date <= nDays)
19 {
20 if (date < 10)
21
22 printf(” ”);
23 printf(”%d”, date);
24
25 printf(” ”);
26 if ((date+startDay-1) % 7 == 0)
27
28 printf(”\n”);
29 date = date + 1;
30 } }
printf(”\n”);
return 0;

รหสั คำสัง่ ท่ี A.5: โปรแกรมการพิมพ์ปฏทิ ิน


Click to View FlipBook Version