当前位置: 首页 > news >正文

西南科技大学814考研一

C语言基础

字节大小

char1 字节
unsigned char1 字节
short2 字节
unsigned short2 字节
int:通常为 4 字节(32 位平台)或 8 字节(64 位平台)
unsigned int:通常为 4 字节(32 位平台)或 8 字节(64 位平台)
long:通常为 4 字节(32 位平台)或 8 字节(64 位平台)
unsigned long:通常为 4 字节(32 位平台)或 8 字节(64 位平台)
long long8 字节
unsigned long long8 字节
float4 字节
double8 字节
long double:通常为 8 字节(32 位平台)或 16 字节(64 位平台)
"i love you"字符串C语言中占多少字节
C语言字符串是字符数组表示,并且结尾用\0
"i love you"={'i',' ','l','o','v','e',' ','y','o','u','\0'}
11
字节

union联合体:不需要补位,找最大

struct结构体:union和数组直接加,其余需要按照补位

补位:char(1),int(4)

char需要补最大的int也就是char占四位总共8位

注意

字节小的可以转换位字节大的,大的转换小的时候向下取整数

输出类型

类型值必须对应打印类型格式

例子

**1:**不同类型进行运算时候,小类型要转换为大类型在进行运算

3+'a'这样的表达式会发生隐式类型转换,'a'会被转换为它对应的ASCII码值97,然后与3相加得到100,这个值是一个整型值。

**2:**变量定义,赋值一定是相同类型

    char a[10]="SERWERTE";//不会报错char b[5];b="wertw";//会报错,string类型给char类型会报错

**3:**字符数组的存储地址

在C语言中,字符数组会以字符串的形式存储,字符串的每个字符会占用1个字节的空间,并且在字符串的末尾会加上一个'\0'作为字符串的结束标志。这个'\0'字符也会被存储在数组中,占用1个字节的空间。

**4:**数组初始化

int a[2][3]={1};
只赋值a[0][0]=1,其余都为0

变量

变量名只能由字母、数字和下划线组成,且必须以字母或下划线开头,不能用特殊字符

自增

int a=1;
int b=++a; //a先加1 a=2 在赋值给b=2
int c=a++; //先赋值给c c=1,a在自增1;a=2

变量后先加

"unsigned char" 是计算机编程中的一种数据类型。它表示一个无符号字符型变量,即只能存储非负整数的字符型变量。

三种结构

  1. 顺序结构:这是C语言中最基本的程序结构,指的是按照代码的先后顺序,逐行执行,不发生跳转。

  2. 选择结构:这种结构用于根据特定条件来执行不同部分的代码。C语言中的选择结构主要由ifelse ifelse语句实现。switch语句也是一种选择结构,用于处理多个可能的情况。

  3. 循环结构:这种结构用于重复执行一段代码,直到满足某个条件时停止。C语言中的循环结构主要由forwhiledo...while循环实现。

    for(开始;判定条件;循环结束执行)

顺序结构

c语言逻辑判断的结果是0或者1

#include <stdio.h>
#include <stdlib.h>int main (){if(3>2&&3%2){printf("%s","进入");}else{printf("%s","不进入");}return 0;
}

循环结构

swith case

满足一个case 里面没有break 会不判断,继续执行下面的case语句

default 默认执行,前面满足有break不会执行,没有会执行

#include <stdio.h>
#include <stdlib.h>int main (){int i;for(i=0;i<2;i++){switch (i) {case 1:printf("%d",i);case 2:printf("%d",i);case 3:printf("%d",3);default:printf("%d",i);}};return 0;
}

注意

x=4
!x=0
在C语言中,!是一个逻辑非运算符,它会对操作数进行逻辑非运算。如果操作数为0,则逻辑非运算的结果为1;如果操作数不为0,则逻辑非运算的结果为0

运算符

运算符表达式:(表达式有几个)一目、二目、三目

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三目运算符:?:

逗号

int a;
printf("%d",(a=2*5,a*4,a+3));

在这段代码中,使用了逗号运算符。逗号运算符会从左到右依次计算每个表达式,并返回最右侧表达式的值。

首先,a=2*5a 赋值为 10

然后,a*4 计算得到 40,但这个值并没有被赋给任何变量,因此它会被忽略。

最后,a+3 计算得到 13,这是逗号运算符返回的值。

因此,printf("%d",(a=2*5,a*4,a+3)); 会输出 13

逻辑运算符

逻辑运算符的优先级从高到低为:NOT(!) > AND(&&) > OR(||)

&& 有一个为真就是真,前面为真不需要判断后面直接返回真

||全真为真,前面为假直接返回假

int x,y,z,t;    
x=y=z=1;
t=++x || ++y && ++z; 
printf("%d,%d,%d,%d",x,y,z,t);

++xx 自增 1,然后返回 x 的值,所以 ++x 的值为2,然后 t = ++x || ++y && ++z,因为 || 运算符具有短路特性,当 ++x 的值为真(非0)时,后面的 ++y && ++z 将不再执行,直接返回 ++x 的结果,所以 yz 的值没有改变,仍然为1。而 t 的值就是 ++x 的结果,也就是2。所以最后的输出结果为 2,1,1,1

普通函数

isspace是C语言中的一个函数,用于检查给定的字符是否是空白字符。

C语言程序的基本单位是函数。一个C语言程序可以由一个或多个函数组成,其中必须有一个名为main的函数,作为程序的入口点。

交换两个值与指针

错误方法 \textcolor{red}{错误方法} 错误方法

