1. 程式人生 > >找到陣列中第k大值的位置

找到陣列中第k大值的位置

找出陣列中第K大小的數,輸出數所在的位置。例如{2,4,3,4,7},第1大的數是7,位置在4。第2大,第3大的數是4,位置在1,3,則返回1和3都可以。

分析:考慮map:map<key,value> 自帶對value去重和對key排序的功能,所以可以把位置下標放在value,把陣列元素的值放在key。這樣對key排序完,找到第k個值對應的下標就可以了。

#include<map>
#include<iostream>
#include<string>
using namespace std;
int findn(int *num,int len,unsiged int n);
int main()
{
 int array[9]={1,2,4,4,3,8,2,2,2};
  int len=9;
 unsigned k;
  cin>>k;
int addr=findn(array,len,k);
cout<<addr<<endl;
}
int findn(int *num,int len ,unsigned int n)
{
 map<int,int> ma;
int i=0;
int *p;
p=num;
int fl_num;
while(ma.size()!=k)
{
 ma[*(p+i)]=i;
i++;
}
map<int,int>::iterator it;
it=ma.begin();
fl_num=it->first;
for(i;i<len;i++)  此時i是從k+1開始的值,遍歷剩下的值
{
 if(*(p+i))>fl_num)
  {
    ma[*(p+i)]=i;
   ma.erase(fl_num);
   it=ma.begin();
   fl_num=it->first;
  }
}
return it->second;
}
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <algorithm>
using namespace std;

int cmp1(int a, int b)
{
	return b<a;
}

//字串分割函式
vector<int> split(string str, string pattern)
{
	string::size_type pos;
	vector<int> result;

	str += pattern;//擴充套件字串以方便操作
	int size = str.size();

	for (int i = 0; i<size; i++)
	{
		pos = str.find(pattern, i);
		if (pos<size)
		{
			string s = str.substr(i, pos - i);
			int tmp = stoi(s);
			result.push_back(tmp);
			i = pos + pattern.size() - 1;
		}
	}
	return result;
}
int main1()
{
	string str;
	int pos;
	while (cin >> str >> pos)
	{
		vector<int> result = split(str, ",");
		vector<int> result_sort = result;
		sort(result_sort.begin(), result_sort.end(), cmp1);
		for (int i = 0; i < result.size(); i++)
		{
			if (result[i] == result_sort[pos-1])
			{
				cout << i+1 << endl;
				break;
			}
		}
	}
	system("pause");
	return 0;
}

找到第n大的數:

//利用快速排序的partition,經過一次partition後,陣列被privot分成左右兩部分,:S左和S右。當S左的元素個數等於k-1時,pivot就是所找的數,當S左小於k-1,所找的數位於S右中,同理,以此來縮小空間;
複雜度為:o(n)
#include<iostream>
using namespace std;
int partition(int a[],int i,int j)
{
int temp=a[i];
if(i<j)
{
 while(i<j)
    {// 從後向前找比選擇軸值得點小的位置
        while(i<j&&a[j]>=temp)  j--;//求第K大時,按照從大到小排序,求第K小時,按照從小到大排序
        if(i<j) a[i]=a[j];
        while(i<j&&a[i]<temp) i++;////
        if(i<j)   a[j]=a[i];
       }
        a[i]=temp;
    return i;
}
}
int search(int a[],int i,int j,int k)
{
    int m=partition(a,i,j);
    if(k==m-i+1)  return a[m];//正好找到第K個值在基準值右邊的數都比支點大。如果此時基準值的下 
                                標為i, 那麼這個基準值就是第(endIndex-i+1)大的數了。endIndex 
                                是最後一個數的下標。
    else if(k<m-i+1)
    {
        return search(a,i,m-1,k);
    }
    else{
            return search(a,m+1,j,k-(m-i+1));
        }
}
int main()
{
 int a[7]={1,3,9,5,6,8,2,4,8};
int k=3;
cout<<search(a,2,6,k);
}