算法学习(十)

1.Binary Search(二分法)

说明:二分法搜索是编程一项常见的任务,因为它是用于搜索排序数组(这就是我们学习排序的原因)和解决数学方程的方法。

我们的目标是解出如下形式的方程:

A * x + B * sqrt(x ^ 3) - C * exp(-x / 50) - D = 0

这里A B和C都是正的,所以这个函数是单调的。x的解肯定存在于0到100的范围内(0 <= x <= 100)。

解应该精确到0.0000001=1e-7或更好。

输入数据:第一行中包含测试用例数。

下面的行中包含每个测试用例的4个数字,即A B C D四个值用空格隔开。

答案:应该包含解——也就是x的值,它满足了给定的方程式——几个答案(对于几个测试用例)应该与空格分开。

例如:

input data:
2
0.59912051 0.64030348 263.33721367 387.92069617
15.68387514 1.26222280 695.23706506 698.72384731

answer:
73.595368554162 41.899174957955

测试数据:

6
9.20675416 0.87395008 1667.33525026 495.83581830
1.87353375 1.61305979 1376.91480917 1153.47175535
4.66566950 0.67303113 366.84269196 434.68812075
15.67052619 0.48875617 714.77221172 -264.23993463
14.69705865 0.69917802 297.42862112 1568.06585760
18.22457610 0.50751334 784.28709171 1720.63987051

代码如下:

 1 import math  # 需要用到math模块
 2 test_case = int(input())  # 测试用例数
 3 for i in range(test_case):
 4     case = input().split()   # 分别得到每行的A,B,C,D
 5     A = float(case[0])
 6     B = float(case[1])
 7     C = float(case[2])
 8     D = float(case[3])
 9     def func(x):
10         return A * x + B * math.sqrt(x ** 3) - C * math.exp(-x / 50) - D   # 建立个要求方程式,代入A,B,C,D 的值
11     low = 0
12     height = 100.0
13     n = low + (height - low) / 2.0    # 求中值
14     m = 100     # 因为发现代码出现了无限循环,分析后,所有的解经过100次的循环都可以解出来,所有设定100次循环
15     while func(n) != 0 and m > 0:   # 当方程不等于0,开始循环,可能就是因为n是小数,所有方程只能接近0,不能等于0,造成了无限循环
16         if func(n) > 0:             # 所以添加100的循环次数限制,避免无限循环
17             height = n - 1.0
18             low = low
19         elif func(n) < 0:
20             low = n + 1.0
21             height = height
22         n = low + (height - low) / 2.0
23         m -= 1    # 减少一次循环
24     print(n, end=' ')
25 
26 输出:61.34503889699867 84.37226003243683 56.756393017339064 15.062697470552255 78.1010605734923 82.05365393491547

  最后请教下各位大神,还有哪种方法能避免出现无线循环啊。

2.Selection Sort(选择排序法)

说明:假设我们有N个值的数组,想对它们排序,就像冒泡排序一样:

[3, 1, 4, 1, 5, 9, 2, 6, 5, 3]

我们方法如下:

在整个数组中,找到最大元素的位置(在上面的例子中,5是最大值9的索引);

将这个元素与最后一个元素交换(因为在排序的数组中,它应该是最后一个)——也就是位置N-1;

现在考虑长度为N-1的子数组,没有最后一个值(已经“在正确的位置”);

在这个子数组中找到最大元素的位置(也就是整个数组中的第二大元素)-现在它将是索引7(值6所在的位置);

将它与子数组中的最后一个元素交换(例如,位置n-2);

现在考虑长度n-2的子数组(没有两个最后的元素)-执行下面的选择和交换,等等;

当“子数组”减少到1时,算法就结束了。

例子:

[3, 1, 4, 1, 5, 9, 2, 6, 5, 3]      - max is 9 at position 5, swap 5-th with 9-th
[3, 1, 4, 1, 5, 3, 2, 6, 5], 9      - max is 6 at position 7, swap 7-th with 8-th
[3, 1, 4, 1, 5, 3, 2, 5], 6, 9      - max is 5 at position 4, swap 4-th with 7-th - they are equal!
[3, 1, 4, 1, 5, 3, 2], 5, 6, 9      - max is 5 at position 4, swap 4-th with 6-th
[3, 1, 4, 1, 2, 3], 5, 5, 6, 9      - max is 4 at position 2, swap 2-th with 5-th
[3, 1, 3, 1, 2], 4, 5, 5, 6, 9
...
[1], 1, 2, 3, 3, 4, 5, 5, 6, 9      - subarray of length 1 is reached, stop an algorithm.

分析:

这个算法需要让N通过数组,在每次传递时,它平均执行N/2操作,所以它有O(N^2)“时间复杂度”,和冒泡排序一样。然而,与冒泡排序不同的是,它并没有在每次传递中执行n/2交换,只需要进行一次交换。这使得它工作的更快,对于大型数据集来说,需要更多

这样的狡猾的算法。

您可以选择最小值,而不是最大值,然后将它们与数组的开始交换。同样,根据我们选择最左或右的最大值(或最小值),排序可能是稳定的,也可能是不稳定的,这意味着它要么保留或不保留相等元素的顺序当我们排序对象,而不是数字时,这可能很重要。

问题陈述:

您要实现上面描述的算法,并在每次传递时打印出所选择的最大值的索引。

输入数据:第一行中包含数组的大小。

下一行包含数组本身(所有元素都是不同的)。

答案:应该包含每个传递的最大值的索引(N-1值)。

例如:

input data:
6
31 41 59 26 53 58

answer:
2 2 2 1 0

测试数据:

128
54 28 159 13 163 41 137 160 4 191 129 173 61 44 102 135 161 32 130 16 53 142 38 5 26 172 196 190 199 51 149 15 150 175 45 153 166 127 27 17 30 162 178 92 193 113 34 117 39 57 11 104 24 118 183 93 60 2 87 19 84 49 145 140 59 174 22 78 29 131 73 35 36 66 58 154 50 31 48 157 107 79 12 98 95 42 182 85 99 156 106 74 169 184 103 116 151 105 152 146 180 21 126 119 33 96 197 133 72 25 114 110 189 6 55 170 63 67 186 192 65 64 90 177 136 158 125 109

代码如下:

test_case = int(input())  # 测试用例
data = input().split()  # 分隔字符
array = []
for i in data:
    array.append(int(i))   # 把字符转化为整数

for i in range(test_case - 1):
    max_index = array.index(max(array))
    print(max_index, end=' ')   # 打印索引
    last_elem = array[-1]
    array[-1] = max(array)  # 交换最大值和最后一个值
    array[max_index] = last_elem
    array = array[:-1]  # 返回新数组

输出:28 106 26 44 119 9 27 112 118 93 54 86 100 42 93 33 65 11 25 100 92 36 4 41 16 7 2 26 79 89 75 35 89 35 32 30 79 62 21 63 6 44 15 30 69 18 10 37 7 36 16 53 47 21 11 45 65 28 37 62 47 51 35 14 63 37 4 30 55 43 9 43 6 30 10 47 7 28 26 30 11 33 27 44 12 12 14 21 26 12 0 20 29 10 4 20 10 13 15 5 13 22 13 15 4 14 17 16 17 0 1 12 15 13 11 7 2 6 2 1 6 3 0 0 3 0 1 
原文地址:https://www.cnblogs.com/zt19994/p/7406052.html