排列问题、整数划分问题

1、排列问题:设r={r1,r2,…,rn}是n个元素的集合,求r的全排列。

(1)设计思想:

设 R={r1,r2,,rn} 是要进行排列的n个元素。Rᵢ=R−rᵢ。 集合X中元素的全排列记为 ᵢPerm(X)(rᵢ)Perm(X))表示在全排列Perm(X)的每个排列前加上前缀n ᵢrᵢ得到的排列。R的全排列可归纳定义如下:

当n=1时, Perm(R)=(r),其中r是集合R中唯一的元素;

当n>1时, Perm(R)由 (r1)Perm(R1),(r2)Perm(R2),,(rn)Perm(Rn) 构成。

依此递归定义,可设计产生Perm(R)的递归算法如下:

(2)程序代码:

#include<stdio.h>
#include"iostream.h"
template <class Type>
void Perm(Type list[],int k,int m)
{
if(k==m)
{
for(int i=0;i<=m;i++)
cout<<list[i];
cout<<endl;
}
else
{
for(int i=k;i<=m;i++)
{
Swap(list[k],list[i]);
Perm(list,k+1,m);
Swap(list[k],list[i]);
}
}
}
template<class Type>
inline void Swap(Type &a,Type &b)
{
Type temp=a;
a=b;
b=temp;
}
void main()
{
int ar[]={1,2,3};
int n=sizeof(ar)/sizeof(ar[0]);
Perm(ar,0,n-1);
}

实验结果:

2、整数划分问题:将正整数n表示成一系列正整数之和,正整数n的这种表示称为正整数n的划分。求正整数n的不同划分的个数。例如:正整数6有11中不同的划分。

(1)设计思想:

在正整数n的所有划分中,将最大加数n₁不大于m的划分个数记作q(nm)。可以建立q(n,m)的如下递归关系:

q(n,m)={1   q(n,n)   1+q(n,n−1)   q(n,m−1)+q(n-m,m)}

 n=1,m=1     n< m    n=m   n>m>1

据此,可设计计算q(n,m)的递归函数如下。正整数n的划分数p(n)=q(n,n)。

#include<iostream>

using namespace std;

int main()

{

int a,b,c;

int q(int n,int m);

cout<<"请输入整数及大于最大加数的数"<<endl;

cin>>a>>b;

c=q(a,b);

cout<<"所需要的划分数:"<<c<<endl;

return 0;

}

int q(int n,int m)

{

if((n<1)||(m<1)) return 0;

if((n==1)||(m==1)) return 1;

if(n<m) return q(n,n);

if(n==m) return q(n,m-1)+1;

return q(n,m-1)+q(n-m,m);

}

实验结果

3、二分搜索技术:设a[0:n-1]是一个已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置I和大于x的最大元素位置j。当搜索元素在数组中时,I和j相同,均为x在数组中的位置。

(1)设计思想:

时间完成搜索任务。二分搜索算法的基本思想是,将n个元素分成个数大致相同的两半,取a[n/2]与x作比较。如果x=a[n/2],则找到x,算法终止;如果x<a[n/2],则只在数组a的左半部继续搜索x;如果x>a[n/2],则只在数组a的右半部继续搜索x。

(2)程序代码:

#include<iostream>
using namespace std;
int main()
{
int const length=100;
int n,x;
int a[length];
cout<<"依次输入数组的长度,数组内容、要查找的数"<<endl;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
cin>>x;
void BinarySearch(int a[],int n,int x);
BinarySearch(a,n,x);
return 0;
}
void BinarySearch(int a[],int n,int x)
{
int i,j,mid=0,left=0;
int right=n-1;
while(left<right+1&&left>=0)
{
int mid=(left+right)/2;
if(x==a[mid])
{
i=j=mid;
break;
}
if(x>a[mid])
left=mid+1;
else
right=mid-1;
}
if((i=j)&&(i>=0))
cout<<"所找数据在数组中下标为:"<<i<<endl;
else
cout<<"所找数据不在数组中";
}

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值