算法之路——概论习题总结

1.算法是就求解问题的一系列计算步骤。算法具有 有限性,确定性,可行性,输入性,输出性5个重要特征。
2.判断一个大于2的正整数n是否为素数的方法有多种,给出两种算法,说明其中一种算法更好的理由。
两种算法如下:

#include
#include
using namespace std;
bool isPrime1(int n)//方法1 ,时间复杂度O(n) 
{
	for(int i=2;i<n;i++)
	if(n%i==0)
	return false;
	return true;
}
bool isPrime2(int n)//方法2 ,时间复杂度O(根号n) 
{
	for(int i=2;i<=(int)sqrt(n);i++)
	if(n%i==0)
	return false;
	return true;
}
int main()
{
	int n=5;
cout<<isPrime1(n)<<isPrime2(n);
}

3.有一个含n(n>2)个整数的数组a,判断其中是否存在出现次数超过所有元素一半的元素。
解:先将a中的元素递增排序,再求出现次数最多的次数maxnum,最后判断是否满足条件。程序如下:

#include
#include
using namespace std;
bool solve(int a[], int n, int &x)
{
	sort(a, a + n);//递增排序
	int maxnum = 0;//出现次数最多的次数
	int num = 1;
	int e = a[0];
	for (int i = 1; i < n; i++){
		if (a[i] == e){
			num++;
			if (num > maxnum){
				maxnum = num;
				x = e;
			}
		}
		else{
			e = a[i];
			num = 1;
		}
	}
if (maxnum > n / 2)
return true;
else
return false;
}
void main(){
	int a[] = { 2, 2, 2, 4, 5, 6, 2 };
	int n = sizeof(a) / sizeof(a[0]);//数组长度
	int x;
	if (solve(a, n, x))
		printf("出现次数超过所有元素一半的元素为%d\n", x);//printf比cout的运行快,时间问题的话这样处理可能会好。
	else
		printf("不存在出现次数超过所有元素一半的元素\n");
}

4.一个字符串采用string对象存储,设计一个算法判断该字符串是否为回文。
解:采用前后字符判断方法。

#include
#include
using namespace std;
bool solve(string str)//判断字符串是否为回文
{
	int i = 0,j = str.length() - 1;
	while (i < j)
	{
		if (str[i] != str[j])
			return false;
		i++;
		j--;
	}
	return true;
}
int  main(){
	cout << "求解结果" << endl;
	string str = "abcd";
	cout << " " << str << (solve(str) ? "是回文":"不是回文") << endl;
	string str1 = "abba";
	cout << " " << str1 << (solve(str1) ? "是回文" : "不是回文") << endl;
}

5.有一个整数系列,设计一个算法判断其中是否存在两个元素的和恰好等于给定的整数K。
题解:先将 a中的元素按递增排序,然后从两端开始进行判断。
对应的而程序如下。
代码1:

#include
#include
using namespace std;
bool solve(int a[], int n, int k,int j,int s)
{
	sort(a, a + n);
	while (s< j){
		if (a[s] + a[j] == k)
			return true;
		else if (a[s] + a[j]< k)
			s++;
		else
			j--;
	}
	return false;
}
int main(){
	int a[] = { 1, 2, 4, 5, 3 };
	int n = sizeof(a) / sizeof(a[0]);
	printf("求解结果\n");
	int k = 9, s=0, j=n-1;
	if (solve(a, n, k, s, j))
		printf("存在:%d+%d=%d\n", a[s], a[j], k);
	else
		printf("不存在两个元素和为%d\n", k);
	int k1 = 10;
	if (solve(a, n, k1, s, j))
		printf("存在:%d+%d=%d\n", a[s], a[j], k1);
	else
		printf("不存在两个元素和为%d\n", k1);
}            

代码2:

#include
#include
using namespace std;
bool solve(int a[], int n, int k,int j,int s)
{
	
	while (s< j){
		if (a[s] + a[j] == k)
			return true;
		else if (a[s] + a[j]< k)
			s++;
		else
			j--;
	}
	return false;
}
int main(){
	
	int a[] = { 1, 2, 4, 5, 3 };
	int n = sizeof(a) / sizeof(a[0]);
	sort(a, a + n);
	printf("求解结果\n");
	int k = 9, s=0, j=n-1;
	if (solve(a, n, k, s, j))
		printf("存在:%d+%d=%d\n", a[s], a[j], k);
	else
		printf("存在两个元素和为%d\n", k);
	int k1 = 10;
	if (solve(a, n, k1, s, j))
		printf("存在:%d+%d=%d\n", a[s], a[j], k1);
	else
		printf("不存在两个元素和为%d\n", k1);
	system("pause");
}

6.有两个整数序列,每个整数序列中的所有元素均不相同,设计一个算法求他们的共同元素,要求不使用STL中的集合算法。
解:采用集合set存储整数序列,集合中的元素默认是递增排序的,再采用二路归并算法求他们的交集。 程序如下:

#include
#include
using namespace std;
void solve(set<int>s1,set<int>s2,set<int>&s3)//求交集s3
{
	set<int>::iterator it1,it2;
	it1=s1.begin();it2=s2.begin();
	while(it1!=s1.end()&&it2!=s2.end()){
	if(*it1==*it2){
	s3.insert(*it1);
	++it1;
	++it2;
	}
	else if(*it1<*it2)
	++it1;
	else
	++it2;
	}
}
void dispset(set<int>s)//输出集合中的元素
{
set<int>::iterator it;
for(it=s.begin();it!=s.end();++it)
printf("%d",*it);
printf("\n");
}
void main(){
int a[]={3,2,4,8};
int n=sizeof(a)/sizeof(a[0]);
set<int>s1(a,a+n);
int b[]={1,2,4,5,3};
int m=sizeof(b)/sizeof(b[0]);
set<int>s2(b,b+m);
ste<int>s3;
solve(s1,s2,s3);
printf("求解结果\n");
printf("s1:");dispset(s1);
printf("s2:");dispset(s2);
printf("s3:");dispset(s3);
}

你可能感兴趣的:(Algorithm,总结)