python 3.2 - ค้นหาตัวเลขที่เล็กที่สุดเป็นอันดับสองในรายการโดยใช้การเรียกซ้ำ

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

def smallest(int_list):

    if(len(int_list) == 1):
        return int_list[0]
    else:
        a = smallest(int_list[1:])
        b = int_list[0]

        if(a <= b):
            return a
        else:
            return b

ใครสามารถชี้ฉันไปในทิศทางที่ถูกต้อง?


person Niiks    schedule 26.01.2015    source แหล่งที่มา
comment
สร้าง 2 ฟังก์ชัน ฟังก์ชันหนึ่งค้นหาค่าที่น้อยที่สุดและฟังก์ชันหนึ่งที่พยายามค้นหาค่าที่น้อยที่สุดถัดไปโดยให้ค่าที่ส่งคืนของฟังก์ชันแรก   -  person smac89    schedule 26.01.2015
comment
แทนที่จะส่งคืนค่าที่น้อยที่สุด ให้ลองส่งคืนทูเพิลที่มีส่วนที่เล็กที่สุดและเล็กที่สุดเป็นอันดับสองของรายการที่คุณได้ดำเนินการไปแล้ว อัปเดตทูเพิลต่อไปในแต่ละขั้นตอน   -  person shridharama    schedule 26.01.2015
comment
en.wikipedia.org/wiki/Quickselect อธิบายเรื่องนี้ได้ค่อนข้างดี   -  person georg    schedule 26.01.2015
comment
ตรวจสอบคำตอบของฉัน ฉันใช้งานบางอย่างตามที่ @shridharama แนะนำ   -  person levi    schedule 26.01.2015
comment
มีสิ่งหนึ่งที่ไม่ชัดเจนนัก คุณต้องการส่งคืนองค์ประกอบเลขคู่ที่เล็กที่สุดอันดับที่ 2 ซ้ำกันเหมือน return 1 ใน [1,1,2,3] หรือไม่ หรือคุณต้องการ 2?   -  person Anzel    schedule 26.01.2015


คำตอบ (7)


นี่คือการใช้งานสั้นๆ ที่ไม่ใช้ min() หรือ sorted() นอกจากนี้ยังใช้งานได้เมื่อมีค่าซ้ำกันในรายการอีกด้วย

def ss(e):
    if len(e)==2 and e[0]<=e[1]:return e[1]
    return ss(e[:-1]) if e[0]<=e[-1]>=e[1] else ss([e[-1]]+e[:-1])

print("The selected value was:", ss([5, 4, 3, 2, 1]))
person Jason Sanchez    schedule 29.03.2015

ที่นี่:

def r_sort(a_list, ind):
    def rf(list_to_be_sorted, list_already_sorted):
        li = []
        if len(list_to_be_sorted) == 0:
            return list_already_sorted
        else:    
            x = min(list_to_be_sorted)    
            list_to_be_sorted.remove(x)
            li.append(x)
            return rf(list_to_be_sorted, list_already_sorted + li)
    return rf(a_list, [])[ind]

>>> r_sort([1,10,9,5,55,3,2], 1)  
2
person Community    schedule 26.01.2015

สิ่งนี้ควรจะได้ผล get_smallest_two_items() ส่งคืนสิ่งอันดับที่มี 2 องค์ประกอบที่เล็กที่สุดจาก 3 อินพุต การนำไปปฏิบัติควรเป็นเรื่องเล็กน้อย โปรดทราบว่าการดำเนินการนี้จะถือว่าความยาวขั้นต่ำของรายการคือ 2

def smallest(int_list):
   smallest_two = smallest_helper(int_list)
   return smallest_two[0] if smallest_two[0]<=smallest_two[1] else smallest_two[1]

def smallest_helper(int_list):

  if(len(int_list) == 2):
    return (int_list[0],int_list[1])
  else:
    a_b = smallest(int_list[1:])
    a = a_b[0]
    b = a_b[1]
    c = int_list[0]

    return get_smallest_two_items(a,b,c)
