网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
grade=(score>=90)?'A':(score>60)?'B':'C';
printf("分数:%d-等级:%c",score,grade);
}
#### 16、题目:最大公约数和最小公倍数
输入两个正整数m和n,求其最大公约数和最小公倍数。
/*
题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
*/
#include <stdio.h>
int main(){
int m=12,n=26,min,max;
min=m>n?n:m;
max=m>n?m:n;
int common_divisor,common_multiple;
for(int i=1;i<=min;i++){
if((m%i0) && (n%i0)){
common_divisor=i;
}
}
for(int j=max;j<=m*n;j++){
if((j%m0) && (j%n0)){
common_multiple=j;
break; // 找到第一个公约数就关闭循环
}
}
printf(“最大公约数:%d\n最小公倍数:%d\n”,common_divisor,common_multiple);
}
运行结果:
最大公约数:2
最小公倍数:156
### 【2020-10-16】
#### 17、题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
/*
题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
*/
/*
分析:scanf结束符为空格、回车,gets结束符为回车,因此选用gets做输入函数
*/
#include <stdio.h>
#include <string.h>
int main(){
char str[256];
printf(“输入:”);
gets(str);
int str_length,count_ch=0,count_num=0,count_space=0,count_other=0;
str_length=strlen(str);
// 统计
for(int i=0;i<str_length;i++){
// for(int i=0;str[i]!='\0';i++){ // 也可以
if((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z')){ // 字母
count_ch++;
}else if(str[i]>='0'&&str[i]<='9'){ // 数字
count_num++;
}else if(str[i]==' '){
count_space++;
}else{
count_other++;
}
}
printf("字母:%d 个\n",count_ch);
printf("数字:%d 个\n",count_num);
printf("空格:%d 个\n",count_space);
printf("其他:%d 个\n",count_other);
}
运行结果:
输入:I am a student.1 2 3 456 789
字母:11 个
数字:9 个
空格:7 个
其他:1 个
#### 18、题目:求s=a+aa+aaa+aaaa+aa…a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。
/*
题目:求s=a+aa+aaa+aaaa+aa…a的值,其中a是一个数字。
例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。
*/
#include <stdio.h>
// 递归–构造倍数
int multiple(int n){
int result=0;
if(n1){
result=1;
}else if(n2){
result=10;
}else{
result=10*multiple(n-1);
}
return result;
}
// 迭代–构造加数
int addend(int a,int n){
int addend=0;
printf(“\n计算过程 %d:addend=”,n);
for(int i=1;i<=n;i++){
addend=addend+a*multiple(i);
if(i<n){
printf(“%d+”,addend);
}else{
printf(“%d”,addend);
}
}
return addend;
}
int main(){
int a,n,sum=0;
printf(“数字a:”);scanf(“%d”,&a);
printf(“加数个数:”);scanf(“%d”,&n);
for(int i=1;i<=n;i++){
sum=sum+addend(a,i);
}
printf(“\n\n计算结果:%d\n”,sum);
}
运行结果:
数字a:2
加数个数:5
计算过程 1:addend=2
计算过程 2:addend=2+22
计算过程 3:addend=2+22+222
计算过程 4:addend=2+22+222+2222
计算过程 5:addend=2+22+222+2222+22222
计算结果:24690
#### 19、题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。编程找出1000以内的所有完数。例如6=1+2+3.
完全数:它所有的`真因子`(即除了`自身以外`的约数)的和(即因子函数),恰好等于它本身。
/*
题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。编程找出1000以内的所有完数。
例如6=1+2+3.
*/
/* 步骤:1.求出因子;2.求因子之和 */
#include <stdio.h>
int getFactor(int n){
int sum=0;
for(int i=1;i<n;i++){
if(n%i==0){ // 因子
sum=sum+i;
}
}
return sum;
}
int main(){
for(int i=1;i<=1000;i++){
if(getFactor(i)==i){
printf(“********** %d 是完数\n”,i);
}
}
}
运行结果:
********** 6 是完数
********** 28 是完数
********** 496 是完数
### 【2020-10-18】
#### 20、题目:小球自由下落
题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
/*
题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;
再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
*/
/*
分析:每次反弹后,高度减半:1/2HIGH,1/4HIGH,1/8HIGH…
*/
#include <stdio.h>
#define HIGH 100
#define COUNT 10
// 每次反弹高度
float return_high(int n){
float cur_high;
float denominator=1;
for(int i=1;i<=n;i++){
denominator=denominator*2; // 2的n次方
}
cur_high=1/denominator*HIGH;
return cur_high;
}
int main()
{
float sum=HIGH;
for(int i=1;i<=COUNT;i++){
sum=sum+2*return_high(i);
printf(“第 %d 次反弹,反弹后高度为:%f\n”,i,return_high(i));
}
printf(“共经过 %f 米\n”,sum);
}
改进:
/*
分析:每次反弹后,高度减半:HIGH/2,HIGH/4,HIGH/8…
*/
#include <stdio.h>
#define HIGH 100
#define COUNT 10
int main()
{
float sum=HIGH,cur_high=HIGH;
for(int i=1;i<=COUNT;i++){
cur_high=cur_high/2;
sum=sum+2*cur_high;
printf(“第 %d 次反弹,反弹后高度为:%f 米\n”,i,cur_high);
}
printf(“共经过 %f 米\n”,sum);
}
运行结果:
第 1 次反弹,反弹后高度为:50.000000 米
第 2 次反弹,反弹后高度为:25.000000 米
第 3 次反弹,反弹后高度为:12.500000 米
第 4 次反弹,反弹后高度为:6.250000 米
第 5 次反弹,反弹后高度为:3.125000 米
第 6 次反弹,反弹后高度为:1.562500 米
第 7 次反弹,反弹后高度为:0.781250 米
第 8 次反弹,反弹后高度为:0.390625 米
第 9 次反弹,反弹后高度为:0.195312 米
第 10 次反弹,反弹后高度为:0.097656 米
共经过 299.804688 米
#### 21、题目:猴子吃桃问题
题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个
第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下
的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
迭代实现
/*
题目:猴子吃桃问题:
猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。
第二天早上又将剩下的桃子吃掉一半,又多吃了一个。
以后每天早上都吃了前一天剩下的一半零一个。
到第10天早上想再吃时,见只剩下一个桃子了。
求第一天共摘了多少。
*/
#include <stdio.h>
#define DAY 10
int main(){
int total;
for(int i=1;i<=DAY;i++){
if(i==1){
total=1;
}else{
total=2*(total+1);
}
}
printf(“桃子总数: %d 个\n”,total);
}
递归实现:
#include <stdio.h>
#define DAY 10
int peach(int n){
int result;
if(n==1){
result=1;
}else{
result=2*(peach(n-1)+1);
}
return result;
}
int main(){
printf(“桃子总数: %d 个\n”,peach(DAY));
}
运行结果:
桃子总数: 1534 个
#### \*22、题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
答案:
/*
题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。
有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
*/
#include <stdio.h>
int main(){
char a,b,c;
for(a=‘x’;a<=‘z’;a++) {
for(b=‘x’;b<=‘z’;b++) {
if(a!=b) { // 限定:a≠b
for(c=‘x’;c<=‘z’;c++) {
if(a!=c&&b!=c) { // 限定:b≠c
if(a!=‘x’&&c!=‘x’&&c!=‘z’) { // 筛选出满足条件的组合
printf(“顺序为:\na–%c\nb–%c\nc–%c\n”,a,b,c);
}
}
}
}
}
}
}
运行结果:
顺序为:
a–z
b–x
c–y
### 【2020-10-19】
#### \*23、题目:图案打印——菱形
下半部分的模型建立是重点
/*题目:打印菱形*/
#include <stdio.h>
#include <math.h>
int main() {
int row=10,mid;
mid=(row%2==0)?(row/2):(row/2+1);
for(int i=1;i<=row;i++){
for(int j=1;j<=abs(mid-i);j++){
printf(" ");
}
for(int k=1;k<2\*abs(mid-abs(mid-i));k++){
printf("\*");
}
printf("\n");
}
}
运行结果:
\*
***
*****
*******
*********
*******
*****
***
*
#### 24、题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前20项之和。
递归实现:分子、分母分别找规律
/*
题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前20项之和。
*/
#include <stdio.h>
#include <math.h>
#define COUNT 20
float fun(int n,int flag){
float result;
if(n1){
result=flag?1:2; // flag:0-分子,1-分母
}else if(n2){
result=flag?2:3;
}else{
result=fun(n-1,flag)+fun(n-2,flag);
}
return result;
}
int main() {
float sum=0;
for(int i=1;i<=COUNT;i++){
sum=sum+fun(i,0)/fun(i,1);
}
printf(“结果:%f”,sum);
}
迭代实现:按分数找规律——a=a+b,b=a
#include <stdio.h>
#include <math.h>
#define COUNT 20
int main() {
float sum=0,a=2,b=1,temp;
for(int i=1;i<=COUNT;i++){
sum=sum+a/b;
temp=a;
a=a+b;
b=temp;
}
printf(“结果:%f”,sum);
}
运行结果:
结果:32.660263
#### 25、题目:求1+2!+3!+…+20!的和。
递归实现:注意,数据类型需要是`long double`,因为`20!`太大了
/*题目:求1+2!+3!+…+20!的和。*/
#include <stdio.h>
#define COUNT 20
long double fun(int n){
long double result=n;
if(n==1){
result=1;
}else{
result=result*fun(n-1);
}
return result;
}
int main() {
long double sum=0;
// printf(“sum=”);
for(int i=1;i<=COUNT;i++){
sum=sum+fun(i);
// printf(“%LF +”,fun(i));
}
printf(“结果:%LF”,sum);
}
迭代实现:
/*题目:求1+2!+3!+…+20!的和。*/
#include <stdio.h>
#define COUNT 20
int main() {
long double sum=1,temp=1;
// printf(“sum=%LF +”,temp);
for(int i=2;i<=COUNT;i++){
temp=temp*i;
sum=sum+temp;
// printf(“%LF +”,temp);
}
printf(“结果:%LF”,sum);
}
运行结果:
sum=1.000000 +2.000000 +6.000000 +24.000000 +120.000000 +720.000000 +5040.000000 +40320.000000 +362880.000000 +3628800.000000 +39916800.000000 +479001600.000000 +6227020800.000000 +87178291200.000000 +1307674368000.000000 +20922789888000.000000 +355687428096000.000000 +6402373705728000.000000 +121645100408832000.000000 +2432902008176640000.000000
结果:2561327494111820313.000000
### 【2020-10-21】
#### 26、题目:利用递归方法求5!
/*题目:利用递归方法求5!。*/
#include <stdio.h>
// 递归
int recursion(int n){
// int result=n; // 方式一
int result; // 方式二
if(n==1){
result=1;
}else{
// result=result*recursion(n-1); // 方式一
result=n*recursion(n-1); // 方式二
}
return result;
}
// 迭代
int iteration(int n){
int result=1;
for(int i=1;i<=n;i++){
result=result*i;
}
return result;
}
int main() {
printf(“递归:5!=%d\n”,recursion(5));
printf(“迭代:5!=%d\n”,iteration(5));
}
运行结果:
递归:5!=120
迭代:5!=120
#### 27、题目:利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来。
/*题目:利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来。*/
#include <stdio.h>
#include <string.h>
// 递归
void recursion(char *p, int cur){
printf(“%5c”,*p);
if(cur){
recursion(p-1,cur-1);
}
}
// 迭代
void iteration(char str[]){
int length=strlen(str);
for(int i=length-1;i>=0;i–){
printf(“%5c”,str[i]);
}
}
int main() {
char str[]=“abcde”; // 逆序打印
// 递归
char \*p; p=str;
int length=strlen(str);
recursion(p+length-1,length-1);
// 迭代
// iteration(str);
}
运行结果:
e d c b a
#### 28、题目:递归。有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?
/*
题目:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。
问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。
请问第五个人多大?
*/
#include <stdio.h>
#define AMOUNT 5
// 递归
int recursion(int n){
int age;
if(n==1){
age=10;
}else{
age=recursion(n-1)+2;
}
return age;
}
// 迭代
int iteration(int n){
int age=10;
for(int i=2;i<=n;i++){
age+=2;
}
return age;
}
int main() {
printf(“第 %d 个人年龄:%d\n”,AMOUNT,recursion(AMOUNT));
printf(“第 %d 个人年龄:%d\n”,AMOUNT,iteration(AMOUNT));
}
运行结果:
第 5 个人年龄:18
第 5 个人年龄:18
#### \*29、题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。
#include <stdio.h>
int main() {
int num;
do{ // 限制输入数据大小
printf(“输入:”);scanf(“%d”,&num);
}while(num>100000);
printf(“逆序打印:”);
int count=0;
for(int i=num;i>0;i=i/10){ // 注意:i!=0,需要i>0
count++;
printf(“%d “,i%10);
}
printf(”\n%d 位数\n”,count);
}
输入:512
逆序打印:2 1 5
3 位数
#include <stdio.h>
int main() {
int num;
do{
printf(“输入:”);scanf(“%d”,&num);
}while(num>100000);
printf(“逆序打印:”);
int count=0,a,b;
while(num){
a=num/10;
b=num%10; // 个位
if(a||b){
count++;
printf(“%2d”,b); // 末位
}
//if(num>10){ // 注意:不能限制num>10
num=num/10; // 每次减去末位
//}
}
printf(“\n%d 位数\n”,count);
}
### 【2020-10-22】
#### \*30、题目:回文数,首尾比较
题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
/*
题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
*/
#include <stdio.h>
// 判断是几位数
int num_length(int num){
int length=0;
for(int i=num;i>0;i=i/10){
if(i>10){
length++;
}
}
return length;
}
// 判断是几位数
int member_hunder(int num){
int result=1;
for(int j=1;j<=num_length(num);j++){
result=result*10;
}
return result; // 整十、百、签……
}
// 判断回文数:首尾数字比较
void iteration(int num){
int first,last; // 记录首尾数字
int flag1=num,flag2=num,flag=0; // flag用于统计首尾相同的次数;flag1用于从后往前逐位推进,flag2用于从前往后逐位推进
while(flag1){
last=flag1%10;
first=flag2/member\_hunder(flag2);
if(first==last){
flag++;
printf("首:%d = 尾:%d\n",first,last);
}
flag1=flag1/10; // 后→前
flag2=flag2-flag2/member\_hunder(flag2)\*member\_hunder(flag2); // 前→后
// printf("flag1=%d,flag2=%d\n\n",flag1,flag2);
}
printf("匹配对数=%d,数值长度=%d\n",flag,num\_length(num)+1);
if(flag>=(num\_length(num))){
printf("%d 是回文数\n",num);
}else{
printf("%d 非回文数\n",num);
}
}
int main() {
int num=12321;
iteration(num);
}
运行结果:
首:1 = 尾:1
首:2 = 尾:2
首:3 = 尾:3
首:2 = 尾:2
首:1 = 尾:1
匹配对数=5,数值长度=5
12321 是回文数
使用 `for` 循环:
// 判断回文数:首尾数字比较
void iteration(int num){
int first,last;
int mid=(getLength(num)%2==0?getLength(num)/2:getLength(num)/2+1);
int flag1=num,flag2=num,flag=0; // flag用于统计首尾相同的次数
for(int i=1;i<=mid;i++){
last=flag1%10;
first=flag2/memberHundred(flag2);
if(first==last){
flag++;
// printf("首:%d = 尾:%d\n",first,last);
}
flag1=flag1/10; // 后→前
flag2=flag2-flag2/memberHundred(flag2)\*memberHundred(flag2); // 前→后
// printf("flag1=%d,flag2=%d\n\n",flag1,flag2);
}
printf("匹配对数=%d,数值长度=%d\n",flag,getLength(num)+1);
if(flag>=mid){
printf("%d 是回文数\n",num);
}else{
printf("%d 非回文数\n",num);
}
}
需要用到两组变化,第一组:前→后;第二组:后→前
第一组每次获取最高位数字,第二组每次获取最低位数字
last=flag1%10; // 获取低位数字(首位)
first=flag2/memberHundred(flag2); // 获取高位数字(末位)
| 变化次数 | 前→后 | 后→前 |
| --- | --- | --- |
| 0 | 512 | 512 |
| 1 | 12 | 51 |
| 2 | 2 | 5 |
#### \*31、题目:逐字比较
题目:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母。
#include <stdio.h>
#include <string.h>
struct week{
char dayStr[20];
}day[7]={{“monday”},{“tuesday”},{“wednesday”},{“thursday”},{“friday”},{“saturday”},{“sunday”}},tempDay[3];
int compare(int index){ // index:当前比较的是第 index 个字符
char firstCh;
printf(“输入第 %d 个字母:”,index+1);
scanf(“%c”,&firstCh);
printf(“%c\n”,firstCh);
int count=0;char temp[20];
for(int i=0;i<7;i++){
if(index==0){
strcpy(temp,day[i].dayStr); // 取出星期i
}else{
strcpy(temp,tempDay[i].dayStr); // 二次比较,取出星期i
}
if(firstCh==temp[index]){ // 字符比较
strcpy(tempDay[count].dayStr,temp); // 存储所有满足条件的星期i,二次比较的时候从这个数组中选取
count++; // 满足条件的星期i的个数,大于1就继续二次输入
// strcpy(tempDay[count].dayStr,""); // 将原数组中的末尾设置为结束
}
}
fflush(stdin); // 清空输入缓冲区
// tempDay记录打印
for(int k=0;k<2;k++){
printf("%s\n",tempDay[k].dayStr);
}
return count;
}
int main() {
int count;
count=compare(0);
if(count==1){
printf(“对应:%s\n”,tempDay[0].dayStr);
}else if(count>1){
count=compare(1);
printf(“对应:%s\n”,tempDay[0].dayStr);
}
}
运行结果:
输入第 1 个字母:m
对应:monday
输入第 1 个字母:w
对应:wednesday
输入第 1 个字母:f
对应:friday
输入第 1 个字母:t
tuesday,thursday
输入第 2 个字母:h
thursday
对应:thursday
输入第 1 个字母:t
tuesday,thursday
输入第 2 个字母:u
tuesday,thursday //
对应:tuesday
输入第 1 个字母:s
saturday,sunday
输入第 2 个字母:u
sunday
对应:sunday
输入第 1 个字母:s
saturday,sunday
输入第 2 个字母:a
saturday,sunday // 原因在于没有清缓存,数组缓存。但是并不影响,因为每次会把符合条件的放在前面
对应:saturday
###### 注意——清空输入缓冲区`fflush(stdin);`
1、不能用枚举,要用结构体
分析:不能用枚举,因为枚举的每个元素对应的是0,1,2…数字
// enum week{monday,tuesday,wednesday,thursday,friday,saturday,sunday} day;
struct week{
char dayStr[20];
}day[7]={{“monday”},{“tuesday”},{“wednesday”},{“thursday”},{“friday”},{“saturday”},{“sunday”}};
2、bug 解决
* 问题:第二次`scanf`无效
* 原因:第一次输入的回车,在第二次执行时被赋值给变量
* 解决方法:清空输入缓冲区,清除掉回车`fflush(stdin);`
>
> 参考:<https://blog.csdn.net/qq_26768741/article/details/50933598>
>
>
>
### 【2020-10-23】
#### 32、题目:删除指定字母
题目:删除一个字符串中的指定字母,如:字符串 “aca”,删除其中的 a 字母。
#include <stdio.h>
#include <string.h>
int main() {
char str[200];
printf(“目标字符串:”);gets(str);
char ch;
printf(“删除字母:”);ch=getchar();
int count=0;
for(int i=0;str[i];i++){
if(ch!=str[i]){
str[count++]=str[i];
}
}
str[count]='\0'; // 结束符
printf("%s\n",str);
}
运行结果:
目标字符串:aca
删除字母:a
结果:c
###### 注意——gets()函数有参数,getchar()函数无参数
1.字符串:gets()函数有参数
char str[10];
gets(str);
2.字符:getchar()函数无参数
char ch=getchar();
#### 33、题目:质数/素数
题目:判断一个数字是否为质数。
#include <stdio.h>
int main() {
int num,flag=1;
printf(“输入数值:”);scanf(“%d”,&num);
int mid=(num%2==0)?(num/2):(num/2+1);
for(int i=2;i<mid;i++){
if(num%i==0){
flag=0;
break;
}
}
if(flag){
printf("%d 是质数\n",num);
}else{
printf("%d 不是质数\n",num);
}
}
#### \*35、题目:字符串反转 / 字符串逆序
题目:如将字符串 “www.runoob.com” 反转为 “moc.boonur.www”。
###### 1、下标法:时间复杂度 o(n)
#include <stdio.h>
#include <string.h>
int main() {
char str[]=“www.runoob.com”;
// printf(“输入字符串:”);gets(str);
int length=strlen(str);
char tempStr[length];
for(int i=0;i<length;i++){
tempStr[i]=str[length-1-i];
}
strcpy(str,tempStr); // 字符串复制,参数2复制到参数1
printf("反转后:%s\n",str);
}
运行结果:
反转后:moc.boonur.www
###### 2、指针法:时间复杂度 o(1)
#include <stdio.h>
#include <string.h>
int main() {
char str[]=“www.runoob.com”;
int length=strlen(str);int changeAmount=length/2; // 交换次数
char \*front,\*later;
char temp; // 临时空间——注意,不能是 char \*temp; 因为temp是没有初始值的,所以使用\*temp时找不到数据
front=str; // 首地址
later=str+length-1; // 尾地址
for(int i=0;i<changeAmount;i++){
temp=\*later;
\*later=\*front;
\*front=temp;
front++;
later--;
}
printf("反转后:%s\n",str);
}
字符串操作:
追加元素
删除元素
修改元素
元素排序
元素反转
1.空间复杂度o(0)——在原数组上操作
删除元素
追加元素
修改元素
2.空间复杂度o()——开辟临时空间
元素排序:插入排序/冒泡o(1),
元素反转:o(n)
###### 注意——开辟临时空间 temp 时,temp 的数据类型不能是指针
因为 temp 没有初始值,那么 \*temp 无法找到对应的地址来存放临时数据
### 【2020-10-24】
#### \*37、题目:排序
题目:对10个数进行排序。
#include <stdio.h>
int nums[10]={23,2,27,98,234,1,4,90,8,34};
// 插入排序
void insertSort(int arr[]){
int temp;
for(int i=0;arr[i];i++){
for(int j=i+1;arr[j];j++){
if(arr[j]<arr[i]){
temp=arr[j];
arr[j]=arr[i];
arr[i]=temp;
}
}
}
}
// 输入
void scanfArr(){
printf(“输入:”);
for(int i=0;i<10;i++){
scanf(“%d”,&nums[i]);
}
}
// 打印排序后的数组
void printArr(){
printf(“排序后:”);
for(int i=0;nums[i];i++){
printf(“%d “,nums[i]);
}
printf(”\n”);
}
int main() {
scanfArr();
insertSort(nums);
printArr();
}
运行结果:
输入:23 2 27 98 234 1 4 90 88 34
排序:1 2 4 23 27 34 88 90 98 234
###### 37.1 选择排序 o(n2)–找出最小,一次交换
// 选择排序
void selectSort(int arr[]){
int temp,min;
for(int i=0;arr[i];i++){
min=i; // 最小值的下标
for(int j=i+1;arr[j];j++){
if(arr[j]<arr[min]){
min=j; // 找到最小值下标
}
}
if(min!=i){ // 最小值下标改变
temp=arr[min]; // 当前元素和最小元素交换,最小的放前面
arr[min]=arr[i];
arr[i]=temp;
}
}
}
###### 37.2 插入排序 o(n2)–相邻比较,相邻交换,同步交换下标
// 插入排序
void insertSort(int arr[]){
int temp,min;
for(int i=1;arr[i];i++){
min=i;
for(int j=i-1;j>=0;j–){
if(arr[min]<arr[j]){
temp=arr[j]; // 遇到比自己小的就交换,同时自己的下标同步修改
arr[j]=arr[min];
arr[min]=temp;
min=j;
}
}
}
}
###### 37.3 冒泡排序 o(n2)–相邻比较,相邻交换
不符合冒泡排序定义
// 冒泡排序(注释部分为优化)
void bubbleSort(int arr[]){
int temp;
// int isSort=1;
for(int i=0;arr[i];i++){
// isSort=1;
for(int j=i+1;arr[j];j++){
if(arr[j]<arr[i]){
temp=arr[j];
arr[j]=arr[i];
arr[i]=temp;
// isSort=0;
}
}
// if(isSort){
// break; // 没有变动,已经有序,结束此后的外循环
// }
}
}
符合冒泡排序定义,两两比较相邻元素:相邻比较,相邻交换
// 冒泡排序(注释部分为优化)
void bubbleSort(int arr[],int n){
int temp;
// int isSort=1;
for(int i=0;i<n;i++){
// isSort=1;
for(int j=n-1;j>i;j–){
if(arr[j-1]<arr[j]){
temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
// isSort=0;
}
}
// if(isSort){
// break; // 没有变动,已经有序,结束此后的外循环
// }
}
}
###### 37.4 希尔排序 o(n2\*logn)–按步长gap分组,组内冒泡
// 希尔排序(插入排序的变种)
void shellSort(int arr[]){
// 数组长度
int length=0;
for(int i=0;arr[i];i++){
length++;
}
// 排序
int temp;
int gap=length/2;
while(gap){
for(int j=0;j<length/gap;j++){ // 每组个数
for(int k=j+gap;arr[k];k=k+gap){ // 组内排序
if(arr[k]<arr[j]){
temp=arr[j];
arr[j]=arr[k];
arr[k]=temp;
}
}
}
gap=gap/2;
}
}
###### 37.5 归并排序
思想
1、递归分割:两两分割
分割数组为小数组,直至小数组为单元素数组
2、递归合并:两两合并
相邻数组合并
合并时排序
#### 38、题目:矩阵对角线元素之和
题目:求一个3\*3矩阵对角线元素之和
#include <stdio.h>
#define RANK 3 // 阶数
int arr[RANK][RANK]={
1,2,3,
4,5,6,
7,8,9
};
int main() {
int sum=0;
for(int i=0;i<RANK;i++){
sum=sum+arr[i][i];
}
printf(“对角线之和=%d\n”,sum);
}
对角线之和=15
#### \*39、题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。
#include <stdio.h>
#define LENGTH 5
int main() {
// int arr[LENGTH]={1,2,8,9};
int arr[LENGTH]={9,8,2,1};
int num=3;
int flag=-1;
// 1.查找插入位置
for(int i=1;i<LENGTH;i++){
if((num>arr[i-1]&&num<arr[i])||(num<arr[i-1]&&num>arr[i])){
flag=i; // 标记插入位置
}
}
if(flag>=0){
// 2.元素右移,为插入留位置
for(int j=LENGTH-1;j>=flag;j–){
arr[j]=arr[j-1];
}
// 3.插入
arr[flag]=num;
}
void printArr(int arr[]);
printArr(arr);
}
void printArr(int arr[]){
printf(“插入后数组:”);
for(int i=0;i<LENGTH;i++){
printf(“%d “,arr[i]);
}
printf(”\n”);
}
插入后数组:1 2 3 8 9
### 【2020-10-25】
#### 40、题目:数组逆序打印
###### 40.1 逆序输出(不改变数组顺序)
题目:将一个数组逆序输出。
/*
题目:将一个数组逆序输出。
*/
#include <stdio.h>
#define LENGTH 5
int arr[LENGTH]={9,8,2,1};
// 1.下标法 时间复杂度o(n)
void byIndex(){
// 数组长度
int length=0;
for(int i=0;i<LENGTH;i++){
length++;
}
for(int i=length-1;i>=0;i--){
printf("%d ",arr[i]);
}
}
// 2.指针法 时间复杂度o(n)
void byPoint(){
// 数组长度
int length=0;
for(int i=0;i<LENGTH;i++){
length++;
}
int \*front; // 首指针
front=arr+length-1; // 尾地址赋值给首指针
int \*i;
for(i=front;i>=arr;i--){
printf("%d ",\*i); // 输出
}
}
// 数组打印
void printArr(){
for(int i=0;i<LENGTH;i++){
printf("%d ",arr[i]);
}
}
int main() {
printf(“逆序打印(下标法):”);
byIndex();
printf(“\n逆序打印(指针法):”);
byPoint();
printf("\n数组顺序(不变):");
printArr();
}
运行结果:
逆序打印(下标法):0 1 2 8 9
逆序打印(指针法):0 1 2 8 9
数组顺序(不变):9 8 2 1 0
###### 40.2 数组逆序(改变数组顺序)
/*
题目:将一个数组逆序。
*/
#include <stdio.h>
#define LENGTH 5
int arr[LENGTH]={9,8,2,1};
// 数组打印
void printArr(){
for(int i=0;i<LENGTH;i++){
printf("%d ",arr[i]);
}
}
// 1.下标法 时间复杂度o(n)
void byIndex(){
int temp;
int mid=(LENGTH-1)/2;
for(int i=0;i<mid;i++){
temp=arr[i];
arr[i]=arr[LENGTH-1-i];
arr[LENGTH-1-i]=temp;
}
}
// 2.指针法-迭代法:交换首尾数据 时间复杂度o(n)
void byPoint(){
int temp_1;int *temp_2;
int *front,*later;
front=arr;
later=arr+LENGTH-1;
int mid=LENGTH/2; // 交换次数
for(int i=1;i<=mid;i++){ // 前后交换数据
temp_1=\*front;
\*front=\*later;
\*later=temp_1;
front++;
later--;
}
}
int main() {
printArr();
printf("\n逆序(下标法):");
byIndex();
printArr();
printf("\n逆序(指针法):");
byPoint();
printArr();
}
运行结果:
9 8 2 1 0
逆序(下标法):0 1 2 8 9
逆序(指针法):9 8 2 1 0
###### 注意——数组逆序操作,只能交换数据,不能交换地址??——因为地址是常量
// 2.指针法-迭代法:交换首尾指针 时间复杂度o(n)
void byPoint(){
int temp_1;int *temp_2;
int *front,*later;
front=arr;
later=arr+LENGTH-1;
int mid=LENGTH/2; // 交换次数
// for(int i=1;i<=mid;i++){ // 前后交换数据--正确
// temp\_1=\*front;
// \*front=\*later;
// \*later=temp\_1;
// front++;
// later--;
// }
for(int i=1;i<=mid;i++){ // 前后交换地址--无效
if(i==1){
temp_2=front;
front=later;
later=temp_2;
}else{
front=front-1;
later=later+1;
}
}
}
#### 41、for循环条件中定义的变量的作用范围
>
> * 循环条件中定义的变量 i 只在当前 for 循环中(作用域{})有效
> * 同一个函数内,多个 for 循环中可以分别定义 i 为变量——因为 i 的作用范围为当前 for 循环
>
>
>
#include <stdio.h>
int main() {
for(int i=0;i<3;i++){
int a=1;
printf("%d “,a);
}
for(int j=0;j<3;j++){
i=10; // 报错:i 没有定义 → i 只在上面的for中(定义的{}中)有效
printf(”%d ",i);
}
}
同一个函数内,多个 for 循环中可以分别定义 i 为变量——因为 i 的作用范围为当前 for 循环。如下:
#include <stdio.h>
int main() {
for(int i=0;i<3;i++){
int a=1;
printf(“a=%d\n”,a);
}
for(int i=0;i<3;i++){
int b=10;
printf(“b=%d\n”,b);
}
}
#### 41、static定义静态变量的用法
* 用法一:保持调用数据
函数调用之后,static变量会保持调用结束的数据,下次调用时继续使用
* 用法二:内置模块
互不相干
#include <stdio.h>
int main(){
int i,num;
num=2;
for(i=0;i<3;i++){
printf(“num 变量为 %d \n”,num);
num++;
{
static int num=1;
printf(“内置模块 num 变量为 %d\n”,num);
num++;
}
}
return 0;
}
#### 43、内置模块——可嵌入的独立作用域
>
> * 内置模块中的变量和内置模块外的变量互不相干
> * 内置模块中的变量作用域只在内部模块中
>
>
>
/*
内置模块
*/
#include <stdio.h>
int main(){
int num=2;
// static int num=2;
for(int i=0;i<3;i++){
printf(“函数中:num=%d \n”,num);num++;
{
int num=1;
// static int num=1;
printf(“函数内置模块中:num=%d\n”,num);num++; // 内置模块中的变量作用域只有内部模块
}
}
printf(“\nnum=%d\n”,num); // 是函数中的num
}
函数中:num=2
函数内置模块中:num=1
函数中:num=3
函数内置模块中:num=1
函数中:num=4
函数内置模块中:num=1
num=5
#### 44、external的用法
### 【2020-10-26】
#### 45、register的用法
* 寄存器变量。存放在寄存器中,而非内存中
* 不能用 & 来获取地址
* 只能是单个的值(不能是数组),并且长度<=整型的长度
* 只有auto变量和形参可以做寄存器变量
* 寄存器只用于需要快速访问的变量,比如计数器
#### 46、宏 #define
宏可以定义:
* 全局变量
* 表达式
* 函数(注意,不能换行)
* 比较规则(>、<、==)
1、定义函数
#include <stdio.h>
#define exchange(a,b) { int t;t=a;a=b;b=t;} //注意放在一行里
int main(){
int x=10,y=20;
exchange(x,y);
printf(“交换后:x=%d, y=%d\n”,x,y);
}
运行结果:
交换后:x=20, y=10
2、定义规则
#include <stdio.h>
#define LAG >
#define SMA <
#define EQ ==
int main(){
int i=1,j=2;
if(i LAG j)
printf(“%d 大于 %d \n”,i,j);
else if(i EQ j)
printf(“%d 等于 %d \n”,i,j);
else if(i SMA j)
printf(“%d 小于 %d \n”,i,j);
else
printf(“没有值。\n”);
}
运行结果:
1 小于 2
#### 49、#if、#ifdef、#ifndef
| 语句 | 含义 |
| --- | --- |
| #define | 宏定义 |
| #ifdef | 如果已经存在宏定义 |
| #ifndef | 如果没有该宏定义 |
| #endif | 结束条件语句 |
| #undef | 取消宏定义 |
| #define | 宏定义 |
#include<stdio.h>
#define MAX
#define MAXIMUM(x,y)(x>y)?x:y
#define MINIMUM(x,y) (x>y)?y:x
int main(){
// 1.如果已经定义了MAX
#ifdef MAX
printf(“更大的数字是 %d\n”,MAXIMUM(a,b)); // 如果已经定义了MAX,执行这一条
#else
printf(“更小的数字是 %d\n”,MINIMUM(a,b));
#endif // 结束条件语句
// 2.如果没有定义
#ifndef MIN
printf("更小的数字是 %d\n",MINIMUM(a,b));// 如果没有定义MIN,执行这一条
#else
printf("更大的数字是 %d\n",MAXIMUM(a,b));
#endif
// 3.取消宏定义
#undef MAX
#ifdef MAX
printf("更大的数字是 %d\n",MAXIMUM(a,b));
#else
printf("更小的数字是 %d\n",MINIMUM(a,b));
#endif
// 4.定义宏
#define MIN
#ifndef MIN
printf("更小的数字是 %d\n",MINIMUM(a,b));
#else
printf("更大的数字是 %d\n",MAXIMUM(a,b));
#endif
}
运行结果:
更大的数字是 20
更小的数字是 10
更小的数字是 10
更大的数字是 20
#### 51、按位与运算 &、按位或运算 |、按位异或运算 ^
#### 54、题目:取一个整数 a 从右端开始的 4~7 位
>
> 答案:<https://www.runoob.com/cprogramming/c-exercise-example54.html>
>
>
>
/*
题目:取一个整数 a 从右端开始的 4~7 位。
*/
/*
分析:十进制→二进制→移位
需要获取移出的位,方法:将移位后的数值和某一个数(1111B=7)做按位与(同1为1),即可得到4-7位
*/
#include <stdio.h>
int main(){
int num=36,result,temp,t=7;
temp=num>>4;
result=temp&t;
printf("%d\n",result);
}
运行结果:
结果:2
2=0010B
#### 53、按位取反~
0取反为-1
1取反为-2
-1取反为0
-2取反为1
#include <stdio.h>
int main(){
int num=2,temp;
temp=~num;
printf("%d\n",temp);
printf("%x\n",temp);
}
结果:-3
fffffffd
num=2=0000 0010B
取反:0000 0010B → 1111 1101B(补码)→ 1000 0011B(原码)=-3
所以,2取反为-3
#### \*\*56、画图——画圆
题目:画图,学用circle画圆形
/*
题目:画圆。
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
// 圆:R*R=x*x+y*y
void circle(){
double y,m;
int x;
for(y=10;y>=-10;y–){ //圆的半径为10
m=2.5*sqrt(100-y*y); //计算行y对应的列坐标m,2.5为屏幕纵横比调节系数,
//屏幕的行距大于列距,不调节会是椭圆
for(x=1;x<30-m;x++){
printf(" “); //图形左侧空白控制
}
printf(”*“); //圆的左侧
for(;x<30+m;x++){
printf(” “);
}
printf(” * \n"); //圆的右侧
}
}
void quxian(){
double y;
int x, m;
for (y = 1; y >= -1;y-=0.1) //y为列方向,值从1到-1,步长为0.1
{
m = acos(y) * 10; //计算出y对应的弧度m,乘10为图像扩大倍数
for (x = 1; x < m;x++)
{
printf(" “);
}
printf(”*“); //控制打印左侧的*号
for (; x < 62 - m;x++)
{
printf(” “);
}
printf(”*\n"); //控制打印同一行中对称的右侧的*号
}
}
int main(){
circle();
quxian();
}
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
// 圆:R*R=x*x+y*y
void circle(){
double y,m;
int x;
for(y=5;y>=-5;y–){ //圆的半径为5
m=2.5*sqrt(25-y*y); //计算行y对应的列坐标m,2.5为屏幕纵横比调节系数–屏幕的行距大于列距,不调节会是椭圆
for(x=1;x<15-m;x++){
printf(" “); //图形左侧空白控制
}
printf(”*“); //圆的左侧
for(;x<15+m;x++){
printf(” “);
}
printf(” * \n"); //圆的右侧
}
}
int main(){
circle();
}
\* \*
\* \*
\* \*
* *
* *
* *
* *
* *
* *
* *
* *
#### 57、画图——画直线
#### 58、画图——画长方形
#### \*61、题目:杨辉三角形
题目:打印出杨辉三角形(要求打印出10行)。
二元数组
找好规律
/*
题目:打印出杨辉三角形(要求打印出10行)。
*/
/*
二元数组
*/
#include <stdio.h>
int main(){
int row=10;
int arr[row][row];
for(int i=0;i<row;i++){
arr[i][0]=1;
arr[i][i]=1;
}
for(int i=2;i<row;i++){
for(int j=1;j<i;j++){
arr[i][j]=arr[i-1][j-1]+arr[i-1][j]; // 重点
}
}
for(int i=0;i<row;i++){
for(int j=0;j<=i;j++){
printf("%3d ",arr[i][j]);
}
printf("\n");
}
}
运行结果:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
### 【2020-10-28】
#### \*66、实现 swap() 函数
通过函数调用进行数据交换时,交换形参并不能实现实参的交换,幼通过`交换地址`来实现实参交换
/*
题目:输入3个数a,b,c,按大小顺序输出。
*/
#include <stdio.h>
void swap(int m,int n){
int temp;
temp=n;
n=m;
m=temp;
printf(“change:m=%d,n=%d\n”,m,n);
}
int main(){
int a=10,b=11;
if(a<b){
swap(a,b);
}
printf("a=%d,b=%d",a,b);
}
change:m=11,n=10
a=10,b=11
通过地址:交换成功
#include <stdio.h>
void swap(int *m,int *n){
int temp;
temp=*n;
*n=*m;
*m=temp;
printf(“change:m=%d,n=%d\n”,*m,*n);
}
int main(){
int a=10,b=11;
int *p1,*p2;
p1=&a;
p2=&b;
if(a<b){
swap(p1,p2);
}
printf("a=%d,b=%d",a,b);
}
change:m=11,n=10
a=11,b=10
#### \*?\*67、题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
/*
题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
*/
#include <stdio.h>
#define LENGTH 5
void printArr(int arr[]){
for(int j=0;arr[j];j++){
printf(“%d “,arr[j]);
}
printf(”\n”);
}
int main(){
int arr[LENGTH]={1,3,5,7,9};
printArr(arr);
int min=arr[0],max=arr[0];
int minFlag=0,maxFlag=0,temp,temp2;
for(int i=0;arr[i];i++){
if(min>arr[i]){
min=arr[i];
minFlag=i;
}
if(max<arr[i]){
max=arr[i];
maxFlag=i;
}
}
printf("maxFlag=%d,minFlag=%d\n",maxFlag,minFlag);
if(minFlag==0&&maxFlag==LENGTH-1){
temp=arr[0];
arr[0]=arr[LENGTH-1];
arr[LENGTH-1]=temp;
}else{ // 1、2不能交换顺序
// 1
temp2=arr[LENGTH-1];
arr[LENGTH-1]=arr[minFlag];
arr[minFlag]=temp2;
// 2
temp=arr[0];
arr[0]=arr[maxFlag];
arr[maxFlag]=temp;
arr[LENGTH]='\0'; // 需要设置结束符,否则会越界?
// 又没问题了
}
printArr(arr);
}
1 3 5 7 9
maxFlag=4,minFlag=0
9 3 5 7 1
#### 疑问:数组打印越界问题
>
> 解答:
> 只适用于字符串数组,不能是字符数组,也不能是其他数组。
> 编译器不检查数组下标的合法性。
>
>
>
使用 `array[i]` 做控制条件,出现问题
#include <stdio.h>
int main(){
int array[]={1,2,3};
for(int i=0;array[i];i++){
printf(“下标:%d”,i);
printf(“数据:%d\n”,array[i]);
}
}
下标:0数据:1
下标:1数据:2
下标:2数据:3
下标:3数据:1703792
下标:4数据:4199129
下标:5数据:1
下标:6数据:34411544
下标:7数据:34411680
下标:8数据:4198896
下标:9数据:4198896
下标:10数据:2297856
### 【2020-11-4】
#### \*\*68、题目:有 n个整数,使其前面各数顺序向后移 m 个位置,最后m个数变成最前面的 m 个数。
###### 下标方式:元素备份
时间复杂度:o(n)
空间复杂度:o(n)
/*
题目:有 n 个整数,使其前面各数顺序向后移 m 个位置,最后 m 个数变成最前面的 m 个数。
*/
/*
类似于循环移位
*/
#include <stdio.h>
#define LENGTH 7
#define MOVE 4
// 1.时间复杂度o(n),空间复杂度o(n)——建立备份
void moveArr(int arr[],int length,int move){
int temp[MOVE],index=0;
// 1.备份
for(int i=length-move;i<length;i++){
temp[index++]=arr[i];
}
printf(“temp数组:”);
for(int q=0;q<MOVE;q++){
printf("%d ",temp[q]);
}
// 2.移动
for(int j=length-move;j>=0;j–){
arr[j+move]=arr[j];
}
// 3.备份填充
for(int k=0;k<move;k++){
arr[move-k-1]=temp[k];
}
// 结果
printf("\n结果:");
for(int p=0;p<length;p++){
printf("%d ",arr[p]);
}
}
int main(){
int arr[LENGTH]={1,2,3,4,5,6,7};
moveArr(arr,LENGTH,MOVE);
}
temp数组:4 5 6 7
结果:7 6 5 4 1 2 3
###### 指针方式:元素滚动
时间复杂度:o(n2)
空间复杂度:o(n)
思路:
1.每轮滚动移出一个元素(存放在尾地址的下一个地址中)
2.每轮滚动结束,将移出的元素放到首地址中
多次滚动即可实现
实现分析:
整个过程数组 array 的首地址是不变的
通过*array=last;改变首地址存放的的元素数据
#include <stdio.h>
#include <stdlib.h>
// 滚动数组
void move(int array[],int n,int offset){
int *p,*arr_end,last;
arr_end=array+n; // 数组最后一个元素的下一个位置,用于地址滚动(临时空间,o(1))
while(offset){ // 滚动直到偏移量为0
last=\*(arr_end-1); // 绝对位置/地址保持不变
for(p=arr_end;p!=array;p--){
\*p=\*(p-1); // 逐个向右滚动一位→一轮之后,数组元素整体向右移动一个位置,数组首地址保持不变
// printf("%d ",\*p);
}
\*array=last; // 移出的元素存放到首地址中
offset--;
printf("\nlast=%d,\*array=%d\n",last,\*array);
}
/\*
分析:整个过程array指向的首地址是不变的
*array=last;改变了首地址的元素数据,而不是改变array的指向地址
思路:
1.每轮滚动移出一个元素(存放在arr_end指向的地址中)
2.每轮滚动结束,将移出的元素重新放到首地址中
*/
}
int main(){
int arr[7]={1,2,3,4,5,6,7};
int n=7,offset=3; // offset:移动次数
move(arr,n,offset);
for(int i=0;i<n;++i) printf("%4d",arr[i]);
printf("\n");
}
7 6 5 4 3 2 1 // 倒序
*array=7
6 5 4 3 2 1 7
*array=6
5 4 3 2 1 7 6 // 倒序。正序为:6 7 1 2 3 4 5
*array=5
5 6 7 1 2 3 4
#### 69、题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
/*
题目:有n个人围成一圈,顺序排号。
从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
*/
#include <stdio.h>
#define ACCOUNT 10
int main(){
// 初始编号
int sign[ACCOUNT],count;
for(int i=1;i<=ACCOUNT;i++){
sign[i-1]=i;
}
for(int j=1;j<=ACCOUNT;j++){
if(j%3==0){
sign[j-1]=0; // 0:退出圈子
printf(“%d 退出圈子\n”,j);
}
}
printf(“留下的人:\n”);
for(int k=0;k<ACCOUNT;k++){
if(sign[k]){
printf(“原 %d 号\n”,sign[k]);
}
}
}
3 退出圈子
6 退出圈子
9 退出圈子
留下的人:
原 1 号
原 2 号
原 4 号
原 5 号
原 7 号
原 8 号
原 10 号
#### \*\*69、题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,直到剩余一个人,问最后留下的是原来第几号的那位。
不循环,每次从头开始
/*
题目:有n个人围成一圈,顺序排号。
从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
*/
#include <stdio.h>
#define ACCOUNT 10
int main(){
// 初始编号
int sign[ACCOUNT];
for(int i=1;i<=ACCOUNT;i++){
sign[i-1]=i;
}
// 循环报数
int remainNum,roundTime=1;
do{
remainNum=0;
printf("第 %d 轮\n",roundTime);
int count=1; // 报数
// 退出
printf("退出:");
for(int j=0;j<ACCOUNT;j++){
if(sign[j]){
if(count%3==0){
sign[j]=0;
printf("%d ",j+1);
}
count++;
}
}
// 剩余
printf("\n剩余:");
for(int k=0;k<ACCOUNT;k++){
if(sign[k]){
remainNum++;
printf("%d ",sign[k]);
}
}
printf("\n");
roundTime++;
printf("剩余人数:%d\n",remainNum);
}while(remainNum>2);
}
第 1 轮
退出:3 6 9
剩余:1 2 4 5 7 8 10
剩余人数:7
第 2 轮
退出:4 8
剩余:1 2 5 7 10
剩余人数:5
第 3 轮
退出:5
剩余:1 2 7 10
剩余人数:4
第 4 轮
退出:7
剩余:1 2 10
剩余人数:3
第 5 轮
退出:10
剩余:1 2
剩余人数:2
###### 循环,按圆继续报数
#include <stdio.h>
#define ACCOUNT 10
int main(){
// 初始编号
int sign[ACCOUNT];
for(int i=1;i<=ACCOUNT;i++){
sign[i-1]=i;
}
// 循环报数
int remainNum,roundTime=1,lastOut=0;
int count=1; // 报数 // 重要
do{
remainNum=0;
printf("第 %d 轮\n",roundTime);
printf("lastOut=%d\n",lastOut);
// 退出
printf("退出:");
for(int j=lastOut;j<ACCOUNT;j++){
if(sign[j]){
if(count%3==0){
sign[j]=0;
printf("%d ",j+1);
}
count++;
lastOut=(j==(ACCOUNT-1))?0:(j+1); // 重要【语句位置】
}
}
// 剩余
printf("\n剩余:");
for(int k=0;k<ACCOUNT;k++){
if(sign[k]){
remainNum++;
printf("%d ",sign[k]);
}
}
printf("\n");
roundTime++;
printf("剩余人数:%d\n\n",remainNum);
}while(remainNum>1);
}
第 1 轮
退出:3 6 9
剩余:1 2 4 5 7 8 10
剩余人数:7
第 2 轮
退出:2 7
剩余:1 4 5 8 10
剩余人数:5
第 3 轮
退出:1 8
剩余:4 5 10
剩余人数:3
第 4 轮
退出:5
剩余:4 10
剩余人数:2
第 5 轮
退出:10
剩余:4
剩余人数:1
### 【2020-11-6】
#### 70、题目:统计字符串长度【数组指针做函数返回值】
/*
题目:写一个函数,求一个字符串的长度,在 main 函数中输入字符串,并输出其长度。
*/
#include <stdio.h>
#include <string.h>
// 1.输入字符串
char * inputStr(){
char str[256]; // 声明字符串数组
printf(“输入字符串:”);
gets(str);
return str;
}
// 2.统计长度
int getLength(char string[]){
int length=0;
for(int i=0;string[i];i++){ // 循环条件:string[i]和string[i]!='\0’一样
length++;
}
return length;
}
int main(){
char *inputString; int lengthString;
inputString=inputStr(); // 输入
lengthString=getLength(inputString); // 统计
printf(“字符串长度:%d\n”,lengthString);
}
输入字符串:made in china
字符串长度:13
#### 71、题目:结构体。编写input()和output()函数输入,输出5个学生的数据记录。
/*
题目:编写input()和output()函数输入,输出5个学生的数据记录。
*/
#include <stdio.h>
#include <string.h>
#define NUMBER 5
// 学生信息
struct STUDENT{
char name[20];
char sex[2];
// char sex;
int age;
}students[NUMBER];
// 输入
void inputStu(){
for(int i=0;i<NUMBER;i++){
printf(“第 %d 个学生信息\n”,i+1);
printf(“姓名:”);scanf(“%s”,students[i].name);
printf(“性别:”);scanf(“%s”,students[i].sex);
printf(“年龄:”);scanf(“%d”,&students[i].age);
}
}
// 输出
void ouputStu(){
for(int i=0;i<NUMBER;i++){
printf(“第 %d 个学生信息\n”,i+1);
printf(“姓名:%s\n”,students[i].name);
printf(“性别:%s\n”,students[i].sex);
printf(“年龄:%d\n”,students[i].age);
}
}
// 指定输出
void pointOutput(int age){
for(int i=0;i<NUMBER;i++){
if(students[i].age==age){
printf(“输出信息:%d %s\n”,students[i].age,students[i].name);
}
}
}
int main(){
printf(“\n********** 信息输入 **********\n”);
inputStu();
printf(“\n********** 信息输出 **********\n”);
ouputStu();
}
********** 信息输入 **********
第 1 个学生信息
姓名:first
性别:女
年龄:20
第 2 个学生信息
姓名:second
性别:女
年龄:21
第 3 个学生信息
姓名:third
性别:女
年龄:22
第 4 个学生信息
姓名:four
性别:男
年龄:20
第 5 个学生信息
姓名:five
性别:男
年龄:21
********** 信息输出 **********
第 1 个学生信息
姓名:first
性别:女
年龄:20
第 2 个学生信息
姓名:second
性别:女
年龄:21
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
if(sign[k]){
remainNum++;
printf("%d ",sign[k]);
}
}
printf("\n");
roundTime++;
printf("剩余人数:%d\n\n",remainNum);
}while(remainNum>1);
}
第 1 轮
退出:3 6 9
剩余:1 2 4 5 7 8 10
剩余人数:7
第 2 轮
退出:2 7
剩余:1 4 5 8 10
剩余人数:5
第 3 轮
退出:1 8
剩余:4 5 10
剩余人数:3
第 4 轮
退出:5
剩余:4 10
剩余人数:2
第 5 轮
退出:10
剩余:4
剩余人数:1
### 【2020-11-6】
#### 70、题目:统计字符串长度【数组指针做函数返回值】
/*
题目:写一个函数,求一个字符串的长度,在 main 函数中输入字符串,并输出其长度。
*/
#include <stdio.h>
#include <string.h>
// 1.输入字符串
char * inputStr(){
char str[256]; // 声明字符串数组
printf(“输入字符串:”);
gets(str);
return str;
}
// 2.统计长度
int getLength(char string[]){
int length=0;
for(int i=0;string[i];i++){ // 循环条件:string[i]和string[i]!='\0’一样
length++;
}
return length;
}
int main(){
char *inputString; int lengthString;
inputString=inputStr(); // 输入
lengthString=getLength(inputString); // 统计
printf(“字符串长度:%d\n”,lengthString);
}
输入字符串:made in china
字符串长度:13
#### 71、题目:结构体。编写input()和output()函数输入,输出5个学生的数据记录。
/*
题目:编写input()和output()函数输入,输出5个学生的数据记录。
*/
#include <stdio.h>
#include <string.h>
#define NUMBER 5
// 学生信息
struct STUDENT{
char name[20];
char sex[2];
// char sex;
int age;
}students[NUMBER];
// 输入
void inputStu(){
for(int i=0;i<NUMBER;i++){
printf(“第 %d 个学生信息\n”,i+1);
printf(“姓名:”);scanf(“%s”,students[i].name);
printf(“性别:”);scanf(“%s”,students[i].sex);
printf(“年龄:”);scanf(“%d”,&students[i].age);
}
}
// 输出
void ouputStu(){
for(int i=0;i<NUMBER;i++){
printf(“第 %d 个学生信息\n”,i+1);
printf(“姓名:%s\n”,students[i].name);
printf(“性别:%s\n”,students[i].sex);
printf(“年龄:%d\n”,students[i].age);
}
}
// 指定输出
void pointOutput(int age){
for(int i=0;i<NUMBER;i++){
if(students[i].age==age){
printf(“输出信息:%d %s\n”,students[i].age,students[i].name);
}
}
}
int main(){
printf(“\n********** 信息输入 **********\n”);
inputStu();
printf(“\n********** 信息输出 **********\n”);
ouputStu();
}
********** 信息输入 **********
第 1 个学生信息
姓名:first
性别:女
年龄:20
第 2 个学生信息
姓名:second
性别:女
年龄:21
第 3 个学生信息
姓名:third
性别:女
年龄:22
第 4 个学生信息
姓名:four
性别:男
年龄:20
第 5 个学生信息
姓名:five
性别:男
年龄:21
********** 信息输出 **********
第 1 个学生信息
姓名:first
性别:女
年龄:20
第 2 个学生信息
姓名:second
性别:女
年龄:21
[外链图片转存中…(img-rtD2zL5q-1715739274949)]
[外链图片转存中…(img-XiCwCnzL-1715739274950)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新