前言
有时候,我们需要对数组进行排序,而在算法中,由于对效率的追求,选择排序和冒泡排序已经无法满足我们的需求。这时,我们就需要使用效率更高的快排。

程序设计思路
在快速排序中,我们需要两个指针,分别是左指针和右指针,即left和right。他们从数组两端出发,相向而行。之后找到中点,作为基准数,比基准数大的和小的各自到一边(为讲解方便,这里讲升序)。当左右指针相遇时,我们已经将所有的数分为两组。之后,我们再次进行相同操作,直到将所有的数分组不断细化,最后每个数一组。
这样一来,我们不难想到递归。即当主程序结束后,我们对两组数再次调用主程序本身,之后再次调用。
这种方法的时间复杂度是O(n log n)。

代码实现

void qsort(long long a[],long long left,long long right){三个参数分别为数组名、左右端点
    long long i,j,t;//i、j分别存放左右端点
    if(left>=right) return;//特判,用于最后退出程序
    int x=(left+right)/2;//取中点
    swap(a[x],a[left]);//防止重复
    t=a[left];//基准数
    i=left;
    j=right;
    while(i<j){
        while(a[j]>=t && i<j) j--;//j不断向左,直到发现小数
        while(a[i]<=t && i<j) i++;//i不断向右,直到发现大数
        if(i<j) swap(a[i],a[j]);//如果i比j小,交换
        else break;
    }
    swap(a[left],a[i]);//调换回来
    
    //再次调用
    if(left<i) qsort(a,left,i-1);
    if(right>i) qsort(a,j+1,right);
}

sort( , , )函数使用
在C++的STL库中,有一个sort函数,可以省去我们自写快排的烦恼。
sort( , , )函数的第一个参数是数组头地址,第二个参数是数组尾地址。第三个是cmp函数名称。下面是对数组x[ ]进行排序的代码:

