1.扩展字符
【问题描述】
从键盘输入包含扩展符'-'的字符串,将其扩展为等价的完整字符,例如将a-d扩展为abcd,并输出扩展后的字符串。
【输入形式】
从键盘输入包含扩展符的字符串
【输出形式】
输出扩展后的字符串
【输入样例1】
ADEa-g-m02
【输出样例1】
ADEabcdefghijklm02
【输入样例2】
cdeT-bcd
【输出样例2】
cdeT-bcd
【样例说明】
将样例1的输入ADEa-g-m02扩展为:ADEabcdefghijklm02;样例2的输入cdeT-bcd中,扩展符前的字符为大写字母,扩展符后的字符为小写字母,不在同一范围内,所以不进行扩展。
解题思路:
1/ 由于不知道数据范围 输入先不考虑使用gets(s) scanf("%s",&s)
*使用getchar()而不用scanf(" %s",&ch)的原因
首先是scanf不会扫描'\n'会卡在最后的输入 从而超时
其次是getchar() putchar()的运行速度更快
2/ 问题的关键在于'-'前后的判断 所以要储存上一个字符的结果
在碰到'-'时在扫描下一个字符 从而进行是否扩展的判断
*不确定环判断条件时候 果断while(1) 到后面在break continue
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define LL long long
#define MAX(A,B) (A)>(B)?(A):(B)
#define MIN(A,B) (A)<(B)?(A):(B)
int main(int argc,const char* argv[]){
char ch_l='\0',ch,ch_r='\0';
int i;
while(1){
ch=getchar();
if(!isgraph(ch)) break; //判断是否到字符串结尾
if(ch!='-'){ //非'-' 正常输出
putchar(ch);
ch_l=ch; //记录上个字符
continue;
}
//扫描到'-' 接着扫描入下一个字符
ch_r=getchar();
if(!isgraph(ch_r)) break; //判断是否到字符串结尾
if(((islower(ch_l)&&islower(ch_r))|| //判断'-'前后字符是否满足条件
(isupper(ch_l)&&isupper(ch_r))||
(isdigit(ch_l)&&isdigit(ch_r))) && ch_l<ch_r){
for(i=ch_l+1;i<ch_r;i++)
putchar(i); //扩展'-'
putchar(ch_r);
ch_l=ch_r; //记录值
continue;
}
//不满足扩展要求
putchar(ch);
putchar(ch_r);
ch_l=ch_r; //记录上个字符
}
return 0;
}
2. 表达式的计算(支持空格 连乘 连除)
【问题描述】
从标准输入中读入一个整数算术运算表达式,如5 - 1 * 2 * 3 + 12 / 2 / 2 = 。计算表达式结果,并输出。
要求:
1、表达式运算符只有+、-、*、/,表达式末尾的’=’字符表示表达式输入结束,表达式中可能会出现空格;
2、表达式中不含圆括号,不会出现错误的表达式;
3、出现除号/时,以整数相除进行运算,结果仍为整数,例如:5/3结果应为1。
【输入形式】
在控制台中输入一个以’=’结尾的整数算术运算表达式。
【输出形式】
向控制台输出计算结果(为整数)。
【样例1输入】
5 - 1 * 2 * 3 + 12 / 2 / 2 =
【样例1输出】
2
【样例2输入】
500 =
【样例2输出】
500
【样例1说明】
输入的表达式为5 - 1 * 2 * 3 + 12 / 2 / 2 =,按照整数运算规则,计算结果为2,故输出2。
【样例2说明】
输入的表达式为500 = ,没有运算符参与运算,故直接输出500。
算法之一提示:
1、可以利用gets函数,读取整行表达式;
2、对于空格,可以考虑首先去除表达式中的所有空格
3、可以设一计数器用来记录已读取、但未参加运算的运算符的个数,根据该计数器来判断如何进行运算;
4、可以设计一函数:实现二元整数算术运算。
解题思路1:
scanf("%d %c",&num,&op)解决空格问题
加减号可以看成分隔符 乘除优先运算 结果先储存到tmp_value 遇到+-时在加到result上
*此方法局限与不包括括号的情况下
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define LL long long
#define MAX(A,B) (A)>(B)?(A):(B)
#define MIN(A,B) (A)<(B)?(A):(B)
int main(int argc,const char* argv[]){
long long result=0,tmp_value=1,num; //由于不带括号 不受数字正负影响 开头是负数也不影响
char op;
while(1){
scanf("%lld %c",&num,&op);
tmp_value*=num;
while(op=='*' || op=='/'){ //碰到乘除优先计算 不是乘除跳出
scanf("%lld",&num);
if(op=='*') tmp_value*=num;
else tmp_value/=num;
scanf(" %c",&op);
}
result+=tmp_value;
if(op=='+') tmp_value=1; //加号减号直接体现在临时值上
else if(op=='-') tmp_value=-1;
else{
printf("%lld",result);
break;
}
}
return 0;
}
解题思路2:
应用堆栈实现
*可以加上括号
3.小数形式与科学计数法换算(简)
【问题描述】
编写一个程序,将用小数表示的浮点数,转换成科学计数法的形式输出。输入的数据没有符号,小数点前后必有数字,且全为有效数据,即小数点后的末尾数字不为0;小数点前若只有一位数字,可以为0,否则小数点前的最高位数字不为0。
提示:以字符串形式保存相关数据。
【输入形式】
从控制台输入一小数,最后有回车换行符,所有输入的字符数不会超过100。
【输出形式】
以科学计数法形式输出数据。输出的数据由以下几部分构成:
1.底数部分是一个小数或整数,若为小数,则小数点前后必有数字,而且都为有效数字。即:小数点前只有一位大于0的数字,小数点后的末尾数字不能为0。若为整数,则只有一位数字,不带小数点。
2.必有小写字母“e”。
3.指数部分是一个整数,若大于等于0,则不带正号“+”。若小于0,则需要带负号“-”,且整数的最高位数字不为0。
【输入样例1】
0.000000000000002
【输出样例1】
2e-15
【输入样例2】
8.9845623489651700659
【输出样例2】
8.9845623489651700659e0
【输入样例3】
367298599999093453490394859509568659795603.4
【输出样例3】
3.672985999990934534903948595095686597956034e41
【样例说明】
以小数形式输入数据,然后转换成科学计数法形式输出。
解题思路:
遍历一遍找到小数点和第一位有效数字的位置 再根据一些特判解决特殊情况
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define LL long long
#define MAX(A,B) (A)>(B)?(A):(B)
#define MIN(A,B) (A)<(B)?(A):(B)
char s[99999];
int main(int argc,const char* argv[]){
int len,pos_dot=-1,pos_first_num=-1;
scanf("%s",s);
len=strlen(s);
for(int i=0;i<len;i++){
if(pos_dot==-1 && s[i]=='.') pos_dot=i; //找到'.'的位置
if(pos_first_num==-1 && s[i]!='0' && s[i]!='.'){ //找到第一个有效数字的位置
pos_first_num=i;
putchar(s[i]);
if(i!=len-1) putchar('.'); //小数点后不能为0
continue;
}
if(pos_first_num!=-1 && s[i]!='.') putchar(s[i]);
}
if(s[0]=='0') pos_dot++; //小数点前第一位为0的情况
printf("e%d",pos_dot-pos_first_num-1);
return 0;
}
4. 超长正整数的减法
问题描述】
编写程序实现两个超长正整数(每个最长80位数字)的减法运算。
【输入形式】
从键盘读入两个整数,要考虑输入高位可能为0的情况(如00083)。
1. 第一行是超长正整数A;
2. 第二行是超长正整数B;
【输出形式】
输出只有一行,是长整数A减去长整数B的运算结果,从高到低依次输出各位数字。要求:若结果为0,则只输出一个0;否则输出的结果的最高位不能为0,并且各位数字紧密输出。
【输入样例】
234098
134098703578230056
【输出样例】
-134098703577995958
【样例说明】
进行两个正整数减法运算, 234098 -134098703578230056 = -134098703577995958。
【评分标准】
完全正确得20分,每个测试点4分,提交程序文件名为subtract.c。
解题思路:
注意事项:1/大减小 2/高低位 3/相同数相减
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define LL long long
#define MAX(A,B) (A)>(B)?(A):(B)
#define MIN(A,B) (A)<(B)?(A):(B)
#define SIZE 100 //提交发现大小设置100就够
char s1[SIZE],s2[SIZE];
int num1[SIZE],num2[SIZE],ans_int[SIZE];
void swap(int *a,int *b);
void HighPrecisionSub(char* s1,char* s2);
int main(int argc,const char* argv[]){
scanf("%s%s",s1,s2);
HighPrecisionSub(s1,s2);
return 0;
}
void swap(int *a,int *b){
int t;
t=*a;
*a=*b;
*b=t;
return;
}
void HighPrecisionSub(char* s1,char* s2){
int len,len1,len2,i,flag=0;
len1=strlen(s1);
len2=strlen(s2);
len=MAX(len1,len2);
for(i=0;i<len1;i++) num1[len1-i-1]=s1[i]-'0'; //将字符串转换为数组 注意高低位的转换
for(i=0;i<len2;i++) num2[len2-i-1]=s2[i]-'0';
if(len1<len2 || (len1==len2 && strcmp(s1,s2)<0)){ //将大的值放到num1里
for(i=0;i<len;i++) swap(&num1[i],&num2[i]);
flag=1; //若交换 输出最前要放'-'
}
for(i=0;i<len;i++){ //模拟竖式减法
ans_int[i]+=num1[i]-num2[i];
if(ans_int[i]<0){
ans_int[i]+=10;
num1[i+1]--;
}
}
while(ans_int[len-1]==0 && len>1) len--; //找最高位的位置 同时答案至少有一位
if(flag) putchar('-');
for(int i=len-1;i>=0;i--) printf("%d",ans_int[i]);
return;
}
5. 全排列数的生成
问题描述】输入整数N( 1 <= N <= 10 ),生成从1~N所有整数的全排列。
【输入形式】输入整数N。
【输出形式】输出有N!行,每行都是从1~N所有整数的一个全排列,各整数之间以空格分隔。各行上的全排列不重复。输出各行遵循“小数优先”原则, 在各全排列中,较小的数尽量靠前输出。如果将每行上的输出看成一个数字,则所有输出构成升序数列。具体格式见输出样例。
【样例输入1】1
【样例输出1】1
【样例说明1】输入整数N=1,其全排列只有一种。
【样例输入2】3
【样例输出2】
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
【样例说明2】输入整数N=3,要求整数1、2、3的所有全排列, 共有N!=6行。且先输出1开头的所有排列数,再输出2开头的所有排列数,最后输出3开头的所有排列数。在以1开头的所有全排列中同样遵循此原则。
解题思路:
【46. 全排列 Permutations 【LeetCode 力扣官方题解】】 https://www.bilibili.com/video/BV1oa4y1v7Kz/?share_source=copy_web&vd_source=0133d8a1acbf30bcb8f6d49a7f69ace4
观看视频理解思路即可 不用管后面的代码实现
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define LL long long
#define MAX(A,B) (A)>(B)?(A):(B)
#define MIN(A,B) (A)<(B)?(A):(B)
int path[15],used[15];
void FullPermu(int n,int depth);
int main(int argc,const char* argv[]){
int N;
scanf("%d",&N);
FullPermu(N,0);
return 0;
}
void FullPermu(int n,int depth){
int i;
if(depth==n){ //终止条件
for(i=0;i<n;i++) printf("%d ",path[i]); //输入排列
putchar('\n');
return;
}
for(i=1;i<=n;i++){
if(used[i]) continue; //元素被使用则跳过
path[depth]=i;
used[i]=1; //标记元素被使用
FullPermu(n,depth+1); //放入一个元素时 深度加一
used[i]=0; //消除标记
}
return;
}