จำนวนคี่ที่ใหญ่ที่สุด

Aug 19 2020

ขอให้ผู้ใช้ป้อนจำนวนเต็ม 10 จำนวนแล้วพิมพ์จำนวนคี่ที่ใหญ่ที่สุดที่ป้อน หากไม่ได้ป้อนเลขคี่ให้พิมพ์ข้อความเพื่อเอฟเฟกต์นั้น

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

counter = 0
odd = []

while counter < 10:
    x = int(input("Enter a number: "))
    if abs(x)%2 != 0:
        odd.append(x)
    counter += 1

if len(odd) == 0:
    print("No odd number was entered")
else:
    print("The largest odd number is:", max(odd))

คำตอบ

19 MarioIshac Aug 19 2020 at 07:14

สำหรับโปรแกรมปัจจุบันของคุณเราสามารถปรับปรุงสองสิ่ง:

  1. เปลี่ยนชื่อoddเป็นodds(เนื่องจากเป็นlist)
  2. ใช้not oddsแทนlen(odds) == 0(ดูฉันจะตรวจสอบได้อย่างไรว่ารายการว่างเปล่าหรือไม่ด้วยเหตุผลว่าทำไมจึงเป็นที่ต้องการ)
  3. ลบcounter. เนื่องจากเราใช้เฉพาะcounterในwhileสภาพที่เราจริงสามารถแทนที่ทั้งหมดด้วยwhilefor _ in range(10)
  4. ปฏิบัติตามPEP 8 . ตัวอย่างเช่นใช้ช่องว่าง 4 ช่องสำหรับแต่ละระดับการเยื้อง

เราได้รับปัจจัยในการเปลี่ยนแปลงทั้งหมดนี้:

odds = []

for _ in range(10):
    x = int(input("Enter a number: "))
    if abs(x) % 2 != 0:
        odds.append(x)

if not odds:
    print("No odd number was entered")
else:
    print("The largest odd number is:", max(odds))

แต่เรายังสามารถปรับปรุงประสิทธิภาพของโปรแกรมนี้ ตอนนี้เราติดตามจำนวนคี่ทั้งหมดก่อนที่จะเลือกสูงสุด ซึ่งหมายความว่าความซับซ้อนของพื้นที่คือ O (N) เราสามารถเปลี่ยนค่านี้เป็น O (1) ได้โดยติดตามจำนวนคี่ที่ใหญ่ที่สุดดังนี้:

max_odd = None

for _ in range(10):
    x = int(input("Enter a number: "))

    if abs(x) % 2 != 0:
        max_odd = x if max_odd is None else max(max_odd, x)

if max_odd is None:
    print("No odd number was entered")
else:
    print("The largest odd number is: ", max_odd)

โปรดทราบว่าเราใช้Noneเพื่อแสดงว่ายังไม่มีการป้อนเลขคี่ซึ่งในกรณีนี้เมื่อป้อนเลขคี่เราตั้งค่าmax_oddเป็นxโดยตรง มิฉะนั้นเราตั้งไปmax_oddmax(max_odd, x)

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

ในที่สุดก็มีอีกสิ่งหนึ่งที่คุณสามารถทำได้ หากคุณต้องการอนุญาตให้โปรแกรมสะสมตัวเลขต่อไปในกรณีที่strพิมพ์โดยไม่ได้ตั้งใจซึ่งไม่สามารถแยกวิเคราะห์เป็นตัวเลขได้ (เช่น"") เราสามารถใช้ a try/ exceptห่อในwhileลักษณะดังนี้:

while True:
    try:
        x = int(input("Enter a number: "))
        break
    except ValueError:
        continue

สิ่งนี้จะแทนที่:

x = int(input("Enter a number: "))

ในรหัสเดิม สิ่งนี้จะแจ้งให้ผู้ใช้พิมพ์ a strที่สามารถแยกวิเคราะห์ได้intจนกว่าพวกเขาจะทำ เนื่องจากทั้งหมดนี้เกิดขึ้นในการวนซ้ำเหมือนกันforจำนวนตัวเลขที่พวกเขาจะพิมพ์ (10 ในกรณีของเรา) จะไม่ลดลง

6 GZ0 Aug 19 2020 at 08:58

เพิ่มไปยังบทวิจารณ์ก่อนหน้า:

  • เมื่อxเป็นจำนวนเต็มabs(x) % 2เท่ากับx % 2ใน Python เอาต์พุตของตัวดำเนินการโมดูโล%มีเครื่องหมายเดียวกับตัวถูกดำเนินการที่สอง
  • เมื่อใช้รหัสนอกวิธีการ / ชั้นก็เป็นวิธีที่ดีที่จะนำรหัสภายในยามหลัก ดูคำอธิบายเพิ่มเติมที่นี่

ใน Python 3.8 สามารถย่อโค้ดได้โดยใช้ตัวดำเนินการกำหนด:=ร่วมกับmaxฟังก์ชัน