person shridharama    schedule 26.01.2015
comment
อืม รังเกียจที่จะแสดงความคิดเห็นก่อนที่จะโหวตลง? - person shridharama; 26.01.2015
comment
แน่นอน นั่น get_smallest_two_items(a,b,c) มาจากไหน? - person Anzel; 26.01.2015
comment
@Anzel ยังไงกันแน่? มันจะส่งคืนค่าที่น้อยที่สุดของ a, b และ c เป็นสิ่งอันดับตามที่กล่าวไว้ในคำตอบของฉัน - person shridharama; 26.01.2015
comment
คุณได้ทดสอบรหัสของคุณแล้วหรือยัง? คุณไม่มีชื่อฟังก์ชันที่เรียกว่า get_smallest_two_items()... มันคือ NameError - person Anzel; 26.01.2015
comment
ฉันได้กล่าวถึงในคำตอบว่าวิธีนี้ควรใช้งานง่าย เป้าหมายของฉันไม่ใช่การเขียนโค้ดที่ปฏิบัติการได้อย่างสมบูรณ์แบบ แต่เป็นการชี้ OP ไปในทิศทางที่ถูกต้องมากกว่า Stackoverflow ไม่ได้มีไว้สำหรับการป้อนโค้ดทุกบรรทัดโดยใช้ช้อน - person shridharama; 26.01.2015
comment
โอเค คุณมีจุดที่ถูกต้องแต่อ่อนแอ คุณกำลังใช้ฟังก์ชันแบบเรียกซ้ำซึ่งตัวมันเองไม่ได้อธิบายมากนักหรือให้ทิศทางที่ชัดเจน ฉันจะถอน downvote อีกครั้ง - person Anzel; 26.01.2015

ตัวอย่างที่ง่ายกว่าความคิดเห็นของฉัน:

def find_nth_smallest(n, int_list):
    smallest = min(int_list)
    if n <= 1:
        return smallest
    int_list = [v for v in int_list if v != smallest]
    if int_list:
        return max(find_nth_smallest(n - 1, int_list), smallest)
    return None

ตัวอย่าง:

Python 2.7.8 (default, Oct 20 2014, 15:05:19) 
[GCC 4.9.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from kthTerm import find_nth_smallest
>>> import random
>>> random.seed()
>>> int_list = [random.randint(1, 100) for _ in range(20)]
>>> int_list
[68, 50, 6, 36, 98, 15, 81, 36, 13, 71, 76, 77, 69, 75, 79, 53, 26, 25, 18, 62]
>>> find_nth_smallest(2, int_list)
13
>>> sorted(int_list)
[6, 13, 15, 18, 25, 26, 36, 36, 50, 53, 62, 68, 69, 71, 75, 76, 77, 79, 81, 98]
person smac89    schedule 26.01.2015

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

import random

def min2(xs):
    if len(xs) < 3: return xs
    n = len(xs) // 2
    return sorted(min2(xs[:n]) + [xs[n]] + min2(xs[n+1:]))[:2]

tk = range(100000)
random.shuffle(tk)
print min2(tk)
person Paul Hankin    schedule 26.01.2015

นี่เป็นวิธีเรียกซ้ำล้วนๆ คุณต้องส่งคืนองค์ประกอบที่เล็กที่สุดตัวแรกและตัวที่สองที่เล็กที่สุดในทูเพิลเป็นต้น

def smallest(int_list):

    if(len(int_list) == 2):
        if (int_list[0] >= int_list[1]):
            return (int_list[0],int_list[1])
        else:
            return (int_list[1],int_list[0])
    else:
        first_smallest,second_smallest = smallest(int_list[1:])
        current_elem = int_list[0]
        if(second_smallest <= current_elem):
            return (second_smallest,current_elem)
        else:
            if (current_elem<=first_smallest):
               return (current_elem,first_smallest)
            else:
               return (first_smallest,second_smallest)



if __name__ == "__main__":    
    small = smallest([1,2,3,4])
    print small[1]
    //output 2 
person levi    schedule 26.01.2015
comment
เล็กที่สุด ([2,1,3,4,5]) ควรส่งคืน 2 ผลตอบแทนนี้ (1, 3) - person Jason Sanchez; 12.08.2015

def Second_smallest (my_list):

if len(my_list) == 2:
    return my_list[0] if my_list[0] > my_list[1] else my_list[1]

else:
    sec_least = second_smallest(my_list[1:])
    return sec_least if sec_least < my_list[0] else my_list[1]
person jellyman2014    schedule 27.01.2015
comment
Second_smallest([2,1,3,4,5]) ส่งคืน 1 แต่ควรส่งคืน 2 Second_smallest([1,1,2,3,4]) ส่งคืน 2 แต่ควรส่งคืน 1 - person Jason Sanchez; 12.08.2015