Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
zhhf96
C-Plus-Plus-TheAlgorithms
提交
f308a05a
C
C-Plus-Plus-TheAlgorithms
项目概览
zhhf96
/
C-Plus-Plus-TheAlgorithms
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
C-Plus-Plus-TheAlgorithms
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
f308a05a
编写于
8月 23, 2020
作者:
A
Ayaan Khan
提交者:
GitHub
8月 23, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1045 from Rp-sushil/rp
[BUG] #804 search/median_search.cpp FIXED
上级
416a3bc1
b50591df
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
142 addition
and
64 deletion
+142
-64
search/median_search.cpp
search/median_search.cpp
+142
-64
未找到文件。
search/median_search.cpp
浏览文件 @
f308a05a
/**
* \file
* \brief [Median search](https://en.wikipedia.org/wiki/Median_search) algorithm
* \warning This core is erroneous and gives invorrect answers. Tested using
* cases from [here](https://brilliant.org/wiki/median-finding-algorithm/)
* \ingroup median search
* \{
* @file median_search.cpp
* @brief Implementation of [Median search](https://en.wikipedia.org/wiki/Median_of_medians) algorithm.
* @cases from [here](https://brilliant.org/wiki/median-finding-algorithm/)
*
* @details
* Given an array A[1,...,n] of n numbers and an index i, where 1 ≤ i ≤ n, find the i-th smallest element of A.
* median_of_medians(A, i):
* #divide A into sublists of len 5
* sublists = [A[j:j+5] for j in range(0, len(A), 5)]
* medians = [sorted(sublist)[len(sublist)/2] for sublist in sublists]
* if len(medians) <= 5:
* pivot = sorted(medians)[len(medians)/2]
* else:
* #the pivot is the median of the medians
* pivot = median_of_medians(medians, len(medians)/2)
* #partitioning step
* low = [j for j in A if j < pivot]
* high = [j for j in A if j > pivot]
* k = len(low)
* if i < k:
* return median_of_medians(low,i)
* elif i > k:
* return median_of_medians(high,i-k-1)
* else: #pivot = k
* return pivot
*
* \note this algorithm implements median search for only arrays which have distinct elements
*
* Here are some example lists you can use to see how the algorithm works
* A = [1,2,3,4,5,1000,8,9,99] (Contain Unique Elements)
* B = [1,2,3,4,5,6] (Contains Unique Elements)
* print median_of_medians(A, 0) #should be 1
* print median_of_medians(A,7) #should be 99
* print median_of_medians(B,4) #should be 5
*
* @author Unknown author
* @author [Sushil Kumar](https://github.com/Rp-sushil)
*/
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
/**
* @todo add documentation
* @namespace search
* @brief Search algorithms
*/
namespace
search
{
/**
* @namespace median_search
* @brief Functions for [Median search](https://en.wikipedia.org/wiki/Median_search) algorithm
*/
template
<
class
X
>
void
comp
(
X
x
,
std
::
vector
<
int
>
*
s1
,
std
::
vector
<
int
>
*
s2
,
std
::
vector
<
int
>
*
s3
)
{
if
(
s1
->
size
()
>=
x
&&
s1
->
size
()
+
s2
->
size
()
<
x
)
{
std
::
cout
<<
(
*
s2
)[
0
]
<<
" is the "
<<
x
+
1
<<
"th element from front"
;
}
else
if
(
s1
->
size
()
>
x
)
{
std
::
sort
(
s1
->
begin
(),
s1
->
end
());
std
::
cout
<<
(
*
s1
)[
x
]
<<
" is the "
<<
x
+
1
<<
"th element from front"
;
}
else
if
(
s1
->
size
()
+
s2
->
size
()
<=
x
&&
s3
->
size
()
>
x
)
{
std
::
sort
(
s3
->
begin
(),
s3
->
end
());
std
::
cout
<<
(
*
s3
)[
x
-
s1
->
size
()
-
s2
->
size
()]
<<
" is the "
<<
x
+
1
<<
"th element from front"
;
}
else
{
std
::
cout
<<
x
+
1
<<
" is invalid location"
;
}
namespace
median_search
{
/**
* This function search the element in an array for the given index.
* @param A array where numbers are saved
* @param idx current index in array
* @returns corresponding element which we want to search.
*/
int
median_of_medians
(
const
std
::
vector
<
int
>&
A
,
const
int
&
idx
)
{
int
pivot
=
0
;
// initialized with zero
std
::
vector
<
int
>
a
(
A
.
begin
(),
A
.
end
());
std
::
vector
<
int
>
m
;
int
r
=
a
.
size
();
for
(
int
i
=
0
;
i
<
r
;
i
+=
5
){
std
::
sort
(
a
.
begin
()
+
i
,
a
.
begin
()
+
std
::
min
(
r
,
i
+
5
));
int
mid
=
(
i
+
std
::
min
(
r
,
i
+
5
))
/
2
;
m
.
push_back
(
a
[
mid
]);
}
int
sz
=
int
(
m
.
size
());
if
(
sz
<=
5
){
std
::
sort
(
m
.
begin
(),
m
.
end
());
pivot
=
m
[(
sz
-
1
)
/
2
];
}
else
{
pivot
=
median_of_medians
(
m
,
idx
);
}
std
::
vector
<
int
>
low
;
std
::
vector
<
int
>
high
;
for
(
int
i
=
0
;
i
<
r
;
i
++
){
if
(
a
[
i
]
<
pivot
){
low
.
push_back
(
a
[
i
]);
}
else
if
(
a
[
i
]
>
pivot
){
high
.
push_back
(
a
[
i
]);
}
}
int
k
=
int
(
low
.
size
());
if
(
idx
<
k
){
return
median_of_medians
(
low
,
idx
);
}
else
if
(
idx
>
k
){
return
median_of_medians
(
high
,
idx
-
k
-
1
);
}
else
{
return
pivot
;
}
}
}
// namespace median_search
}
// namespace search
#define MAX_NUM 20 ///< maximum number of values to sort from
/**
* Function to test above algorithm
*/
void
test
(){
std
::
vector
<
int
>
A
{
25
,
21
,
98
,
100
,
76
,
22
,
43
,
60
,
89
,
87
};
int
i
=
3
;
assert
(
A
[
6
]
==
search
::
median_search
::
median_of_medians
(
A
,
i
));
// A[6] = 43, is the fourth smallest element.
std
::
cout
<<
"test case:1 passed
\n
"
;
std
::
vector
<
int
>
B
{
1
,
2
,
3
,
4
,
5
,
6
};
int
j
=
4
;
assert
(
B
[
4
]
==
search
::
median_search
::
median_of_medians
(
B
,
j
));
// B[4] = 5, is the fifth smallest element.
std
::
cout
<<
"test case:2 passed
\n
"
;
std
::
vector
<
int
>
C
{
1
,
2
,
3
,
4
,
5
,
1000
,
8
,
9
,
99
};
int
k
=
3
;
assert
(
C
[
3
]
==
search
::
median_search
::
median_of_medians
(
C
,
k
));
// C[3] = 4, is the fourth smallest element.
std
::
cout
<<
"test case:3 passed
\n
"
;
std
::
cout
<<
"--All tests passed--
\n
"
;
}
/**
* Main function
*/
int
main
()
{
std
::
vector
<
int
>
v
{
25
,
21
,
98
,
100
,
76
,
22
,
43
,
60
,
89
,
87
};
std
::
vector
<
int
>
s1
;
std
::
vector
<
int
>
s2
;
std
::
vector
<
int
>
s3
;
// creates an array of random numbers
// for (int i = 0; i < MAX_NUM; i++) {
// int r = std::rand() % 1000;
// v.push_back(r);
// std::cout << r << " ";
// }
for
(
int
r
:
v
)
std
::
cout
<<
r
<<
" "
;
int
median
=
std
::
rand
()
%
1000
;
// initialize to a random numnber
std
::
cout
<<
"
\n
median="
<<
median
<<
std
::
endl
;
int
avg1
,
avg2
,
avg3
,
sum1
=
0
,
sum2
=
0
,
sum3
=
0
;
for
(
int
i
=
0
;
i
<
v
.
size
();
i
++
)
{
// iterate through all numbers
if
(
v
.
back
()
==
v
[
median
])
{
avg1
=
sum1
+
v
.
back
();
s2
.
push_back
(
v
.
back
());
}
else
if
(
v
.
back
()
<
v
[
median
])
{
avg2
=
sum2
+
v
.
back
();
s1
.
push_back
(
v
.
back
());
}
else
{
avg3
=
sum3
+
v
.
back
();
s3
.
push_back
(
v
.
back
());
}
v
.
pop_back
();
}
int
x
;
std
::
cout
<<
"enter the no. to be searched form begining:- "
;
std
::
cin
>>
x
;
comp
(
x
-
1
,
&
s1
,
&
s2
,
&
s3
);
return
0
;
int
main
()
{
test
();
int
n
=
0
;
std
::
cout
<<
"Enter Size of Array: "
;
std
::
cin
>>
n
;
std
::
vector
<
int
>
a
(
n
);
std
::
cout
<<
"Enter Array: "
;
for
(
int
i
=
0
;
i
<
n
;
i
++
){
std
::
cin
>>
a
[
i
];
}
std
::
cout
<<
"Median: "
;
// Median defination: https://en.wikipedia.org/wiki/Median
int
x
=
search
::
median_search
::
median_of_medians
(
a
,
(
n
-
1
)
/
2
);
if
(
n
%
2
==
0
){
int
y
=
search
::
median_search
::
median_of_medians
(
a
,
n
/
2
);
std
::
cout
<<
(
float
(
x
)
+
float
(
y
))
/
2.0
;
}
else
{
std
::
cout
<<
x
;
}
std
::
cout
<<
"
\n
To find i-th smallest element "
;
std
::
cout
<<
"
\n
Enter i: "
;
int
idx
=
0
;
std
::
cin
>>
idx
;
idx
--
;
std
::
cout
<<
idx
+
1
<<
"-th smallest element: "
<<
search
::
median_search
::
median_of_medians
(
a
,
idx
)
<<
'\n'
;
return
0
;
}
/// }
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录