#include <stdio.h>
void f(int *p,int *q){int *c;c=p;p=q;q=c;
}
void tran(int a,int b){int c = a;a=b;b=c;
}
//u.a和u.b共享同一块内存区域。当你先给u.a赋值,然后给u.b赋值,你实际上是在覆盖u.a的值。
int main() {int x=4,y=8;int *p = &x;int *q = &y;printf("交换之前地址%d-%d\n",p,q);printf("交换之前指针对应的值%d-%d\n",*p,*q);f(p,q);printf("交换之后地址%d-%d\n",p,q);printf("交换之后指针对应的值%d-%d\n",*p,*q);printf("x,y之前的值%d-%d\n",x,y);f(&x,&y);printf("x,y之后的值%d-%d\n",x,y);printf("x,y之前的值%d-%d\n",x,y);tran(x,y);printf("x,y之后的值%d-%d\n",x,y);
}

函数f中的参数a和b是整型指针,函数内部对a和b的修改并不会影响到函数外部的p和q。这是因为指针变量在C语言中也是按值传递的,也就是说,函数f接收的是p和q的副本,而非它们本身。

因此,在函数f中交换a和b的值,并不会影响到p和q。所以,主函数main中的打印结果会显示,指针的地址和对应的值都没有发生变化。

指针函数

看后面,就是一个函数

返回函数结果的地址

定义:int *f()

#include <stdio.h>
int *f(){static  int x = 10; //全局使用return &x;          //返回x的地址
}
int main() {int *r = f();   //接受返回地址printf("%d\n",*r);   //打印地址对应的值return 0;
}

函数指针

看后面就是一个指针 ;一个指向函数的指针;在内存空间中存放的是函数的地址;

int add(int a,int b){return a+b;
}
int main() {int (*r)(int a,int b) = &add;   //函数指针接受函数地址int out = r(2,3);         //调用函数printf("%d\n",out);return 0;
}

输出与输入

格式化输出

int x=10,y=3;
printf("%d\n",x%y,x/y);
输出:1

printf函数中,格式化字符串"%d\n"只对应一个输出,即x%y的结果

int a=3366;
printf("│%-08d│",a);

这段代码的目的是打印整数 a,值为 3366,在一个格式化的字符串中,字符串的格式为 “│ %-08d │”。让我们分析一下这个格式化字符串:

  • 是一个字面字符,它会被直接打印出来。
  • % 是一个格式说明符的开始。
  • - 表示左对齐。
  • 0 表示如果数字的位数少于指定的宽度,那么不足的部分会用0填充。
  • 8 表示数字的宽度为8位。
  • d 表示打印一个整数。

所以,这段代码会打印出 │33660000│。整数 a(3366)左对齐,并在右侧用0填充,以确保总共有8位数字。

int x;
x = printf("I am c program\n");
printf("x=%d", x);

首先打印字符串 “I am c program\n”,然后打印变量 x 的值。变量 x 的值就是 printf 函数返回的值,也就是打印的字符数(不包括最后的 ‘\0’ 字符)。

打印与++

#include <stdio.h>
//合并方法
int main() {int a = 1;printf("%d ",a++);//在前先打印,a在+1;return 0;
}
1 
#include <stdio.h>
//合并方法
int main() {int a = 1;printf("%d ",++a);//a先+1,后先打印;return 0;
}
2
#include <stdio.h>int main( ){int arr[] = {2,4,6,8,10,12,14,16};int *p=arr;printf("%d ", *p); //p指针指向数组第一元素printf("%d ", *p+1); //拿到p指针指向元素,该元素的值加1,在打印,p还是指向该元素,该元素的值没有发送变化printf("%d ", *p++); //先打印p指针指向元素的值;p指针往后后移一个printf("%d ", (*p)++); //先打印p指针指向元素的值;设置p指针指向的值在加1printf("%d ",--*p);    //先拿出p指针指向元素的值,设置元素值减1,在打印return 0;
}#include <stdio.h>int main( ){int arr[] = {1,2,3,4,5,6,7,8};int *p=arr + sizeof(arr) / sizeof(int) - 1;*p--+=123; // 双目大于单目 --》*p=*p+123;p是指针p--等同p往前移动一个printf("%d", *p--);//先打印,p在往前移动一个printf("%d", (*p)--);// 先拿着值,打印值,值在减1printf("%d", *--p);//先指针往前移动,在拿着值printf("%d",--*p);//先拿值,值在减1return 0;
}
    #include <stdio.h>int main(){FILE *fp;int i, a[6] = {1, 2, 3, 4, 5, 6}, b[6];fp = fopen("d.dat", "w + b");//将数组中元素写入fp文件指针,数组,每次写入元素存储地址大小,写六个,文件指针fwrite(a, sizeof(int), 6, fp);for (i = 0; i < 6; i++)//将数组中下标为2的元素写入fp文件指针,数组,每次写入元素存储地址大小,写六个,文件指针fwrite(&a[2], sizeof(int), 1, fp);//重置到文件开头rewind(fp);//定位到数组a的第三个元素(索引为2)  fseek(fp, sizeof(int) * 2, SEEK_CUR);// 读取6个整数到数组b  fread(b, sizeof(int), 6, fp);fclose(fp);for (i = 0; i < 6; i++)printf("%d,", b[i]);}
//结果
3,4,5,6,3,3,

数组

什么类型的数组用什么类型指针的接收

