素数判断
什么是素数?——素数一般指质数。质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
如果我们想写一个素数,必定要用一个循环来进行检验,设有检验数n,那就要用i[1,n]来与其进行计算,但由于除了1和n本身,其他数都不行,所以i的范围应该是[2,n-1]
int main()
{
int n;
scanf("%d",&n);
for(int i=2;i<n;i++)
{
if(n%i==0)//就说明能被1和n本身以外的数整除,就说明不是素数
{
printf("%d是素数",n);
}
}
return 0;
}
现在,我们来查找100-200之间的素数
int main()
{
int i = 0;
int count=0;
for (i = 100; i <= 200; i++)
{
//判断i是否为素数
for(int j=2;j<i;j++)
{
if(i%j==0)
{
printf("%d是素数\n",i);
}
}
}
printf("%d", count);
return 0;
}
如果想封装成函数怎么弄?——最好能进行一个返回值的利用,返回1就是素数,0就不是素数
然后将返回值拿到主函数里用条件语句进行判断
且有一个可以减少运行时间的方法——若一个数n为100,那么用检验数(100开方-10)便可以检验出来,故用sqrt开方来减少计算量
//判断是不是素数
int is_prime(int i)//本质上代替了flag的作用
{
int j = 0;
for (j = 2; j <= sqrt(i); j++)
{
if (i % j == 0)
{
return 0;
}
}
return 1;
}
int main()
{
int i = 0;
int count=0;
for (i = 100; i <= 200; i++)
{
//判断i是否为素数
if (1 == is_prime(i))
{
printf("%d", i);
count++;
}
}
printf("%d", count);
return 0;
}
冒泡排序
![](https://i-blog.csdnimg.cn/blog_migrate/5f02c2ba312b12f1591aa52bb782a5e4.png)
简而言之就是,排序的时候相邻两个进行比较,重复进行,一步步会将大的往后放,小的往前放,这样就会实现升序的排序
先想好比较步骤的代码——先进行比较,第j个与第j+1进行比较,若arr[j]>arr[j+1],那么就进行交换——需要一个tmp来储存数字,若arr[j]<arr[j+1]呢?
那就直接跳到下一个数字,也就是用arr[j+1]与arr[j+2]比较,这个过程需要用循环来实现'
//冒泡排序的次数
for (i = 0; i < sz - 1; i++)
{
//一趟冒泡的次数
int j = 0;
for (j = 0; j < sz-1-i; j++)//因为每次都会排出一个最小值,所以我们每排除一个,则比较的次数-1
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
在用之前,也需要知道数组的长度。
故主函数为
int main()
{
int arr[] = { 3,1,5,9,2,4,7,6,8,0 };
//排序-升序
//冒泡排序
int sz = sizeof(arr) // sizeof(arr[0]);//读取长度
bubble_sort(arr,sz);//数组长度需要在外边传入
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d", arr[i]);
}
return 0;
}
那么再将冒泡排序封装成一个函数
//冒泡排序,相邻两个进行比较
void bubble_sort(int *arr,int sz)
{
int i = 0;
//int sz = sizeof(arr) / sizeof(arr[0]);//sz必须在函数外部求的,再传入
//
// 为什么在外部传参的时候,传进去的sz是10?
// 因为传入数组名时,实则传入的是数组首元素地址,首元素地址即1个元素,故sz在里边求就是1
//冒泡排序的次数
for (i = 0; i < sz - 1; i++)
{
//一趟冒泡的次数
int j = 0;
for (j = 0; j < sz-1-i; j++)//因为每次都会排出一个最小值,所以我们每排除一个,则比较的次数-1
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
查找数字
- (逐一查找)
本质就是用for循环的遍历算法一个一个比较过去
若找到则返回相应的值(数组的下标)
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
//strlen是字符串专用
int flag = 0;
for (i = 0; i < sz; i++)
{
if (k == arr[i])
{
flag = 1;//用于标记是否能找到
printf("找到了,下标是:%d", i);
break;
}
}
if (flag == 0)
{
printf("找不到\n");
}
return 0;
}
但是这样子的查找会比较久,而且每个都要过一遍会使代码运行比较久
那有什么更方便的方法呢?
2.二分查找
二分查找的定义:
![](https://i-blog.csdnimg.cn/blog_migrate/578d89d3155b29c2f4a14c057289a7e5.png)
简而言之,就是定义左右的数字,然后找到中间数,接着再次缩小范围找中间数
可以类比为,猜数字的方法
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;//元素个数减去1就是最后一个元素对应的数组下标
int flag = 0;//作为是否找到的标记
while (left<=right)
{
//1.int mid = (left + right) / 2;//若这两个数太大,则会越界,导致一些数的丢失
int mid = left + (right - left) / 2;//使两侧补齐,得到平均数
if (arr[mid] < k)
{
left = mid + 1;//数字为小于要查找的数字时,说明要查找的数字在右边,故加1
}
else if (arr[mid] > k)//数字为大于要查找的数字时,说明要查找的数字在左边,故减1
{
right = mid - 1;
}
else
{
printf("找到了,下标是:%d\n", mid);
flag = 1;
break;
}
}
if (flag == 0)
{
printf("没找到");
}
return 0;
}
举一个例子
![](https://i-blog.csdnimg.cn/blog_migrate/4855ae057fac82c7aa043354cd06d5ac.jpeg)
递归
什么是递归?
![](https://i-blog.csdnimg.cn/blog_migrate/bfade815d84b46a5c9bac3f36c8cda53.png)
递归的条件
存在限制条件,当满足这个限制条件的时候,递归便不再继续。
每次递归调用之后越来越接近这个限制条件。
阶乘
非递归,用简单的循环
int fac(int n)
{
int i = 0;
int ret = 1;
for (i = 1; i <= n; i++)//一个一个乘过去
{
ret = ret * i;
}
return ret;
}
用递归,当要求的数>=1的时候就进入下一个递归
int fac(int n)
{
if (n <= 1)
{
return 1;
}
else return n * fac(n - 1);
}
int main()
{
int x;
scanf("%d", &x);
int ret=fac(x);
printf("%d", ret);
return 0;
}
递归的运用,需要萌新们多次的推算,多次画出流程图,才能很好地使用
斐波那契数列
斐波那契数列:
![](https://i-blog.csdnimg.cn/blog_migrate/660c9442d8d5cb7c2a1df5da0d3a531a.png)
int Fib(int n)
{
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
但是,这样子会使代码量及其巨大,在到一定数后,就会超出栈区
因此可以改为:(非递归)
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n>=3)
{
c = a + b;
a = b;
b = c;
n--;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/adee328510840899590f59a9cae58960.jpeg)
因此,递归和循环需要按照实际情况来判断,按照最简单的方式来求