目录
求1~n的连续整数和
1、目的:通过对比同一问题不同解法的绝对执行时间,体会不同算法的优劣。
2、要求:编写一个程序expl-1.cpp,其中add1(逐个累加)和add2(高斯法)函数采用两种解法计算1+2+…+n,AddTimel和AddTime2分别调用它们求1+2+.+n,并统计求解时间。
3、代码:
#include <stdio.h> //标准输入、输出,头文件
#include <time.h>
#include <math.h> //include<math.h>是用来引入数学函数库的头文件。这个头文件包含了许多数学函数的声明,如三角函数、指数函数、对数函数、幂函数等等。
//求1+2+3+…+n
//方法一:累加
long add1(long n) //1+2+…+n累加算法实现程序
{
long i,sum=0;
for(i=1;i<=n;i++)
sum+=i;
return sum;
}
void AddTime1(long n) //统计累加消耗时常
{
clock_t t; //clock_t是一个长整形数,clock_t计时所表示的是占用CPU的时钟单元,相当于声明了一个时间变量
long sum;
t=clock(); //记录程序从启动到函数调用占用CPU的时间
sum=add1(n); //调用add1函数
t=clock()-t; //计算程序启动到运算add1结束的时间,减去初始时间
printf("方法1:\n");
printf("结果:1~%d之和:%ld\n",n,sum);
printf("用时:%lf秒\n",((float)t)/CLOCKS_PER_SEC); //在time.h文件中,定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元
}
//方法2: 高斯算法
long add2(long n) //高斯算法实现程序
{
return n*(n+1)/2;
}
void AddTime2(long n) //统计高斯算法消耗时长,具体分析同上
{
clock_t t;
long sum;
t=clock();
sum=add2(n);
t=clock()-t;
printf("方法2:\n");
printf("结果:1~%d之和:%d\n",n,sum);
printf("用时:%lf秒\n",((float)t)/CLOCKS_PER_SEC);
}
int main()
{
int n;
printf("n(大于1000000):");
scanf("%d",&n);
if(n<1000000)
return 0;
AddTime1(n);
AddTime2(n);
return 1;
}
ps:补充一点关于头文件#include <time.h>的知识
time.h中的四个变量类型
1、size_t 无符号整数类型,它是 sizeof 关键字的结果。
2、clock_t clock()函数的返回值,unsigned long,clock返回的是时钟中断数,除以CLOCKS_PER_SEC(1000)就是进程运行秒数。
3、time_t 存储日历时间类型,time()函数的返回值,从1970/01/01/00:00:00开始到现在的秒数。它的本质也是一个长整形。
4、struct tm 用来保存时间和日期的结构。注意中国时区为UTC-8,手动转换为北京时间时要加8h,用localtime函数计算本地时间会自动转换,不需要加8小时。
实现顺序表各种基本运算的算法
1、目的:领会顺序表存储结构和掌握顺序表中各种基本运算算法设计。
2、要求:编写一个程序sqlist.cpp,实现顺序表的各种基本运算和整体建表算法(假设顺序表的元素类型ElemType为char),并在此基础上设计一个主程序,完成相应的功能。
3、代码:
#include<stdio.h>
#include<malloc.h> //内存动态分配和释放
#define MaxSize 50 //定义MaxSize常量,值为50
typedef char ElemType; //定义一种新的类型名称ElemType,该类型名同char效果一样
typedef struct //https://blog.youkuaiyun.com/weixin_44948467/article/details/114452324
{
ElemType data[MaxSize]; //存放顺序表元素
int length; //存放顺序表的长度
}SqList; //结构体名称
void Createlist(SqList *&L,ElemType a[],int n) //整体建立顺序表,且不返回值
{
L=(SqList*)malloc(sizeof(SqList)); //分配存放线性表的空间
for(int i=0;i<n;i++)
L->data[i]=a[i]; //循环将数据存入顺序表中
L->length=n; //链表长度为n
}
void InitList (SqList *&L) //初始化线性表
{
L = (SqList*)malloc(sizeof(SqList)); //分配存放线性表的空间
L->length = 0; //表长归零
}
void DestroyList(SqList *&L) //销线性表
{
free(L); //释放L表空间
}
bool ListEmpty(SqList *L) //判断线性表是否为空 ,且返回值只能为True或者False
{
return(L->length==0); //为空返回线性表为零
}
int ListLength(SqList *L) //求线性表的长度,返回值为一个整数
{
return(L->length); //返回线性表长度
}
void DispList(SqList *L) //输出线性表
{
for(int i=0;i<L->length;i++) //定义一个循环,执行将线性表元素一次输出的操作
printf("%c",L->data[i]);
printf("\n");
}
bool GetElem(SqList *L,int i,ElemType &e) //求线性表中第i个元素值,且返回值只能为True或者False
{
if(i<1||i>L->length) //i小于1或i大于L的长度,返回错误
return false;
e=L->data[i-1]; //将线性表中第i个元素的值保存在e中
return true; //返回正确
}
int LocateElem(SqList *L,ElemType e) //查找第一个值为e的元素序号
{
int i=0;
while(i<L->length && L->data[i]!=e) //i小于L表长度,且data[i]不等于e
i++; //i自增1
if(i>=L->length) //如果i大于等于L表长
return 0; //返回0
else //否则
return i+1; //返回i+1,即第一个值为e的元素序号
}
bool ListInsert(SqList *&L,int i,ElemType e) //插入第i个元素,且返回值只能为True或者False
{
int j;
if(i<1||i>L->length+1||L->length==MaxSize) //i小于1,长度超过表长或大于存储空间长度,都返回错误
return false;
i--; //将顺序表位序转化为data下标
for(j=L->length;j>i;j--) //将data[i]及后面元素后移一个位置,从最后一个位置向前移动
L->data[j]=L->data[j-1];
L->data[i]=e; //将e插入表的第i位
L->length++; //表长加1
return true;
}
bool ListDelete(SqList *&L,int i,ElemType &e)
{
int j;
if(i<1||i>L->length) //i小于1或i大于表长都不成立
return false;
i--; //将顺序表位序转化为data下标
e=L->data[i]; //将第i为元素存入e地址中
for(j=i;j<L->length-1;j++) //将data[1]之后的元素前移一个位置,从第i未开始,依次向前移一位
L->data[j]=L->data[j+1];
L->length--; //表长减1
return true;
}
//实验程序exp2-1.cpp的程序代码如下:
int main()
{
SqList *L;
ElemType e;
printf("顺序表的基本运算如下:\n");
printf("(1)初始化顺序表L\n");
InitList(L);
printf("(2)依次插入a,b,c,d,e元素\a");
ListInsert(L,1,'a');
ListInsert(L,2,'b');
ListInsert(L,3,'c');
ListInsert(L,4,'d');
ListInsert(L,5,'e');
printf("(3)输出顺序表L:");
DispList(L);
printf("(4)顺序表L的第三个元素%c\n",e);
printf("(5)顺序表L为%s\n",(ListEmpty(L)?"空":"非空"));
GetElem(L,3,e);
printf("(6)顺序表L的第三个元素%c\n",e);
printf("(7)元素a的位置:%d\n",LocateElem(L,'a'));
printf("(8)在第4个元素位置上插入f元素\n");
ListInsert(L,4,'f');
printf("(9)输出顺序表L:");
DispList(L);
printf("(10)删除L的第3个元素\n");
ListDelete(L,3,e);
printf("(11)输出顺序表L:");
DispList(L);
printf("(12)释放顺序表\n");
DestroyList(L);
return 1;
}
求素数个数
1、目的:通过对比同一问题不同解法的绝对执行时间,体会如何设计“好”的算法
2、要求:编写一个程序exep1-3.cpp,求1~n的素数个数。给出两种解法。对于相同的n,给出这两种解法的结果和求解时间,并用相关数据进行测试
3、代码:
#include <stdio.h>
#include <time.h>
#include <math.h>
//判断正整数n是否为素数
//方法一
bool prime1(long n) //判断正整数是否为素数(从2到n)
{
long i;
for(i=2;i<n;i++)
if(n%i==0)
return false;
}
void PrimeTime1(long n)
{
clock_t t; //clock_t是一个长整形数,clock_t计时所表示的是占用CPU的时钟单元,相当于声明了一个时间变量
long sum=0,i;
t=clock(); //记录程序从启动到函数调用占用CPU的时间
for(i=2;i<=n;i++) //i小于n,依次将i传入prime1(),判断i是否为素数,是素数sum个数加1
if(prime1(i))
sum++;
t=clock()-t; //计算程序启动到运算add1结束的时间,减去初始时间
printf("方法1:\n");
printf("结果:2~%d的素数个数:%d\n",n,sum);
printf("用时:%lf秒\n",((float)t)/CLOCKS_PER_SEC);
}
//方法二
bool prime2(long n) //判断正整数是否为素数(从2到n/2)
{
long i;
for(i=2;i<=(n/2);i++)
if(n%i==0)
return false;
return true;
}
void PrimeTime2(long n) //同上
{
clock_t t;
long sum=0,i;
t=clock();
for(i=2;i<=n;i++)
if(prime2(i))
sum++;
t=clock()-t;
printf("方法2:\n");
printf("结果:2~%d的素数个数:%d\n",n,sum);
printf("用时:%lf秒\n",((float)t)/CLOCKS_PER_SEC);
}
//调用主函数
int main()
{
long n;
printf("n(大于100000):");
scanf("%d",&n);
if(n<10000)
return 0;
PrimeTime1(n);
PrimeTime2(n);
return 1;
}