int arr[10] = {1,2,3,4,5,6,7,8,9,10,};
//c语言数组名是第一个元素的地址
int *p = arr;
int *p1 = arr+1;//数组第二个元素的地址
int *p2 = arr++;//不允许,编译报错
printf("%d",*p);
return 0;
#include <stdio.h>
#include <stdlib.h>int main (){char arr[20] = {"hello world"};//数组名是第一个元素的地址char *p1=arr;//打印第一个元素printf("%c\n",*arr);printf("%c\n",*p1);//打印第六个元素printf("%c\n",*arr+5);printf("%c\n",*p1+5);//打印第六个元素地址if(arr+5 == p1+5){printf("%s","是一样的结果\n");}else{printf("%s","不是一样的结果\n");}printf("%c\n",arr+5);printf("%c\n",p1+5);return 0;
}

二维数组

#include <stdio.h>
int main (){int n;int array[1000][3];scanf("%d",&n);for(int i = 0;i<n;i++){scanf("%d %d %d",&array[i][0],&array[i][1],&array[i][2]);}printf("输入的数组:\n");for(int i=0;i<n;i++){printf("%d %d %d\n",array[i][0],array[i][1],array[i][2]);}return 0;
}
#include <stdio.h>int main() {int m, n;scanf("%d", &m);scanf("%d", &n);// 声明二维数组int array[m][n];// 获取用户输入的二维数组元素printf("请输入二维数组的元素:\n");for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {scanf("%d", &array[i][j]);}}// 打印二维数组以验证输入printf("\n您输入的二维数组是:\n");for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {printf("%d ", array[i][j]);}printf("\n");}return 0;
}

字符串

定义字符串

char *str1 = "Hello, World 1!";
char str2[] = "Hello, World 2!";
printf("%s\n",str1);
printf("%s\n",str2);

字符串的比较

字符数组

if(!*s2) 在 C 语言中是判断 s2 指向的字符是否为 '\0' —— 字符串结束标志。

if(*s2)在C语言中是判断s2指向的字符是否不为'\0'

#include <stdio.h>
int main() {char a[5] ={'a','b','c','d','e'};char *ptr = (char*)(&a+1); //ptr指向a的下一个printf("%c, %c\n",*(a+1),*(ptr-1)); //*(ptr-1) 指向a中最后一个return 0;
}

文件读写

C语言操作文件的标准库是stdio.h库,这个库中包含了用于文件操作的函数,例如:

  1. fopen():打开文件;
  2. fclose():关闭文件;
  3. fgetc():从文件中读取一个字符;
  4. fgets():从文件中读取一行;
  5. fprintf():将格式化的数据写入文件;
  6. fscanf():从文件中读取格式化的数据。
FILE *fp; // 文件指针
char ch; // 读取的字符
// 打开文件,如果文件不存在则创建新文件
fp = fopen("./study.txt", "w+");
// 向文件中写入数据
fprintf(fp, "Hello, world!\n");
// 向文件中写入数据
fputs("This is testing for fputs...\n", fp);
// 将文件指针移到文件开头
fseek(fp, 0, SEEK_SET);
// 从文件中读取数据并输出到控制台
while ((ch = fgetc(fp)) != EOF) {
putchar(ch);
}
// 关闭文件
fclose(fp);

fprintf()fputs() 都是用于向文件中写入数据的 C 语言标准库函数,但它们有一些区别。

区别一:参数不同

fprintf() 函数需要指定格式化字符串以及要写入的数据,可以写入多种类型的数据,并且可以按照指定的格式进行输出。而 fputs() 函数只能写入字符串数据,不能写入其他类型的数据。

区别二:返回值不同

fprintf() 函数返回写入的字符数,如果发生错误则返回负值。而 fputs() 函数返回非负数表示成功,返回 EOF 表示失败。

区别三:功能不同

fprintf() 函数可以将多种类型的数据按照指定的格式写入文件中,可以实现更加复杂的输出操作。而 fputs() 函数只能将字符串写入文件中,功能相对较为简单。

综上所述,fprintf() 函数更加灵活和强大,可以实现更加复杂的输出操作,而 fputs() 函数则适用于简单的字符串写入操作。

fgetc() 是一个 C 语言标准库函数,用于从指定的文件中读取一个字符。

putchar() 函数会将 ch 字符输出到标准输出设备上,并返回输出的字符。如果输出失败,则返回 EOF

例子:

读取文件内容算平均值再写入到文件

#include <stdio.h>int main() {FILE *fp;int num, sum = 0, count = 0;float avg;// 打开文件fp = fopen("data.txt", "r");if (fp == NULL) {printf("无法打开文件!\n");return 1;}// 读取文件中的数字并计算总和和数量while (fscanf(fp, "%d", &num) != EOF) {sum += num;count++;}// 计算平均值avg = (float)sum / count;// 将平均值写入文件fp = fopen("avg.txt", "w");if (fp == NULL) {printf("无法打开文件!\n");return 1;}fprintf(fp, "%.2f", avg);fclose(fp);printf("平均值已写入文件 avg.txt\n");// 关闭文件fclose(fp);return 0;}

例子

#include "stdio.h"
int main(){FILE *fp = NULL;char s[] ="How to tell a story?", ch;fp = fopen("data. txt","w");//将字符串写入文件fprintf(fp,"%s", s);fclose(fp);//读文件fp = fopen("data. txt","r");//移送文件指针fseek(fp,4,SEEK_SET) ;//读取字符判断是不是到文件末尾while ((ch = fgetc(fp)) != EOF){//是t 往前两个设置为结束符,while判断结束跳出循环if(ch =='t'){s[ftell(fp) - 2]='\0';}}printf("%s\n",s);fclose(fp);return 0;
}
  1. ftell(fp):这是一个函数,用于获取文件指针 fp 当前在文件中的位置(以字节为单位)。
  2. ftell(fp) - 2:从 fp 的当前位置往回数 2 个字节。
  3. s[ftell(fp) - 2]:这表示字符数组 s 中位置为 ftell(fp) - 2 的字符。这里有一个假设,即 ftell(fp) - 2 是一个有效的数组索引,不会越界。
  4. s[ftell(fp) - 2] = '\0';:这将 s 数组中位置为 ftell(fp) - 2 的字符设置为 \0(字符串的结束标记)。

