我正在尝试创建一个返回向量中第k个最小元素的代码。 例如: 假设你有一个包含元素{0,3,2,5}的向量rand 并且用户输入2作为K的值。 然后该函数应该从向量返回元素2,因为它是向量中的第二个(第k个)最小元素。
到目前为止,这是我的代码:
int iterative_kth_element(vector<int>& vec, size_t k)
{
int index = 0;
int min = vec[0];
for(int i = k;i<vec.size();i--) {
for (int j = 1; j < vec.size();j++) {
if ( min > vec[j] ) {
min = vec[j];
index = i;
}
vec.erase(vec.begin() + index);
if (i == 1) {
return min;
}
}
}
}
它不断返回一些甚至不在矢量中的巨大数字。
答案 0 :(得分:1)
for(int i = k;i<vec.size();i--)
似乎不正确,假设k
总是< vec.size()
,那么条件i<vec.size()
在这里完全没用。相反,你可能宁愿添加:
for(int i = k; i > 0; i--)
嵌套循环应该实际检查所有元素,因此它应该从0
开始(它跳过第一个元素):
for (int j = 0; j < vec.size(); j++) {
^
我相信
index = i;
原意是:
index = j;
确保所有可能的执行路径都返回一些值,注意编译器给你的警告。在函数末尾添加一个return
语句:
return min;
但您的主要问题是:
min
erase
调用尝试:
int foo(std::vector<int>& vec, const size_t k)
{
int index = 0;
int min = -1;
for(size_t i = 0; i < k; ++i) {
if (vec.empty()) return min;
min = vec[0];
for (size_t j = 0; j < vec.size(); ++j) {
if (vec[j] < min) {
min = vec[j];
index = j;
}
}
vec.erase(vec.begin() + index);
}
return min;
}
int main() {
int a[] = {0, 3, 2, 5};
std::vector<int> v(a, a+4);
std::cout << foo(v, 2);
}
答案 1 :(得分:1)
从这里开始:http://en.wikipedia.org/wiki/Selection_algorithm
int iterative_kth_element(vector<int>& vec, size_t k)
{
int minIndex, minValue;
for (int i = 0; i < k; i++)
{
minIndex = i;
minValue = vec[i];
for (int j = i+1; j < n; j++)
{
if (vec[j] < minValue)
{
minIndex = j;
minValue = vec[j];
}
}
int tmp = vec[i];
vec[i] = vec[minIndex];
vec[minIndex] = tmp;
}
return vec[k];
}
答案 2 :(得分:0)
以下是我的解决方案的一些不完整的代码。它只需要传递1次。这将相对于vec以线性时间运行。希望它可以解决问题。我以前的文字有点罗嗦。我把它留在了这个来源之下。
int iterative_kth_element(vector<int>& vec, size_t k)
{
int mins[k];
//assume first k elements are min
for(int i=0; i<k; i++)
{
mins[i] = vec[i];
}
//TODO:
//sort mins array here
//bubble sort is okay if k is small, or pivot
for(int i=k; i < vec.size(); i++)
{
//since mins is sorted, mins[k-1] is the highest value
if(vec[i] < mins[k-1])
{
mins[k-1] = vec[i];
}
//TODO:
//sort mins array here
//you could do a slick bubble sort starting from
//the back of mins until you find the location
//for the new min item
}
return mins[k-1];
}
//上一个文字
如果你找到了第k个最小的项目。您应该使用第一个k项初始化数组。或者将索引存储到找到最小项目的vec中(从0,1,2,3,...,k开始)
int index = 0;
int min = vec[0];
应该是
int* mins = new int[k];
for(int i=0; i < k; i++) {
mins[i] = vec[i];
}
我还建议保持这个k个最小整数的数组排序。如果您知道最大项目的位置,则只需检查vec中的每个元素与mins中的最大项目。你需要一种排序方法,每当你发现小于你的一个分钟时,就会调用它。
在vec的一次迭代之后,你应该在该数组中拥有k个最小的项目。只需返回最大的项目。存储在阵列中的位置0或k-1处。
需要注意的其他事项:如果k大于vec.size()/ 2,则应该查找(vec.size() - k)最大项。
这应该是log(k * n)时间,最大内存占用量为1.5n(k恰好是vec.size()/ 2的情况是最坏的情况)。
其中n是vec的大小,k是函数中的parm。(如果你实现了那个音符,k的上限是n / 2)。
最糟糕的情况是按降序排列数字列表,其中k是n的一半。
答案 3 :(得分:0)
1 /你有一个矢量,但你几乎只用它作为一个数组
2 /考虑使用迭代器。
3 /您正在接收向量作为参考,这意味着对其进行修改(例如擦除元素)在方法范围之外是有效的,您真的想要这样做吗?答案 4 :(得分:0)
设置整数数组。
从数组中删除分配的所有正元素 最大元素和最小元素之间。
计算数组的负数单元格的总和。
计算素数元素的最小值