C/C++编程笔记

1 递归实现全排列(21/4/6)

//#include <string.h> 如果是.cpp则需要取消这行注释
#include<stdio.h>
void rankRuc(char perm[],int n,int index)  //index是字符换到字符集开始的那个字符索引,n是字符的总个数
{ 
	if(index==n)  //叶节点输出
    {  
    	printf("%2d:",k++); 
        for(int i=0;i<n;i++)  
            printf("%c",perm[i]);  
        printf("\n");  
        return ;  
    }  	
	for (int i=index;i<n;++i)  
	{ 
		swap(perm[i],perm[index]);  //将节点index的字符换到数组开头,进而将数组传入下面递归函数中
		rankRuc(perm,n,index+1);   
		swap(perm[i], perm[index]); //下个循环还需要开始的数组序列,所以要还原
	} 
} 

2 static
范围是 当前代码文件、函数、子函数;
static类似类中的static,可以在同一程序多次调用时,同一范围内的声明 不重置;
static变量只在范围内以及子范围有效,范围内申明的static变量不受上级static的变量影响;
static函数通常作用域是文件,使用范围不能超过当前文件,也就是其他文件方法只能调用extern,是因为默认是static函数;

#include<stdio.h>
#include<string.h>
static int x=111; //文件范围内声明的

void fun()
{
    int i=0;
    printf("%d ",x);
    x++;  //使用了外部static变量x,main函数申明的x,忽略了文件外声明的x
    static int x=12; //两次调用,只有一次有效
    printf("i=%d\n",i);
    printf("x=%d\n",x);
    i++;
    x++;
}

int main()
{
  fun(); //第一次调用
  static int x=56; //main函数声明的static x
  fun(); //第二次调用
  printf("%d ",x);
  return 0;
}

在这里插入图片描述

3 宏交换

#include<stdio.h>
#define exchange(a,b) { int t;t=a;a=b;b=t;}//注意放在一行里
int main()
{
    int x=10;
    int y=20;
    printf("x=%d; y=%d\n",x,y);
    exchange(x,y);
    printf("x=%d; y=%d\n",x,y);
    return 0;
}

4 ~(~0<<4)=15
~表示取反,0在二进制表示为 00000000;
~0表示11111111,在最高位为符号位,符号寄存器标记为1,表示负数;
~0<<4表示11110000,符号寄存器标记为1,10进制表示-16;
~(~0<<4)=00001111=15

5 杨辉三角
在这里插入图片描述

#include<stdio.h>

int main(void)
{	
	int fs[10]={1};
	int last[10]={1};
	printf("%d\n",1);
    for(int i=1;i<10;i++)
    {
		for(int m=1;m<=i;m++){
			if(m==i){
				last[m]=1;
				break;
			}
			last[m]=fs[m-1]+fs[m];	
		}
		
		for(int j=0;j<i+1;j++){
			fs[j]=last[j];
			printf("%d ",last[j]);
		}

		printf("\n");
    }
    return 0;
}

6 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位

#include<stdio.h>

int main()
{
	int n=8;
	int u[n];
 	
	for(int i=0;i<n;i++){
		u[i]=i+1;
	}
	
	int c=0; //数组循环 
	int r=0; //每三个循环 
	int rc=0; //删除数量 
	while(rc<n-1){


		if(u[c]!=0){
			r++;
			if(r%3==0){
				u[c]=0;
				rc++;
				r=0;
			
			}
		}
		
		c++;
		if(c==n){
			c=0;
		}
	}
	
	for(int e=0;e<n;e++){
		if(u[e]!=0){
			printf("%d",u[e]);
		}
	}
	
    return 0;
}

7 typedef重命名 指针名

typedef ListNode * ListNodePtr;    // 这个不叫把 ListNode 重命名,而是定义了一个新的类型 

typedef  struct file { 
... 
}FileInfo ,  *FileP ;
//FileInfo 是struct file的别名//FileP 是struct file* 别名