联合体

#include <stdio.h>
union {int a;char b;} u;
//u.a和u.b共享同一块内存区域。当你先给u.a赋值,然后给u.b赋值,你实际上是在覆盖u.a的值。
int main() {u.a = 65;u.b = 'a';//覆盖a的值printf("%d\n", u.a);printf("%c\n", u.b);}

算法

算法复杂度

模式匹配:O(m*n)

KMP:O(m+n)

模式匹配

暴力

void bruteForce(char *src, char *target) {  int srcLen = strlen(src);  int targetLen = strlen(target);  for (int i = 0; i <= srcLen - targetLen; i++) {  int j;  for (j = 0; j < targetLen; j++) {  if (src[i + j] != target[j])  break;  }  if (j == targetLen) {  printf("Pattern found at index %d \n", i);  }  }  
}

kmp

i不会回退,当不匹配时,回退j,j回退的值在next数组中找

由匹配字符串构建,next数组

next数组构建原理:

nenxt数组长度与匹配串长度一致,循环匹配字符串,

next数组下标值:在匹配串中从0到下标的子串中,分别求该子串前缀或者后缀,从前缀或者后缀中找出一样的,公共缀的最长长度就是next数组对应的下标值

"ABCDABD"为例,
1.首先需要找出ABCDABD这一串字符串的所有前缀AABABCABCDABCDAABCDABABCDABD2.然后找出每个前缀字符的最长公共前后缀"A"的前缀和后缀都为空集,共有元素的长度为0"AB"的前缀为[A],后缀为[B],共有元素的长度为0"ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0"ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;“ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A”,长度为1;“ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB”,长度为2"ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为03.然后就形成了部分匹配值(prefix table)每个前缀字符的最长公共前后缀放在一起就形成了部分匹配表,也就是:0 0 0 0 1 2 0
//构建next数组
void computeLPSArray(char *pat, int M, int *lps) {  int len = 0;   lps[0] = 0;   int i = 1;  while (i < M) {  if (pat[i] == pat[len]) {  len++;  lps[i] = len;  i++;  } else {  if (len != 0) {  len = lps[len - 1];  } else {  lps[i] = len;  i++;  }  }  }  
}  void KMPSearch(char *pat, char *txt) {  int M = strlen(pat);  int N = strlen(txt);  //匹配字符串构建next数组int lps[M];  computeLPSArray(pat, M, lps);  int i = 0;   int j = 0;   while (i < N) { //匹配上加1if (pat[j] == txt[i]) {  j++;  i++;  }  //找到返回indexif (j == M) {  printf("Found pattern at index %d \n", i - j);  j = lps[j - 1];  //没有找到} else if (i < N && pat[j] != txt[i]) {  //不是第一个没有匹配,回退jif (j != 0)  j = lps[j - 1];  //第一个找到,直接加else  i = i + 1;  }  }  
}

数组合并

两个有序数组合并一个有序数组

#include <stdio.h>
//合并方法
int main() {int a[] = {1,3,5,7,9};int asize= sizeof(a)/ sizeof(a[0]);int b[] = {2,4,6,8,10};int bsize= sizeof(b)/ sizeof(b[0]);int r[] ={0,0,0,0,0,0,0,0,0,0};int rsize=asize+bsize;//合并ab到int i=0,j=0,l=0;while(i<=asize&&j<=bsize){if(a[i]<=b[j]){r[l]=a[i];i=i+1;}else{r[l]=b[j];j=j+1;}l=l+1;}for(int i=0;i<rsize;i++){printf("%d ",r[i]);}return 0;
}

动态规划

未知的问题用已知的解决

定义dp数组,判断数组里面是否有,有就取,没有就放在数组

斐波那契数列

int n =10;
int dp[n+1];
dp[0]=0;
dp[1]=1;
int l = sizeof(dp)/sizeof (dp[0]);
for (int j = 2; j <=l ; ++j) {dp[j]=dp[j-1]+dp[j-2];
}
for (int i = 0; i < l; ++i) {printf("%d ",dp[i]);
}
printf("%d ",dp[n-1]);

走楼梯

dp[1] = 1;  
dp[2] = 2;  
for (int i = 3; i <= n; i++) {  p[i] = dp[i - 1] + dp[i - 2];  
}  

最长连续递增子序列

#include <stdio.h>
int max(int a,int b){if(a>b){return a;}else{return b;}
}
int main() {int arr[] = {3,2,5,7,1,4,10,8,9};int len=sizeof(arr)/ sizeof(arr[0]);int dp[len]; //定义dp数组for (int i = 0; i < len; ++i) { //初始化dp[i]=1;};for (int i = 0; i < len; ++i) {int temp = arr[i];//i位置上的元素for (int j = i; j >0 ; j--) {if(arr[j]<temp && i==j+1){  //在i之前找到比这个小,并且是连续的dp[i]=dp[j]+1; //以i位置结尾的最长递增子序列的长度是j的加1(i本身)break;}}}int result = 1;for (int i = 0; i < len; ++i) { //初始化result=max(result,dp[i]);};printf("最长递增子序列的长度:%d",result);return 0;
}

贪心

最优解决:程序通过贪心算法计算出需要使用多少个硬币找零,收银员总是先给最大的硬币

也就是说要找的零钱张数最少

#include <stdio.h>
int found(int a[],int mon,int len,int dp[]){//要找给顾客的钱为0;就退出循环if(mon == 0){return 0;}else{for (int i = 0; i < len; ++i) {if(a[i]>=mon){//先找最大dp[i-1]=mon/a[i-1];mon=mon%a[i-1];len=i;break;}}return found(a,mon,len,dp);}
}
int main() {//若干零钱int arr[] = {1,2,5,10,20,50,100};int mon = 37;//实际要给顾客找零int len = sizeof(arr)/ sizeof(arr[0]);int dp[len];//对应零钱找的张数for(int i=0;i<len;i++){dp[i]=0;}found(arr,mon,len,dp);for(int i=0;i<len;i++){printf("%d张%d\n",dp[i],arr[i]);}return 0;
}

背包

01背包

#include <stdio.h>
int max(int a, int b) {return a > b ? a : b;
}int knapsack(int w[], int v[], int n, int W) {int i, j;//构建二维数组:行放入物品种类0-n号物品种类,列是背包对应的重量,ij是背包对应的最大价值int dp[n+1][W+1];// 初始化dp数组--背包重量为0,其最大价值为0;背包种类为0;其最大价值为0for (i = 0; i <= n; i++) {for (j = 0; j <= W; j++) {if (i == 0 || j == 0) {dp[i][j] = 0;} else {dp[i][j] = -1;}}}// 动态规划求解for (i = 1; i <= n; i++) {for (j = 1; j <= W; j++) {if (j < w[i-1]) {//当前背包重量小于物品重量dp[i][j] = dp[i-1][j]; //背包最大价值是背包重量-1对应的最大价值} else {//当前背包重量可以放该物品//不放,背包最大价值还是当前物品重量-1对应的价值//放,背包最大价值是当前放入物品重量对应的价值+没放之前背包对应的最大价值dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i-1]] + v[i-1]);}}}return dp[n][W];
}int main() {int w[] = {2, 1, 3}; // 物品的重量int v[] = {4, 2, 3}; // 物品的价值int W = 5; // 背包的总重量int n = sizeof(w) / sizeof(w[0]); // 物品的数量int max_value = knapsack(w, v, n, W); // 求最大价值printf("最大价值为:%d\n", max_value);return 0;}

回溯

DFS:深度优先搜索借鉴递归、栈实现

BFS:广度优先搜索借鉴队列实现

DFS 递归判断迷宫有出路没有

#include <stdio.h>
#define M 5
#define N 5
//迷宫出口
int a=3;int b=4;
//迷宫
//0是没有访问过
//-1墙
//2访问过
int maze[M][N] = {{0, 0, 0, 0, 0},{0, -1, -1, 0, -1},{0, -1, 0, 0, -1},{0, -1, -1, -1, -1},{-1, 0, 0, 0, 0}};
//找出路
int find_path(int m,int n){//当前是不是目标,是:返回找到出口if(m==a && n==b){maze[m][n]=2;return 1;}//刚开始一定可以进去;标记走过maze[m][n]=2;//在迷宫内并且可以走//上if(0<=m-1&&m-1<=M&&maze[m-1][n]==0){return find_path(m-1,n);}//右else if(0<=n+1&&n+1<=M&&maze[m][n+1]==0){return find_path(m,n+1);}//下else if(0<=m+1&&m+1<=M&&maze[m+1][n]==0){return find_path(m+1,n);}//左else if(0<=n-1&&n-1<=M&&maze[m][n-1]==0){return find_path(m,n-1);}else {return 0;}}
int main() {if(find_path(0,0)){printf("有出路");}else{printf("没有出路");}//找出路}

BFS长草问题–BFS借助队列

【问题描述】
小明有一块空地,他将这块空地划分为 n 行 m 列的小块,每行和每列的长度都为 1小明选了其中的一些小块空地,种上了草,其他小块仍然保持是空地。
这些草长得很快,每个月,草都会向外长出一些,如果一个小块种了草,则它将向自己的上、下、左、右四小块空地扩展,小块空地都将变为有草的小块。请告诉小明,k 个月后空地上哪些地方有草。
【输入格式】
输入的第一行包含两个整数 n, m。
接下来 n 行,每行包含 m 个字母,表示初始的空地状态,字母之间没有空格。如果为小数点,表示为空地,如果字母为 g,表示种了草。
接下来包含一个整数 k。
【输出格式】
输出 n 行,每行包含 m 个字母,表示 k 个月后空地的状态。如果为小数点,表示为空地,如果字母为 g,表示长了草。
【样例输入】
4 5
.g...
.....
..g..
.....
2
【样例输出】
gggg.
gggg.
ggggg
.ggg.
#include<stdio.h>
#include <stdlib.h>
#define M 6
#define N 6
// 定义链表节点结构体
typedef struct node {int data;struct node* next;
} Node;
// 定义队列结构体
typedef struct queue {Node* front; // 队头指针Node* rear; // 队尾指针int size; // 队列长度
} Queue;// 初始化队列
void initQueue(Queue* q) {q->front = NULL;q->rear = NULL;q->size = 0;
}// 判断队列是否为空
int isEmpty(Queue* q) {return q->front == NULL;
}// 获取队列长度
int getLength(Queue* q) {return q->size;
}// 入队操作
void enqueue(Queue* q, int data) {Node* newNode = (Node*)malloc(sizeof(Node)); // 创建新节点newNode->data = data;newNode->next = NULL;if (isEmpty(q)) { // 如果队列为空,队头和队尾都指向新节点q->front = newNode;} else { // 否则,将新节点插入到队尾,并更新队尾指针q->rear->next = newNode;}q->rear = newNode; // 更新队尾指针q->size++; // 队列长度加1
}// 出队操作
int dequeue(Queue* q) {if (isEmpty(q)) { // 如果队列为空,返回错误码-1return -1;}int data = q->front->data; // 取出队头节点的数据Node* temp = q->front; // 用临时变量保存队头节点地址q->front = q->front->next; // 将队头指针指向下一个节点if (q->front == NULL) { // 如果队头指针为空,说明队列已空,将队尾指针也置为空q->rear = NULL;}free(temp); // 释放队头节点的内存空间q->size--; // 队列长度减1return data; // 返回取出的数据}
//第几个月后
int k = 1;
//草地
char c[M][N]={{'.','.','.','.','.','.'},{'.','.','.','.','g','.'},{'.','g','.','.','.','.'},{'.','.','.','.','.','.'},{'.','.','g','.','.','.'},{'.','.','.','.','.','.'}};
//bfs长草
void bfs(Queue *x,Queue *y){//初始化:长草地址加入队列for (int i = 0; i < M; ++i) {for (int j = 0; j < N ; ++j) {if(c[i][j]=='g'){enqueue(x,i);enqueue(y,j);}}}//队列长度大于0while(getLength(x)>0){//出队int qx = dequeue(x);int qy = dequeue(y);//循环拿到下一步//移动方向int mv[4][2]={{0,1},{1,0},{0,-1},{-1,0}};for(int i=0;i<4;i++){int *temp = mv[i];int tx = qx+temp[0];int ty = qy+temp[1];//如果下个方向可以长草if(0<=tx&&tx<M && c[tx][ty]=='.'&&0<=ty&&ty<N){//标记长草c[tx][ty]='g';//坐标加入队列enqueue(x,tx);enqueue(y,ty);}}}
}
int main(){printf("初始化草地:\n");for (int i = 0; i < M; ++i) {for (int j = 0; j < N ; ++j) {printf("%c ",c[i][j]);}printf("\n");}//创建队列Queue x;initQueue(&x); // 初始化队列Queue y;initQueue(&y); // 初始化队列//长草bfs(&x,&y);printf("%d个月草地长草后:\n",k);for (int i = 0; i < M; ++i) {for (int j = 0; j < M ; ++j) {printf("%c ",c[i][j]);}printf("\n");}return 0;
}

例子

数组移位置

编写一个程序,有 n 个整数,要求你编写一个函数使其向右循环移动 m 个位置

输入:输入 n m 表示有 n 个整数,移动 m 位

输出:输出移动后的数组

例如:

输入:
10 5
1 2 3 4 5 6 7 8 9 0

输出:
6 7 8 9 0 1 2 3 4 5

    #include <stdio.h>int main(){int a[] ={1,2,3,4,5,6,7,8,9,0};int l=sizeof(a)/sizeof (int);int b[l];int index;for(int i=0;i<l;i++){int now = (i+5)%l;b[now]=a[i];}for(int i=0;i<l;i++){printf("%d ",b[i]);}return 1;}

判断字符数组大小

例如:

输入:
abc
abd

输出:

abd

#include<stdio.h>
int strcmp(char *p1,char *p2){//不为0,并且p1对应元素=p2对应元素 进入循环while (*p1 && (*p1 == *p2)){p1++;p2++;}return *(const unsigned char *)p1 - *(const unsigned char *)p2;}
int main()
{char a[]="abc",b[]="abd";if(strcmp(a,b)>0)printf("%s", a);elseprintf("%s", b);return 0;
}

走楼梯

题目描述

现有一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用,你选择从下标为 0 或下标为 1 的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。
编程要求

此题已给出部分代码,你可在/begin-end/之间进行编码,让程序通关。
输入输出格式

输入格式
第一行输入一个整数 costSize;
第二行输入数组 cost。
输出格式
输出一个整数。
输入输出样例1

输入
4
10 21 13 16
输出
23
输入输出样例2

输入
5
1 2 3 4 5
输出
6
说明提示

2≤costSize≤1000
1≤cost[i]≤100


获得二维数组中B、b的个数

#include <stdio.h>int cnt(char *s) {int i = 0;int c = 0;// 如果字符串非空if (s)while (*(s + i)) {if (s[i] == 'B' || *(s + i) == 'b') {c++;}i++;}return c;
}int main() {int c = 0;char s[][6] = {"book", "BBS", "bee", "table"};// 获取数组长度int len = sizeof(s) / sizeof(s[0]);// 遍历数组中的每个字符串,并计算'B'或'b'的个数for (int i = 0; i < len; i++) {//对于二维数组 s[0]是一个指针,指向bookc += cnt(s[i]);}printf("%d\n", c);return 0;
}

函数指针

#include <stdio.h>
int* (*funcpl[2])(int*, int*,int*);
int (*funcp2[2])(int*, int*);
int* max(int *a, int *b,int *c){int*x=*a>*b?a:b;return *x >*c ?x:c;
}
int* min(int *a, int *b, int *c){int *x=*a<*b?a:b;return*x<*c?x:c;
}
int mul(int *a,int *b){return *a * *b;
}
int div(int *a, int *b){//判断b是不是0;不是返回a/b;是返回-1return *b?*a/(*b):-1;
}int main(){int a = 10,b= 20,c = 30, result = 0;funcpl[0] = max;funcpl[1] = min;funcp2[0] = mul;funcp2[1] = div;for(int j= 0;j< 2;){result +=(*funcp2[j++])((*funcpl[0])(&a,&b,&c),(*funcpl[1])(&a, &b,&c));}printf("%d\n",result);return 1;
}

回文数

#include <stdio.h>int is_palindrome(int num) {int reversed = 0;int temp = num;/**********FOUND**********/while (temp != 0) {reversed = reversed * 10 + temp % 10;/**********FOUND**********/temp=temp/10;}if (num == reversed) {return 1;} else {return 0;}
}int main() {int num = 12321;if (is_palindrome(num)) {printf("%d is a palindrome.\n", num);} else {printf("%d is not a palindrome.\n", num);}return 0;
}

交换a,b的值

#include <stdio.h>/**********FOUND**********/
void swap(int *a, int *b) {  // 错误:传递的是值的拷贝,无法实现交换/**********FOUND**********/int temp = *a;/**********FOUND**********/*a = *b;/**********FOUND**********/*b = temp;
}int main() {int x = 10;int y = 5;printf("Before swap: x = %d, y = %d\n", x, y);/**********FOUND**********/swap(&x, &y);printf("After swap: x = %d, y = %d\n", x, y);return 0;
}

自增与逻辑

C语言中!=0的整数为ture,==0为false

#include <stdio.h>int main(){int a = 1;int b=-2;for( ; a-- && b++; ){printf("%d ,%d,", a, b);}printf("%d ,%d,", a, b);return 1;
}

注意:a–&&

先拿a的值,判断true还是false,与&&右边比较,a在减少1

函数

函数的形参和实参分别占用不同的存储单元

若指针指向变量,则可以向指针所指内存单元写入数据

可以取变量的地址赋值给同类型的指针变量

printf("%d\n", strlen("\t"\\n'\065\08AB"));\t 代表一个制表符 (tab)。\\n 代表一个换行符,因为 \ 被转义了,所以它表示一个普通的换行。' 是一个单引号字符。\065 是八进制表示的字符,其对应的十进制是 53,代表字符 S。\08AB 这里有点问题,因为 \08A 和 B 都被解释为独立的字符。八进制08A对应的是一个不可打印的控制字符,而B就是一个普通的字母。两个字符

求数组中最大可以构成的等差数组的组数

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//判断素数
int isPrime(int n){if(n<2){return 1;}else{for(int i = 2;i<n;i++){if(n%i==0){return 0;}}return 1;}
}
// 查找等差数列的函数
int findArithmeticSequences(int arr[], int n) {if (n < 3) return 0; // 如果数组元素少于3, 则不可能有等差数列int maxCount = 0; // 记录最大的等差数列组数  1 2 3 4 最大组数就有三组(1,2;2,3;3,4)for (int i = 0; i < n - 2; i++) { // 遍历数组int count = 0; // 计数器,记录当前起始点的等差数列数量int diff = arr[i + 1] - arr[i]; // 计算当前起始点的公差// 检查等差数列for (int j = i + 1; j < n - 1; j++) {if (arr[j + 1] - arr[j] == diff) {count++; // 找到一个等差数列,增加计数器j++; // 跳过这个元素,因为下一个元素可能与当前元素形成新的等差数列}}maxCount = count > maxCount ? count : maxCount; // 更新最大的等差数列组数}return maxCount + 1; // 返回最大的等差数列组数(+1是因为我们需要至少3个元素来形成一个等差数列)
}int main() {int a=1,b=11;int max_len = 0; // 最长等差数列的长度int temp[b-a];//数组长度int index=0;//获取之间的素数数组for (int i = a; i <= b; i++) {if (isPrime(i)==0){continue; // 如果i不是质数,跳过}else{temp[index]=i;index++;}};int r = findArithmeticSequences(temp,index);printf("%d",r);return 0;}

相关文章:

西南科技大学814考研一

C语言基础 字节大小 char&#xff1a;1 字节 unsigned char&#xff1a;1 字节 short&#xff1a;2 字节 unsigned short&#xff1a;2 字节 int&#xff1a;通常为 4 字节&#xff08;32 位平台&#xff09;或 8 字节&#xff08;64 位平台&#xff09; unsigned int&#x…...

【网络编程】简述TCP通信程序,三次握手,四次挥手

文章目录 &#x1f384;TCP通信程序⭐打印字符串✨中文乱码问题&#x1f388;解决方法 &#x1f33a;TCP三次握手&#x1f33a;TCP四次挥手&#x1f6f8;其他 &#x1f38a;专栏【网络编程】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386…...

【ARM Trace32(劳特巴赫) 使用介绍 5 -- Trace32 ELF 文件加载介绍】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 1.1 Trace32 加载符号表1.1.1 ELF 文件加载1.1.2 其它格式文件加载1.1.3 多个 ELF 的加载1.2 Trace32 UEFI 配置1.2.1 x86 32-BIT1.2.2 x86 64-BIT1.2.3 ARM1.1 Trace32 加载符号表 劳特巴赫 TRACE32 可以显示目标…...

Linux(4):Linux文件与目录管理

目录与路径 相对路径在进行软件或软件安装时非常有用&#xff0c;更加方便。利用相对路径的写法必须要确认目前的路径才能正确的去到想要去的目录。 绝对路径的正确度要比相对路径好&#xff0c;因此&#xff0c;在写程序&#xff08;shell scripts&#xff09;来管理系统的条…...

Altium Designer学习笔记2

原理图的绘制 需要掌握的是系统自带原理图库元件的添加。...

Atlassian发布最新补贴政策,Jira/Confluence迁移上云最低可至零成本

到2024年2月15日&#xff0c;Atlassian将不再提供对Jira、Confluence、Jira Service Management等Server版产品的支持。 近期&#xff0c;Atlassian推出了一项针对云产品的特殊优惠。现在从Server版迁移到云版&#xff0c;您能享受到高额补贴&#xff0c;甚至成本低至零元。立…...

基于FPGA的五子棋(论文+源码)

1.系统设计 在本次设计中&#xff0c;整个系统硬件框图如下图所示&#xff0c;以ALTERA的FPGA作为硬件载体&#xff0c;VGA接口&#xff0c;PS/2鼠标来完成设计&#xff0c;整个系统可以完成人人对战&#xff0c;人机对战的功能。系统通过软件编程来实现上述功能。将在硬件设计…...

QT5 MSVC2017 64bit配置OpenCV4.5无需编译与示范程序

环境&#xff1a;Windows 10 64位 Opencv版本&#xff1a;4.5 QT&#xff1a;5.14 QT5 MSVC2017配置OpenCV 版本参考&#xff1a; opencv msvc c对应版本 1.安装MSVC2017&#xff08;vs2017&#xff09; 打开Visual Studio Installer&#xff0c;点击修改 选择vs2017生成工…...

windows如何查看自己的ip地址

windows如何查看自己的ip地址 1.打开控制面板 2.进入网络和internet 3.进入网络共享中心 4.点击以太网进入网络详情页&#xff0c;或邮件已连接的网络&#xff0c;点击属性 5.查看ipv4地址就是当前机器ip...

Camera2的使用【详细】

目录 1.获取权限 2. 获取指定相机ID (1)获取相机管理者CameraManager (2)获取相机ID列表 (3)获取相机特征CameraCharacteristics (4)获取相机朝向 3.获取相机输出尺寸 (1)根据相机ID获取相机特征 (2)获取输出流配置StreamConfigurationMap (3)获取输出尺寸数组(参数为…...

Playcanvas后处理-辉光bloom

&#xff08;一&#xff09;Bloom介绍 Bloom&#xff08;辉光、光晕、泛光&#xff09;是一种常见的摄像机后处理&#xff08;PostProcessing&#xff09;效果&#xff0c;用于再现真实世界相机的成像伪影。这种效果会产生从图像中明亮区域边界延伸的光条纹&#xff08;或羽毛…...

GCC 学习

GCC Resource Center for GCC Internalshttps://www.cse.iitb.ac.in/grc/这是个不错资料网站&#xff0c;有兴趣的可以了解下...

2023数维杯数学建模C题完整版本

已经完成全部版本&#xff0c;获取请查看文末下方名片 摘要 随着人工智能在多个领域的快速发展&#xff0c;其在文本生成上的应用引起了广泛关注。本研究聚焦于辨识人工智能&#xff08;AI&#xff09;生成文本的基本规则&#xff0c;并探究AI文本的检测及其与人类文本的区分…...

快速解密PPT幻灯片密码,让PPT重见天日

最简单的办法解密、找回和去除PPT幻灯片密码&#xff0c;具体步骤如下&#xff1a;1.百度搜索【密码帝官网】&#xff0c;2.点击“立即开始”在用户中心上传要解密的文件稍等片刻&#xff0c;就能找回密码。不用下载软件&#xff0c;手机电脑都可用。而且还支持Word、Excel、PD…...

十六、RabbitMQ快速入门

目录 一、在centos上下载MQ镜像 二、安装运行容器 三、登录进入MQ 1、添加一个新的用户 2、新建虚拟机 3、 为用户分配权限 四、RabbitMQ的基本概念 RabbitMQ中的几个概念: 五、常见消息模型 六、简单的消息生产与消费 1、消费者类 2、生产者类 3、基本消息队列的消…...

C#WPF用户控件及自定义控件实例

本文演示C#WPF自定义控件实例 用户控件(UserControl)和自定义控件(CustomControl)都是对UI控件的一种封装方式,目的都是实现封装后控件的重用。 只不过各自封装的实现方式和使用的场景上存在差异。 1 基于UserControl 创建 创建控件最简单一个方法就是基于UserControl …...

大模型的语言能力

NLP作为一个领域为基础模型开辟了道路。虽然这些模型在标准基准测试中占据主导地位&#xff0c;但这些模型目前获得的能力与那些将语言描述为人类交流和思维的复杂系统的能力之间存在明显的差距。针对这一点&#xff0c;我们强调语言变异的全部范围&#xff08;例如&#xff0c…...

直播岗位认知篇

一、直播岗位概述 直播岗位&#xff0c;也称为直播主播或直播运营&#xff0c;是指在互联网直播平台上进行直播活动的工作岗位。该岗位的主要职责是通过直播形式&#xff0c;向观众展示自己的才艺、分享生活、销售产品或服务&#xff0c;并引导观众互动和参与。直播主播需要具…...

后端技术知识点内容-全部内容-面试宝典-后端面试知识点

文章目录 -2 flink-1 linux of viewlinux查看占用cup最高的10个进程的命令&#xff1b; 〇、分布式锁 & 分布式事务0-1分布式锁--包含CAP理论模型概述分布式锁&#xff1a;分布式锁应该具备哪些条件&#xff1a;分布式锁的业务场景&#xff1a; 分布式锁的实现方式有&#…...

3.ubuntu20.04环境的ros搭建

ros搭建比较简单&#xff0c;主要步骤如下&#xff1a; 1.配置ros软件源&#xff1a; sudo sh -c echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list 2.配置密钥 sudo apt-key adv --keyser…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...