int k=sizeof(x)/sizeof(x[0];//获取数组长度
sort(x,x+k,);//在默认升序序情况下,无需编写cmp()函数

当我们需要对数组进行降序排序时,就需要自写cmp函数,像这样:

bool cmp(int a,int b){//int为数组数据类型
    return a>b;
}
int k=sizeof(x)/sizeof(x[0];//获取数组长度
sort(x,x+k,cmp);

sort还可以进行结构体排序,像下面这样:

bool cmp(class a,class b){
    return a.num<b.num;//降序,如需升序请将>改为<;此处对结构体中的元素num进行排序
}

sort函数的时间复杂度为O(n log n)。

结语
快排极大的提高了效率,使得程序运行速度更快,节省了时间。我是faryou,下次见!

前言
通常情况下,我们在使用程序进行幂运算时,会利用循环乘法或pow( , )解决。但对于数据非常大的情况,这样做非常影响效率,很容易导致超时。因此,快速幂应运而生。

程序设计思路
快速幂基于二进制进行。通常情况下,我们会将其封装为一个函数binpow( , )。下面举个例子说明其原理:
我们要计算3的13次方,常规做法是:用for循环使一个变量从1开始每次乘3,这里数据小,没有问题,但如果是3100000000呢(不考虑数据溢出)?这样算肯定不对。
快速幂就很好的解决了这个问题,我们可以将3的13次方分解为:
3的13次方 = 3的8次方 3的4次方 3
这样一来,我们只需要计算3的2n次方即可,即每次进行平方运算。节省了大量时间。

代码实现

int quick(int a,int b){//计算a^b
    int res = 1;//从1乘起
    while(b>0){
        if(b&1) res=res*a;//当a(二进制)的这一位是1时,乘a
        a=a*a;//计算a^2
        b>>=1;//答案的一位(二进制)解决
    }
    return res;
}

结语
快速幂在很大程度上提升了效率,使得程序速度更快。我是faryou,再见!

前言
在学习计算机的过程中,我们会碰到不同的进制,如二进制、十六进制等。而这些进制之间的转换,又成为了一个问题。现在,我们来学习写一个程序,实现二~十六进制之间的进制转换。

程序设计思路
一般情况下,要解决一个算法问题,首先要在数学上解决它。进制就代表着满几进一。因此,我们在进制转换时,只需要不断地除以进制数,并将余数连起来,就是新的数了。在进制转换时,通尝使用短除法。如将256转换为十六进制数:

16 l 2 5 6
16 l 1 6············0
16 l 1············0
0············1

故256=0x100。
在真正的写程序的时候,由于十六进制中的10~15用字母A~F表示,因此我们不能直接用int相加,而应该用字符串存数据。

代码实现
以下为题目要求及代码:
202407051720140869844401.png

#include <bits/stdc++.h>
using namespace std;
int n,m,ten;//n、m为题目中原义,ten为被转换的数的十进制
char a[15],ans[15];//a存输入,ans存输出
int n_ten(int n){//n进制→十进制
  int answer=0;//answer为结果
  for(int i=0;a[i]!='\0';i++){//数学方式:十进制数=n进制数的第i位数*n^(i-1)
    if(a[i]>='0' && a[i]<='9') answer=answer*n+a[i]-48;
    if(a[i]>='A' && a[i]<='F') answer=answer*n+a[i]-55;
  }
  return answer;
}
void ten_m(int a,int m){//十进制→m进制,即上面的短除法
  int b=0,i=a;//b为计次,i为十进制数
  while(i>0){//在i除完之前循环
    if(i%m<=9) ans[b]=i%m+48;
    if(i%m>=10) ans[b]=i%m+55;
    i = (i-i%m)/m;
    b++;
  }
  return ;
}
//以上两个函数都使用了ASCLL码相关知识,请自行查表
int main(){
  scanf("%d%s%d",&n,a,&m);
  ten=n_ten(n);
  if(m!=10){
    ten_m(ten,m);
    int n=strlen(ans);//获取长度
    for(int i=n-1;i>=0;i--) printf("%c",ans[i]);
  }
  else printf("%d",ten);
  return 0;
}

结语
进制转换最主要是在数学上理解这个方法,之后就是对照数学方式写程序了。我是faryou,再见!

前言
近期我开始学习信奥了,主要编程语言就是C++。在做学校的题目的时候发现有一道题很难直接解决。参考了做出来的两名同学的做法,发现一个人是利用数组解决(那代码我都不敢看,一堆for循环也没出啥好办法来……),另一个人则是一个数据用一段代码处理,也是屎山代码……后来按照题意找到方向后,便利用自定义函数减少了许多烦琐的步骤。下面为大家介绍一下C++中自定义函数的理解与使用——

函数
要想使用自定义函数,首先就要理解C++中的函数是什么。
简单来说,函数就是一条可以帮助你完成某个特定任务,并返回一个结果值的命令。打个比方:int a;,这条命令就可以帮你完成定义一个名为a的整型变量这一个任务;再比如说if 0这一条命令,就可以判断0的布尔值,并返回一个false。
函数中有一个很重要的组成部分——参数。比如printf("Hello World!");这条代码中,"Hello World!"就是一个参数。函数通过给定的参数进行计算。参数虽然重要,但并不是必要的。
函数中还有一个必要的部分,就是返回值。C++函数中,main()函数的return 0;就是返回一个0的意思。

自定义函数的创建与调用
自定义函数与main()函数类似,下面来看看自定义函数的定义:
首先,是以函数返回值类型+函数名,例如int a(){}就定义了一个返回值为整型,名称为a的函数。
下面介绍参数设置,只需要在函数名后面的括号里用参数数据类型+参数名的格式列出即可,多个函数之间用逗号隔开,注意不要与用户名重复。
在函数的最后,不要忘记返回值,这十分重要,同时注意返回值数据类型要和开头定义的保持一致。
调用函数的时候,只需要以 函数名(参数1,参数2...); 的格式调用即可。

自定义函数的实际应用
上面说了那么多,如果不会应用,那么都是白搭。下面faryou我给大家展示一道学校的题目,以及我的答案——
202401031704291455662705.png
先放个答案,再分析——

#include <cstdio>
using namespace std;
int a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,m=0,n=0;
int pd(int a){//声明自定义函数
  if(a>0) m++;//正数
  if(a<0) n++;//负数
  return 0;
}
int main(){
 
 scanf("%d%d%d%d%d%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10);
  pd(a1);
  pd(a2);
  pd(a3);
  pd(a4);
  pd(a5);
  pd(a6);
  pd(a7);
  pd(a8);
  pd(a9);
  pd(a10);
  printf("positive:%d\nnegative:%d",m,n);
  return 0;
}

这里先声明一下,本人对for循环和数组的使用还不熟悉,所以没有进一步简化~~
可以看到,我在这里使用了一个名为pd的自定义函数,且设置了一个名为a的整型变量,函数中进行了一次二分支的判断,之后的main函数中,我把10个待求数一一通过自定义函数判断正负。程序整体利用了2个计次变量,m和n。

总结
本文先介绍了函数,之后说了自定义函数的基本使用方法,最后为大家举了一个例子。希望大家对此能够有自己的理解,并加以运用到更为复杂的情景当中去。
第一次写C++的文章,有问题请不吝赐教~~
我是faryou,下次见('▽')♪

前言
虚拟主机是一个搭建好环境的网站空间,不支持ssh自定义环境,比较适合不折腾专心做内容的个人或中小型企业使用。像本博客就是使用PHP虚拟主机+Z-Blog PHP搭建。现在市面上常见的虚拟主机多为php语言,少部分为ASP。今天我带大家熟悉一下虚拟主机的基本操作,帮助大家顺利建站~

主机选择
虚拟主机和服务器一样,尽量选择大厂如腾讯、阿里等,这里不过多赘述了~

面板使用
和服务器有宝塔面板、1Panel面板一样,虚拟主机也有自己的面板。一般来说,国内主机使用EasyPanel,国外主机使用vistapanel的多。这里以EasyPanel做演示:
打开EasyPanel面板,首先可以看到虚拟主机的MySQL和FTP信息,建议先修改密码,更安全~
然后打开域名绑定,在DNS服务商处按要求添加相应的CNAME记录。打开在线文件,上传自己的网站程序,PHP一般用WordPress、Z-Blog或Emlog做博客或企业官网,Discuz或Xiuno做论坛。
访问自己的域名,按要求填写MySQL信息即可。

数据库管理
一般的虚拟主机服务商用PHPMyAdmin做数据库管理(包括国内外)。因此,此处使用PHPMyAdmin做演示:
如果专心做网站,其实数据库是不需要管理的。所以,数据库只在需要修改一些特殊数据或做调试时使用。
打开PHPMyAdmin,可以看到左侧是数据树状图,右侧是各种操作按钮。因为是图形化界面,所以我不过多赘述了,大家可以先学习一下SQL知识,之后再使用PHPMyAdmin。

总结
虚拟主机还是很推荐大家去用一用的,特别是有PHP/SQL数据库学习需求或专心做网站的人。好了,今天就到这里,下次见~