基于partition函数解答某些编程题的思想

本文通过改变快速排序partition函数的接口,提出了两种解决问题的方法:最小的k个数和数组中出现超过一半的数字。对于最小的k个数问题,采用迭代的方式根据partition函数调整分割位置;对于数组中超过一半的数字问题,通过递归和partition函数找到满足条件的数字。此外,还提供了使用multiset和迭代器的高效解决方案。最后,通过测试函数验证了解决方案的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       快速排序的核心就是partition函数,我们可以对该函数的接口作适当的改变,来运用修改过的partion函数解决一些编程算法。

       这里举两个例子,这两个例子所用的partition函数如下所示:

int randomRange(int start,int end)
{
	return rand()%(end-start+1)+start;
}
int Partition(int input[],int length, int start,int end)
{
	if (input==NULL||length<=0||(end-start)>(length+1))
		throw new std::bad_exception("Invalid Parameters");
	int keyIndex=randomRange(start,end);
	swap(input[keyIndex],input[start]);
	int key=input[start];
	int p=start;                    
	int q=end+1;
	for (;;)
	{
		do p++;while(p<end&&input[p]<key);
		do q--;while(input[q]>key);	
		if (p<q)
			swap(input[p],input[q]);
		else
			break;
	}
	swap(input[start],input[q]);
	return q;
}

1、 最小的k个数,输入n个整数,找出其中最下的k个数,例如输入4、5、1、6、2、7、3、8、1、2,输出最下的4个数,则输出1、1、2、2。

       这个题目运用partition函数进行求解就是仿照快速排序,不过快速排序分割后对前后两段继续进行分割,而这里需要判定分割的位置,然后再确定对前段还是后段进行分割。代码如下:

void GetLeastNumbers_by_partition(int* input, int n, int* output, int k)
{
    if(input == NULL || output == NULL || k > n || n <= 0 || k <= 0)
        return;
	
    int start = 0;
    int end = n - 1;
    int index = Partition(input, n, start, end);
    while(index != k - 1)
    {
        if(index > k - 1)
        {
            end = index - 1;
            index = Partition(input, n, start, end);
        }
        else
        {
            start = index + 1;
            index = Partition(input, n, start, end);
        }
    }
	
    for(int i = 0; i < k; ++i)
        output[i] = input[i];
}

1、 数组中出现超过一半的数字,这一题就是《编程之美》上面寻找发帖水王的那题。

       选择合适的判定条件进行递归,就可以求出结果,代码如下:

bool g_bInputInvalid = false;

bool CheckInvalidArray(int* numbers, int length)
{
    g_bInputInvalid = false;
    if(numbers == NULL && length <= 0)
        g_bInputInvalid = true;
	
    return g_bInputInvalid;
}

bool CheckMoreThanHalf(int* numbers, int length, int number)
{
    int times = 0;
    for(int i = 0; i < length; ++i)
    {
        if(numbers[i] == number)
            times++;
    }
	
    bool isMoreThanHalf = true;
    if(times * 2 <= length)
    {
        g_bInputInvalid = true;
        isMoreThanHalf = false;
    }
	
    return isMoreThanHalf;
}
int MoreThanHalfNum_Solution1(int* numbers, int length)
{
    if(CheckInvalidArray(numbers, length))
        return 0;
	
    int middle = length >> 1;
    int start = 0;
    int end = length - 1;
    int index = Partition(numbers, length, start, end);
    while(index != middle)
    {
        if(index > middle)
        {
            end = index - 1;
            index = Partition(numbers, length, start, end);
        }
        else
        {
            start = index + 1;
            index = Partition(numbers, length, start, end);
        }
    }
	
    int result = numbers[middle];
    if(!CheckMoreThanHalf(numbers, length, result))
        result = 0;
	
    return result;
}

        最后给出一个基本的测试函数:

int main()
{

	int a[10]={4,5,1,6,2,7,3,8,1,2};
	int result[4]={0};
	GetLeastNumbers_by_partition(a,10, result, 4);
	for (int i=0;i<4;i++)
		cout << result[i];
	int b[10]={2,1,2,2,6,9,2,1,2,2};
	int num=MoreThanHalfNum_Solution1(b,10);
	cout <<endl<<num<<endl;
	return 0;
}

附录

       关于上述的两个编程题,有更加好的解法,代码如下:

1、

typedef multiset<int, greater<int> >            intSet;
typedef multiset<int, greater<int> >::iterator  setIterator;

void GetLeastNumbers_Solution2(const vector<int>& data, intSet& leastNumbers, int k)
{
    leastNumbers.clear();

    if(k < 1 || data.size() < k)
        return;

    vector<int>::const_iterator iter = data.begin();
    for(; iter != data.end(); ++ iter)
    {
        if((leastNumbers.size()) < k)
            leastNumbers.insert(*iter);

        else
        {
            setIterator iterGreatest = leastNumbers.begin();

            if(*iter < *(leastNumbers.begin()))
            {
                leastNumbers.erase(iterGreatest);
                leastNumbers.insert(*iter);
            }
        }
    }
}

2、

int MoreThanHalfNum_Solution2(int* numbers, int length)
{
    if(CheckInvalidArray(numbers, length))
        return 0;
 
    int result = numbers[0];
    int times = 1;
    for(int i = 1; i < length; ++i)
    {
        if(times == 0)
        {
            result = numbers[i];
            times = 1;
        }
        else if(numbers[i] == result)
            times++;
        else
            times--;
    }
 
    if(!CheckMoreThanHalf(numbers, length, result))
        result = 0;
 
    return result;
}




### Partition Function Usage in Programming The `partition` function or method is commonly found within various programming contexts, especially when dealing with algorithms that require dividing elements into groups based on certain criteria. In C++, the Standard Template Library (STL) provides an implementation of this functionality through its algorithm component[^2]. #### Using std::partition in C++ In C++'s STL, `std::partition` rearranges elements so that all elements for which a predicate returns true precede those for which it returns false. However, unlike `stable_partition`, `partition` does not guarantee relative order preservation among elements. Here’s how one can use `std::partition`: ```cpp #include <algorithm> #include <vector> #include <iostream> int main() { std::vector<int> v = {10, 7, 8, 9, 1, 5}; auto is_even = [](int i){ return i % 2 == 0; }; // Apply partition using lambda expression as predicate auto new_end = std::partition(v.begin(), v.end(), is_even); // Print results after applying partition for(auto iter=v.begin(); iter!=new_end; ++iter){ std::cout << *iter << " "; } } ``` This code snippet demonstrates moving even numbers to the front while odd ones follow them without maintaining their original sequence. For GPU-based computations involving CUDA, similar concepts apply but involve different APIs like hipLaunchKernelGGL(). These are used specifically for launching kernels rather than manipulating collections directly[^1]. When optimizing performance-critical applications either offline or online, understanding such functions helps improve efficiency by enabling better management of data structures during processing stages[^3]. --related questions-- 1. How does stable_partition differ from partition? 2. Can you provide examples where partition might be more efficient compared to other methods? 3. What role do predicates play in determining element placement within containers post-partition operation? 4. Are there equivalent operations available across multiple languages besides C++? 5. How would one implement custom partition logic outside standard libraries?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值