C++程序性能2
//C++程序性能2
//ProgramPerformance2.h
//查找最大和最小值函数
template<class T>
bool MinMax(T a[],int n,int& Min,int& Max)
{ //寻找a[0:n-1]中的最小元素和最大元素
//如果数组中的元素数目小于1,则返回false
if(n<1) return false;
Min=Max=0;//初始化
for(int i=1;i<n;i++)
{
if(a[Min]>a[i]) Min=i;
if(a[Max]<a[i]) Max=i;
}
return true;
}
//另一个查找最大和最小值函数
template<class T>
bool MinMax_other(T a[],int n,int& Min,int& Max)
{ //寻找a[0:n-1]中的最小元素和最大元素
//如果数组中的元素数目小于1,则返回false
if(n<1) return false;
Min=Max=0;//初始化
for(int i=1;i<n;i++)
{
if(a[Min]>a[i]) Min=i;
else if(a[Max]<a[i]) Max=i;
}
return true;
}
/*
之所以要确定程序的操作计数和执行步数有两个重要的原因:
1)为了比较两个完成同一功能的程序的时间复杂性;
2)为了预测随着实例特征的变化,程序运行时间的变化量。
-----
利用新符号可以写出关于程序时间和空间复杂性的具体公式(尽管不够精确)。
这种符号被称为渐进符号(asymptotic notation),
它可以描述大型实例特征下时间或空间复杂性的具体表现。
在下面的讨论中f (n) 表示一个程序的时
间或空间复杂性,它是实例特征n的函数。
由于一个程序的时间和空间需求是一个非负值,
所以可以假定对于n的所有取值,函数f的值非负。
由于n表示一个实例特征,所以可以进一步假定n≥0。
即将讨论的渐进符号允许我们对于足够大的n值,
给出f的上限值和/或下限值
-----
大写O 符号给出了函数f的一个上限。
定义[大写O符号] f (n)=O (g (n)) 当且仅当存在正的常数c 和n0,使得对于所有的n≥n0 , 有
f (n) ≤c g(n)。 //上限函数g(n)
----
常用的渐进函数
1 常数
logn 对数
n 线性
nlogn n个logn
n^2 平方
n^3 立方
2^n 指数
n! 阶乘
----
f(n)=3n+2 f(n)=O(n)
f(n)=10n^2+4n+2 f(n)=O(n^2)
f(n)=6*2^n+n^2 f(n)=O(2^n) 因为有n^2<=2^n
f(n)=9;f(n)=2033 f(n)=O(1)
----
定义: 如果f(n)=am*n^m+...+a1*n+a0且am>0,则f(n)=O(n^m)
----
Ω符号与大O 符号类似,它用来估算函数f 的下限值
----
Θ符号适用于同一个函数g 既可以作为f 的上限也可以作为f 的下限的情形。
----
定义[小写o] f (n)=o (g (n) )当且仅当f (n) = O (g (n) )且f (n)≠W (g (n) )
----
3n+2=o(n^2)
10n^2+4n+2=o(n^3);
----
*/
//折半搜索函数
template<class T>
int BinarySearch(T a[],const T& x,int n)
{ //在a[0]<=a[1]<=...<=a[n-1]中搜索x
//如果找到,则返回所在位置,否则返回-1
int left=0;int right=n-1;
while(left<=right)
{
int middle=(left+right)/2;
if(x==a[middle]) return middle;
if(x>a[middle]) left=middle+1;
else right=middle-1;
}
return -1;//未找到x
}
/*
性能测量(performance measurement)主要关注于得到一个程序实际需要的空间和时间。
----
基于以下原因,我们不能精确地测量一个程序运行时所需要的时间和空间:
1)指令空间和数据空间的大小是由编译器在编译时确定的,所以不必测量这些数据。
2)采用前几节介绍的方法,可以很准确地估算递归栈空间和变量动态分配所需要的空间。
----
选择实例的大小
可以根据以下两个因素来确定使用哪些n 值:程序执行的时间及执行的次数
在实践过程中,通常需要3个以上的n 值,其原因如下:
1) 渐进分析仅给出了对于足够大的n 值时程序的复杂性。对于小的n 值,程序的运行时间
可能并不满足渐进曲线。为了确定渐进曲线以外的点,需要使用多个n 值。
2) 即使在满足渐进曲线的区间内,程序实际运行时间也可能不满足预定的渐进曲线,原因
是在进行渐进分析时,忽略了许多低层次的时间需求。
----
设计测试数据
对于许多程序,可以手工或用计算机来产生能导致最好和最坏复杂性的测试数据。
然而,对于平均的复杂性,通常很难设计相应的数据
当不能给出能产生预期的复杂性的测试数据时,可以根据一些随机产生的测试数据所测量
出的最小(最大,平均)时间来估计程序的最坏(最好,平均)复杂性
----
进行实验
在确定了实例的大小并给出了测试数据以后,就可以编写程序来测量所期望的运行时间了
----
*/
// Win32Console.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "baseCplusplus1.h";
#include "baseClassRelInfo2.h";
#include "TestProgram.h"
#include "ProgramPerformance.h"
#include "ProgramPerformance2.h";
void baseCplusplusOp(); //C++函数模板递归一二维数组动态分配存储空间实例1
void baseClassRelInfo2(); //C++类的相关基础2
void baseClassRelInfo2_1(); //C++类的相关基础2 //操作符重载
void ComputeRoots(); //计算根公式
void findMax(); //寻找最大值
void ProgramPerformance(); //程序性能1
void ProgramPerformance2(); //程序性能2
int _tmain(int argc, _TCHAR* argv[])
{
baseCplusplusOp();
baseClassRelInfo2();
std::cout<<"/操作符重载"<<std::endl;
baseClassRelInfo2_1();
std::cout<<"计算根公式"<<std::endl;
ComputeRoots();
std::cout<<"寻找最大值"<<std::endl;
findMax();
std::cout<<"程序性能"<<std::endl;
ProgramPerformance();
std::cout<<"程序性能2"<<std::endl;
ProgramPerformance2();
//暂停操作
char str;
std::cin>>str;
//程序结束
return 0;
}
//程序性能2
void ProgramPerformance2()
{
int a[11]={1,5,2,6,9,11,18,20,25,7,30};
int n=11;
int x=7;
for(int i=0;i<n;i++) std::cout<<a[i]<<" ";
std::cout<<std::endl;
BubbleSort_intimestop(a,n); //排序
std::cout<<"折半搜索"<<std::endl;
int pos=BinarySearch(a,x,n);
std::cout<<x<<" pos="<<pos<<std::endl;
for(int i=0;i<n;i++) std::cout<<a[i]<<" ";
std::cout<<std::endl;
}