8 海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只 猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了 一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的, 问海滩上原来最少有多少个桃子?

#include<stdio.h>

int main()
{
    int x,i=0,j=1;
    while(i<5){  //这里处理的特别巧妙
        x=4*j;
        for(i=0;i<5;i++)
        {
            if(x%4!=0){break;} //这句和下句互换顺序是有区别的,对最终的i值是有影响,
            x=(x/4)*5+1;    	//break在上句,最终的i值多执行一次,在下句的话相对少执行一次,影响while的条件
        }
        j++;
    }
    printf("%d\n",x);
    return 0;
}

9 返回值是void指针,void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者其他数据类型),可以通过类型强制转化转化为其他任意类型指针。如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。

10 C++引用&(21/01/11)
参考:https://www.cnblogs.com/duwenxing/p/7421100.html
&有两个作用,放在等号(=)右边表示取变量地址,放在等号(=)左边表示 声明引用名(别名,同一个内存地址内容的变量别名)
函数参数的引用是,等号左边的引用&;
函数返回值的引用也是等号左边的引用,返回变量为避免临时变量的产生。

11 pthread线程(用.c文件,不能是.cpp)

#include <stdio.h>
#include <pthread.h>

#define Num 4
pthread_mutex_t mutex;
pthread_cond_t cond;
int n=0;
void * p_func(void* t)
{
	int p=(int)t;
	pthread_mutex_lock(&mutex);
	while(p!=n){
		pthread_cond_wait(&cond,&mutex);
	}
	printf("%d ",p+1);
	n=(n+1)%Num;
	pthread_mutex_unlock(&mutex); 
	pthread_cond_broadcast(&cond);
}

int main()
{
	pthread_t tid[Num];
	pthread_mutex_init(&mutex,NULL);
	pthread_cond_init(&cond,NULL);
	int m;
	for(m=0;m<Num;m++){
		pthread_create(&tid[m],NULL,p_func,(void *)m);
	}
	for(m=0;m<Num;m++){
		pthread_join(tid[m],NULL);
	} 
	printf("\n");
	return 0;
}

12 归并排序(递归)

#include <stdio.h>

void sor(int arr[],int seg[],int start,int end){ //0开始,start和end是具体位置,不是长度

	int k=start;
	if(start==end){
		seg[k]=arr[k];
		return;
	}
	
	int len=end-start,mid=(len>>1)+start;
	int start1=start,end1=mid;
	int start2=mid+1,end2=end;
	sor(arr,seg,start1,end1);
	sor(arr,seg,start2,end2);

	while(start1<=end1&&start2<=end2)
		seg[k++]=arr[start1]<arr[start2]?arr[start1++]:arr[start2++];
	
	while(start1<=end1)
		seg[k++]=arr[start1++];
	
	while(start2<=end2)
		seg[k++]=arr[start2++];
	
	for(k=start;k<end+1;k++)
		arr[k]=seg[k]; 
	
}

void merge_sort(int arr[],int len) {
	int b[len];
	sor(arr,b,0,len-1);
}

int main(int argc, char *argv[]) {
	int a[3]={4,2,3};
	merge_sort(a,3);
	for(int s=0;s<3;s++){
		printf("%d ",a[s]);
	}
	
	return 0;
}

13 变量内存申明(2021/4/19)

  指针必须指向具有内存空间的变量,因此指针变量在申明的时候想拥有自己的空间,在C语言中必须使用void *malloc(int)函数申请空间;C++可以用new 进行申请空间,c语言没有new功能。

int *pc=(int*)malloc(10);
int *pcpp=new int[10];

14 vector容器初始化

	int arr2[6]={33,14,5,63,7,18};
	vector<vector<int>> ms(3,vector<int>(arr2,arr2+2));
	for(auto ky:ms){
		for(auto kx:ky)
		cout<<kx<<endl; 
	}
