算法分析与设计
题目1:
【问题描述】每次都是随机选出一个元素为划分基准,在平均情况下线性时间内寻找第i小元素。
【输入形式】在屏幕上输入若干整数,各数间都以一个空格分隔。再输入要寻找的元素是数组从小到大顺序中第几个位置。
【输出形式】数组从小到大顺序中要寻找的那个位置的元素。
【样例输入】
2 9 8 0 7 10 1 12 3 14 5 13 6 11 4
3
【样例输出】
2
【样例说明】
输入:15个整数,以空格分隔。要寻找第3小元素。
输出:2,表示第3小元素为2。
【评分标准】根据输入得到准确的输出。
算法思路很清晰
刚开始使用numpy,不熟悉array的操作,出现了一些问题
结果是错误的
发现问题出在函数
Partition ()
部分
def Partition(list1, p, r):
i = p - 1
j = p
x = list1[r]
# 将小于x的元素交换到左边区域, 将大于x的元素交换到右边区域
while j < r:
if list1[j] <= x:
#print(list1[j], x)
i += 1
list1[i], list1[j] = list1[j], list1[i]
j += 1
list1[i + 1], list1[r] = list1[r], list1[i + 1] # 始终以a[r]为基准,小于a[r]则调到前面 故i+1 之前都小于a[r]
#print("par return ", i+1)
return i + 1
调试中:
x是str_类型的8, list1[j]是str_类型的13
而list1[j] 经过多次测试,发现对于个位数如 5 1~4<5 6~9>5 10~14<5 15~19>5 认为是数据类型的问题,于是使用 进行对numpy array 的强制类型转换 结果正确! arr = arr.astype(np.int32)
# 随机策略线性时间内寻找元素
"""
【问题描述】每次都是随机选出一个元素为划分基准,在平均情况下线性时间内寻找第i小元素。
【输入形式】在屏幕上输入若干整数,各数间都以一个空格分隔。再输入要寻找的元素是数组从小到大顺序中第几个位置。
【输出形式】数组从小到大顺序中要寻找的那个位置的元素。
【样例输入】
2 9 8 0 7 10 1 12 3 14 5 13 6 11 4
3
【样例输出】
2
【样例说明】
输入:15个整数,以空格分隔。要寻找第3小元素。
输出:2,表示第3小元素为2。
【评分标准】根据输入得到准确的输出。
"""
import numpy as np
import random
def Partition(list1, p, r):
i = p - 1
j = p
x = list1[r]
# 将小于x的元素交换到左边区域, 将大于x的元素交换到右边区域
while j < r:
if list1[j] <= x:
#print(list1[j], x)
i += 1
list1[i], list1[j] = list1[j], list1[i]
j += 1
list1[i + 1], list1[r] = list1[r], list1[i + 1] # 始终以a[r]为基准,小于a[r]则调到前面 故i+1 之前都小于a[r]
#print("par return ", i+1)
return i + 1
# 随机选取基准元素
def RandomizedPartition(a, p, r):
i = random.randint(p, r)
a[i], a[r] = a[r], a[i]
return Partition(a, p, r)
def RandomizedSelect(a, p, r, k):
if p == r:
return a[p]
i = RandomizedPartition(a, p, r)
j = i - p + 1
if k <= j:
return RandomizedSelect(a, p, i, k)
else:
return RandomizedSelect(a, i+1, r, k-j)
def main():
list1 = input().split()
list(map(int, list1))
list1 = (list1)
arr = np.array(list1)
arr = arr.astype(np.int32)
#print(arr.dtype)
#print(arr)
k = int(input())
ans = RandomizedSelect(arr, 0, arr.size - 1, k)
print(ans)
if __name__ == '__main__':
main()