以下题目是由老师布置的《 谭浩强C程序设计(第四版)》的oj第四次练习题,共五道
使用软件是Devc++5.11。
希望大家抄了作业顺手点个赞,谢谢,爱宁
最近期末挺忙的,学了微机原理之后,就突然很想写代码。。。这个帖子还没写完,但是写太久了,先发出来吧,之后再添加上最后一道题。宝贝们加油呀!
A. C语言_ex07_01
运行时间限制: 1000 运行内存限制: 65536
题目描述
首先请实现如下两个函数(要自己写代码完成,不允许直接调用库函数):
int myStrLen(char *s);
该函数功能为求字符串s的长度。
void myStrConcat(char *string1, char *string2);
该函数的功能为将字符串string2拼接至字符串string1后边。注意:该函数的两个参数,在调用时有可能会指向同一个字符串,函数需要在这种情况下能正确完成指定的功能。
主函数要求使用以上两个函数实现如下功能:
输入:
第一行为三个整数n(0<n<10),a,b, 第二行为n个整数,后边为n行字符串,每个字符串长度不超过20。
输出:
要求首先将第b行字符串拼接至第a行的字符串后再输出。
第一行为n个用单个空格分隔的整数(最后一个数后无空格),为按各字符串的输入次序输出的各字符串的长度。
后边n行为将输入的字符串按输入的第2行给出的顺序依次输出。
输入保证合法且字符串中不包含空格。
输入样例
2 0 1
1 0
Hello
World
输出样例
10 5
World
HelloWorld
#include<stdio.h>
int myStrLen(char *s)
{
int i,k=0;//我刚开始这里忘记给k赋值
for(i=0;s[i]!='\0';i++)//字符串末尾是\0是一个十分好用的条件
k++;
return k;
}
void myStrConcat(char *string1, char *string2)//这里不能加分号!复制的时候很容易带上,会出现这个错误:expected identifier or '(' before '{' token
{
int i;
int l1, l2;
l1 = myStrLen(string1);
l2 = myStrLen(string2);
for (i=l1; i<l1+l2; ++i)
string1[i] = string2[i-l1];
string1[l1+l2] = '\0'; //注意这个不能改~想过在前面循环l1+l2上 +1,但是会答案错误
}
int main()
{
int n,a,b,i;
int num[10];
char str[10][50];//这个是要输入的字符串,n行,每行不超过21个字符,重叠之后就是 42,如果写了20就会运行时错误,写了42以下的就会答案错误
scanf("%d %d %d",&n,&a,&b);
for(i=0;i<n;i++)
scanf("%d",&num[i]);
for(i=0;i<n;i++)
scanf("%s",str[i]);//%s就是输入字符串,不用写&
myStrConcat(str[a],str[b]);//使用刚刚建的函数
for(i=0;i<n;++i)//这里一定要写++i
printf(" %d",myStrLen(str[i]));
printf("\n");
//按第二行给出的顺序,就是按num[i]的顺序输出str[]
for(i=0;i<n;++i)
printf("%s\n",str[num[i]]);
return 0;
}
第一题太恐怖了,通过数/提交数有137/513!!提交数比别的题多了两三倍,大家一定要好好看这道题。。。
9.新加密技术
题目描述
你发明了一种新的加密技术,它是通过一种聪明的方法将随机产生的一些字符插入原信息。因为涉及专利问题,我们这里不讨论字符是如何产生和插入原信息的。为了证实你的想法,现在需要写个程序来检查原信息是否真的编入最终的字符串了。
给定2个字符串s和t,你需要判断s是否是t的子串。如果你可以通过从中删除部分字符,然后再连接剩下的字符得到s,则认为s是t的子串。
(改编自北大在线裁判系统中的题目)
输入格式
第1行是测试数据的组数T,后面跟着T行测试用例。每行包含2个用空格隔开的字符串(字符 串内仅包含英文大写字母或小写字母), 前边的为s,后边的为t (s和t的长度均不超过10000)。
输出格式
输出: T行,每行对应一组测试用例,如果s是t的子串输出Yes,否则输出No。
输入样例
4
sequence subsequence
person compression
VERDI vivaVittorioEmanueleReDiItalia
caseDoesMatter CaseDoesMatter
输出样例
Yes
No
Yes
No
//这道题其实就是去判断两个字符串中的相等元素,相等的从第一个判断到最后一个
#include<stdio.h>
# include <string.h>
#include<stdbool.h>//如果函数选择了bool类型,布尔值对应的头文件。不过有的编辑器不写这个也可以过。
int judge( char *str1,char *str2)//这个用布尔值bool也可以。
{
int i,j,l1,l2,equal=0,start=0;
l1=strlen(str1);
l2=strlen(str2);
//因为检测字符串2中有没有1,所以用1中的第一个元素,去2里面对一圈,对到了第一个就跳出循环,开始对下一个
for(i=0;i<l1;++i)//经过上一道题,养成了写++i代替i++的习惯。。
{
for(j=start; j<l2; ++j)//注意这里的start,因为文字有顺序的,字符串1中的第二个元素有可能出现在之前对上的元素之前
{
start++;
if(str1[i] == str2[j])
{
equal++;
break;
}
}
}
if(equal==l1)
return 1;
else
return 0;
//如果用布尔值这里要改成
// if (equal == l1)
// return true;
// else
// return false;
}
int main ()
{
int T,i;
scanf("%d",&T); //T行测试用例,小技巧:按住shift再按字母可以快捷输入大写英文
char str1[T][10005],str2[T][10005];//仍然要注意这里的取值范围。
for(i=0;i<T;++i)
scanf("%s %s",str1[i],str2[i]);
for(i=0;i<T;++i)
{
if(judge(str1[i],str2[i]))//if(表达式)表达式的值为1后面的程序执行,若为0则不执行。
printf("Yes\n");
else
printf("No\n");
}
}
C. 句子输出
运行时间限制: 1000 运行内存限制: 65536
作者: bupt_admin 是否specialjudge: False
题目描述
事先允许最多五个英文字符串输入后,再指定输出顺序的编号(即对应输入字符串的顺序),使对应输出的英文字符串按照指定的顺序输出在一行上。
输入格式
第一行:输入一个正整数,表示将要输入的字符串的个数,最大为5。
第二行起:在每一行内对应输入一个字符串,限制在10个字符以内(含10个字符) 。
输入完最后一个字符串的下一行:依次输入输出顺序编号,从0开始(即0表示输入的第一个字符串, 1表示输入的第二个字符串,依次类推),两个相邻数字之间用空格隔开。
输出格式
只有一行,按照输入指定的顺序输出字符串。两个相邻的字符串间用空格隔开,最后一个字符串后没有空格且应换行。
输入样例
3
world
Hello
!
1 0 2
输出样例
Hello world !
#include<stdio.h>
# include <string.h>
int main()
{//按order数组中的顺序输出str中的内容
//不要太纠结空格啥的了,都已经学到这里了。。。
int n,order[10],i,j;
char str[10][20];
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s",str[i]);
}
for( j=0;j<n;j++)
{
scanf("%d",&order[j]);
}
for(i=0;i<n;i++)
{
printf("%s ",str[order[i]]);//这个空格不加也能过
}
}
D、密码危机
题目描述
CSDN用户密码泄露事件在互联网引起了一场密码危机。热衷于使用支付宝网购的盾盾不禁担心起自己的支付宝账户安全。通过了解,盾盾发现支付宝使用双密码,安全控件,资金异动通知,各种安全产品来保障账户的安全,可以放心使用。密码危机事件也引起了盾盾对加密的兴趣,不过他也只能从最简单的开始。盾盾开始有一个长为26的字符串,表示字母的对应关系,比如S对应A,C对应E,于是SCS就被加密为AEA。可是数据一多盾盾便不知道如何处理了,他只能求助于你,现在给你一个26个字母的对应关系,然后再给你n个加密前的字符串,请你输出加密后的字符串。
输入格式
一共有T组测试数据。每组数据第一行为长为26的字符串,第i位S[i]表示字符(‘A’+i-1) 加密后得到S[i],之后为一个数字n,表示共有n组询问。
数据范围: T<=10;n<=100;
字符串长度不超过30(均为大写字母)
输出格式
对于每组数据中的每次询问,输出一行,为加密后的字符串
输入样例
1
QWERTYUIOPASDFGHJKLZXCVBNM
3
ILOVEBUPT
ACMICPC
BUPTSCS
输出样例
OSGCTWXHZ
QEDOEHE
WXHZLEL
#include<stdio.h>
#include<string.h>
//题目的意思就是QWER对应ABCD。先输入密码,然后把密码后面的文字加密输出。
//T的意思是:不止一组密码。可以分别对应,做个循环。
int main()
{
int T,n,i,j;
char string[10][32][102]; //string是被加密的文字,第一个数字表示第T组密码,第二个是第几行代码
char strkey[10][26]; //string key,用来存放密码
scanf("%d",&T);
for(i=0;i<T;i++)
{
scanf("%s",strkey[i]);
scanf("%d",&n);
for(j=0;j<n;j++)
{
scanf("%s",string[i][j]);
}
for(j=0;j<n;j++)
{
encryption(string[i][j],strkey[i]); //进行加密!输出的代码写在函数里面啦
//我一开始是把输出写在main里的。
//但是对于函数来说,return一个字符串有点难操作。为了不难为自己,就在函数里面输出吧。
printf("\n"); //我一开始忘记换行啦!
}
}
}
void encryption(char* in, char* key)
//encryption百度查的词,意思是“加密”。这行的括号里定义的是(被加密的字符串str in,密码key)
//char* 这个东西,暂时考虑成一个不用琢磨范围写几的数组就ok。
{
//在函数里面使用的参数,名字可以随便取,不会对main里的有什么影响。但是main里定义的也不能拿来用。(这就是传说中的形参与实参)
int i=0;
char out[35];
for(i=0;i<strlen(in);i++) //一个一个的转化strin,需要用到strlen来知道in字符串的长度。
//或者用 字符串最后一个是'\0' 这个条件来判断。
out[i]=key[in[i]-65];
//A的asc2码是65。后面的依次加一。减去65,就可以知道这个字母是A后面第几个。
//用密码里面对应位置的字母,放进out里面。
out[strlen(in)]='\0';
//【高亮】这句很重要!
printf("%s",out );
}
E.北京市机动车网上自选牌号的正误容易鉴别吗?
题目描述
2009年3月9日开始,北京市交通管理局正式推出北京市机动车网上自选牌号业务,极大的方便了新购车的市民自选中意的新车牌照号的需求。根据国家制定的机动车号牌号码标准,一辆机动车的号牌号码由七位字符组成,前两位是号牌号码发牌机关代码,后五位是具体号牌号码。主管部门在具体操作上又出台了以下规定:
机动车所有人网上选号的号牌号码发牌机关代码为"京N或者"京Y。后面的五位号牌号码的最后一位必须为数字,其余四位有且必须有两位为英文字母(但字母和0不可用)。例如:京NAB999、京NC9D99、京NE99F9、京N9GH99、京N9J9K9、京N99LM9、京YNB999、京YP9D99、京YZ99F9号码都是正确的。
你能据此用C语言编写一个程序来检测给定的号牌号码是否符合上述规定吗?
输入格式
只有一行,含有号牌号码最后五位的字符内容。如果输入了小写字母,请先变更为大写字母再行检测。如果输入不允许的其他字符内容,则输出"no.”(不含双引号本身)。
输出格式
只有一行。如果检测认为符合规定则输出yes:"并后跟对应的号牌号码,如果检测认为不符合规定则输出’no.”(不含双引号本身)。
输入样例
K00a1
输出样例
yes:K00A1
#include<stdio.h>
#include<string.h>
/*题目分析:
先把大小写搞对,然后再判断。判断要素有三条:
1.第5位必须是数字 ---在i=4时添加判断条件 。
2.字母不能是I、O---在输入时判断,如果输入了IO就直接错啦 。
3.有且仅有两位是字母---可以在输入时添加变量,计算字母、数字的个数;也可以利用字母比数字asc2码大的特点在最后判断。
注意要点:
非常考验asc2码的应用和判断顺序的逻辑。这道题其实放哪章都能做。
输出的“.”、“:”和数组界限都是老生常谈了。
*/
char change(char input) //用来把小写字母变成大写。不用函数也是一样的
{
char output = 0;
if(input>='a'&&input<='z')
{
output=input-32; //同样字母的小写ASCII码值比大写的ASCII码值大32
return output;
}
else
{
return input; //函数是用return来表示自己对输入干了点什么的。
//这个叫change的函数吃掉的和吐出来的都是字符,所以函数的定义类型是char。
}
}
int main() //这里是主函数。
{
int i=0,sum=0;
char in[5]={ }; //我一开始华丽丽的把这个写成了in[4],出现的bug是最后一位不管是什么都会双倍asc2码输出。(如:1-b,2-d)
for(i=0;i<5;++i) //得到教训:出现百思不得解的bug,要优先考虑数组越界
{
scanf("%c",&in[i]);
in[i] = change(in[i]);
sum =sum + in[i];
switch(in[i])
{ //注:冒号后面是空语句,或者理解成满足条件直接跳出循环。
case 'A'...'H': break; //查了一下 ,switch中判断范围可以用...来表示。注意如果判断数字的范围,要在点和数字之间加空格
case 'J'...'N': break; //感兴趣的同学可以查一下,关键词是 "switch判断范围"
case 'P'...'Z': break; //用if(>=&&<= )这种判断方式也是一样的。
case '0'...'9': break; //注意本句写法~是判断0到9的asc2码,而不是判断数字。
default :
{
printf("no.");
return 0; //其实main也只是个函数。
//让他早点return个0出来,后面步骤的就直接不用走了。
//相当于跳出函数的意思。
}
}
if(i==4) //在i=4时判断两个情况:最后一位为字母、有且只有两个字母
{
if(in[4]<='0'||in[4]>='9')
{
printf("no.");
return 0;
}
if(sum<=274) //最小的大写字母是A(65),这就是满足条件的最小情况 65+65+48+48+48=274。‘0’的码是48~我一开始这里也犯错了
{
printf("no.");
return 0;
}
else break;
}
}
printf("yes:");
for(i=0;i<5;i++)
{
printf("%c",in[i]);
}
}
道歉解释
由于我实在是太能拖,第八次练习已经挂了。。没办法在oj上验证了。。。如果可以的话,过两天做点其他的题继续放上来