vector<int> vec(4); //0初始化,4个元素
vector<int> vec(4,2);//2初始化,4个元素
int arr[6]={33,14,5,63,7,18};
vector<int> vec(arr,arr+6);
vector<int> vec{3,4,1,3};
vector<int> vec1(vec);//向量赋值

15 算法题,看似简单,有点难

给你一个二维数组 tasks ,用于表示 n​​​​​​ 项从 0 到 n - 1 编号的任务。其中 tasks[i] = [enqueueTime_i, processingTime_i] 意味着第 i​​​​​​​​​​ 项任务将会于 enqueueTime_i 时进入任务队列,需要 processingTime_i 的时长完成执行。

现有一个单线程 CPU ,同一时间只能执行 最多一项 任务,该 CPU 将会按照下述方式运行:

如果 CPU 空闲,且任务队列中没有需要执行的任务,则 CPU 保持空闲状态。
如果 CPU 空闲,但任务队列中有需要执行的任务,则 CPU 将会选择 执行时间最短 的任务开始执行。如果多个任务具有同样的最短执行时间,则选择下标最小的任务开始执行。
一旦某项任务开始执行,CPU 在 执行完整个任务 前都不会停止。
CPU 可以在完成一项任务后,立即开始执行一项新任务。
返回 CPU 处理任务的顺序。

输入:tasks = [[1,2],[2,4],[3,2],[4,1]]
输出:[0,2,3,1]
输入:tasks = [[7,10],[7,12],[7,5],[7,4],[7,2]]
输出:[4,3,2,0,1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-threaded-cpu
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
using namespace std;
//[[1,2],[2,4],[3,2],[4,1]] 
class solution{
	private:
		 using pii=pair<int,int>;
	public:
	    vector<int> getOrder(vector<vector<int>>& tasks) {

    		int n=tasks.size();
    		vector<int> indi(n);
    		iota(indi.begin(),indi.end(),0);
			sort(indi.begin(),indi.end(),[&](int i,int j){
				return tasks[i][0]<tasks[j][0];
			}); 

			priority_queue<pii,vector<pii>,greater<pii>> q;
			
			vector<int> spend;
			int time=0;
			int ptrz=0;
			for(int i=0;i<n;i++){
				if(q.empty()){
					time=max(time,tasks[indi[i]][0]);
				}
				while(ptrz<n && tasks[indi[ptrz]][0]<=time){
					q.emplace(tasks[indi[ptrz]][1],indi[ptrz]);
					ptrz++; 
				};
				auto top=q.top();
				time+=top.first;
				spend.push_back(top.second); 
				q.pop();
			}

			return spend;
		} 		
};

int main(){

	int arr2[6]={3,14,5,63,7,18};
	vector<vector<int>> ms{{1,2},{2,4},{3,2},{4,1}};
	solution so;
	vector<int> p=so.getOrder(ms);
	for(int t=0;t<p.size();t++){

		cout<<p[t]<<endl; 
	}


	return 0;
} 

16 goto
goto 标签不具有隔离作用,两个goto标签子块放在一起,上一个执行了下面一个也会执行

int main(){
	
	loop1:{
		cout<<1<<endl;
	}
	loop2:{
	cout<<2<<endl;}
	return 0;
}

17 最大频数

输入:nums = [1,2,4], k = 5
输出:3
解释:对第一个元素执行 3 次递增操作,对第二个元素执 2 次递增操作,此时 nums = [4,4,4]4 是数组中最高频元素,频数是 3 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
    int maxFrequency(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        long long total = 0;
        int l = 0, res = 1;
        for (int r = 1; r < n; ++r){
            total += (long long)(nums[r] - nums[r - 1]) * (r - l);
            while (total > k){
                total -= nums[r] - nums[l];
                ++l;
            }
            res = max(res, r - l + 1);
        }
        return res;
    }

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/solution/zui-gao-pin-yuan-su-de-pin-shu-by-leetco-q5g9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

双指针的方式 ,进行增量变化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值