if __name__ == "__main__":
    # Number generator
    num_gen = (o for _ in range(10) if (o := int(input("Enter a number: "))) % 2 != 0)
    max_odd = max(num_gen, default=None)
    if max_odd is None:
        print("No odd number was entered")
    else:
        print(f"The largest odd number is: {max_odd}")

การรวมint(input("Enter a number: "))เข้ากับฟังก์ชันช่วยให้อ่านได้ง่ายขึ้น:

def read_input() -> int:
    return int(input("Enter a number: "))

if __name__ == "__main__":
    num_gen = (o for _ in range(10) if (o := read_input()) % 2 != 0)
    max_odd = max(num_gen, default=None)
    if max_odd is None:
        print("No odd number was entered")
    else:
        print(f"The largest odd number is: {max_odd}")

ตัวแปรอื่นที่จัดการอินพุตของผู้ใช้ที่ไม่ถูกต้องมีดังนี้:

def read_input() -> int:
    while True:
        try:
            return int(input("Enter a number: "))
        except ValueError:
            continue

if __name__ == "__main__":
    try:
        max_odd = max(o for _ in range(10) if (o := read_input()) % 2 != 0)
        print(f"The largest odd number is: {max_odd}")
    except ValueError:
        # Since read_input() no longer raises ValueError, the except
        # statement here only handles the cases where max() gets no inputs
        print("No odd number was entered")
3 AlexeyBurdin Aug 19 2020 at 12:56

ฉันขอถามว่าคุณฝึกภาษาโปรแกรมอะไรก่อน python?
ฉันต้องการพูดถึงซับเดียวสำหรับสิ่งนี้:

max(l,key=lambda x:(x%2,x))

สมมติว่าคุณได้lป้อนข้อมูลแล้วเช่น

s='Enter a number: '
l=[int(input(s)) for i in range(10)]

รหัสทำงานอย่างไร? มันดูสูงสุดkey(x)สำหรับxในและผลตอบแทนดังกล่าวl xที่สำคัญที่นี่คือฟังก์ชั่นแลมบ์ดาที่ผลตอบแทน tuple (1,x)สำหรับแปลกxและแม้แต่(0,x) xtuples จะเทียบจากซ้ายไปขวาเช่น(1,x)>(0,y)ทุกและx yดังนั้นเราจึงพูดแค่ว่า "ให้ค่าสูงสุดแก่ฉันlโดยสมมติว่าจำนวนคี่มีค่ามากกว่าจำนวนคู่เสมอ"

ดังนั้นโปรแกรมทั้งหมดจะมีลักษณะดังนี้

s='Enter a number: '
l=[int(input(s)) for i in range(10)]
m=max(l,key=lambda x:(x%2,x))
if m%2:
    print('The largest odd number is: %d'%m)
else: #the greatest is even, therefore no odd numbers
    print('No odd number was entered')

สั้นดีและง่ายเหมือนงูหลาม

แต่ฉันยอมรับว่า try-except block รอบ ๆint(input())รูปแบบคำตอบที่ยอมรับนั้นมีประโยชน์พร้อมกับไม่มีการจัดเก็บรายการค่าคี่ทั้งหมดไว้ล่วงหน้า

ฉันแค่อยากจะแสดงให้เห็นถึงกระบวนทัศน์ของการเขียนโปรแกรมเชิงฟังก์ชันใน python เมื่อคุณบอก python ว่า 'ฉันต้องการให้เสร็จ (เช่นค่าสูงสุด)' และมันก็ทำเพื่อคุณคุณไม่จำเป็นต้องอธิบายว่าควรทำอย่างไร

ขอบคุณที่อ่าน.

3 EmilioMBumachar Aug 19 2020 at 21:36

ฉันจะพยายามสร้างคำแนะนำสุดท้ายของคำตอบที่ยอมรับ

while True:
    try:
        x = int(input("Enter a number: "))
        break
    except ValueError:
        continue

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

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

ดีกว่าที่จะให้ข้อเสนอแนะ:

while True:
    try:
        x = int(input("Enter a number: "))
        break
    except ValueError:
        print("Invalid number will be ignored.")
        continue

... หรือดีกว่านั้นให้พิมพ์หมายเลขที่พิมพ์ผิดกลับไปที่:

while True:
    try:
        inputString = input("Enter a number: ")
        x = int(inputString)
        break
    except ValueError:
        print("Invalid number will be ignored: {}".format(inputString))
        continue

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

print("Numbers provided are: {}".format(all_valid_numbers_inputted))
if not odds:
    print("No odd number was entered")
else:
    print("The largest odd number is:", max(odds))

หากคุณทำเช่นนี้ขั้นตอนต่อไปคือการกำจัดตัวแปร "odds" และหาจำนวนคี่ที่ใหญ่ที่สุดโดยตรงจากรายการทั้งหมด

1 FMc Aug 25 2020 at 12:23

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

def as_int(s):
    try:
        return int(s)
    except Exception:
        return 0

N = 3
MSG = 'Enter number: '

replies = [input(MSG) for _ in range(N)]  # Interact.
nums = [as_int(r) for r in replies]       # Convert.
odds = [n for n in nums if n % 2]         # Compute.

if odds:                                  # Report.
    print(max(odds))