PTA作业分析5

实验4-2-5 输出整数各位数字

本题要求编写程序,对输入的一个整数,从高位开始逐位分割并输出它的各位数字。

题目

输入格式:

输入在一行中给出一个长整型范围内的非负整数。

输出格式:

从高位开始逐位输出该整数的各位数字,每个数字后面有一个空格。

输入样例:

123456

输出样例:

1 2 3 4 5 6 

思路 :

这道题本身非常简单,常规思路是对number做两次取余逆序,从而得到正向输出。

但是,我想提供一个更加简单的思路,将输入内容看做字符串,然后以空格为分隔符输出

#include<stdio.h>
#include<string.h>
int main(){
    char a[20];    //创建字符数组
    gets(a);    //读入
    int n=strlen(a);
    for(int i=0;i<n;i++){    //依次遍历输出
        printf("%d ",a[i]-'0');
    }
}

实验7-3-5 凯撒密码

题目:

为了防止信息被别人轻易窃取,需要把电码明文通过加密方式变换成为密文。输入一个以回车符为结束标志的字符串(少于80个字符),再输入一个整数offset,用凯撒密码将其加密后输出。恺撒密码是一种简单的替换加密技术,将明文中的所有字母都在字母表上偏移offset位后被替换成密文,当offset大于零时,表示向后偏移;当offset小于零时,表示向前偏移。

输入格式:

输入第一行给出一个以回车结束的非空字符串(少于80个字符);第二行输入一个整数offset。

输出格式:

输出加密后的结果字符串。

输入样例1:

Hello Hangzhou
2

输出样例1:

Jgnnq Jcpibjqw

输入样例2:

a=x+y
-1

输出样例2:

z=w+x

思路:

凯撒加密是非常经典的加密问题,关键在于如何位移,最方便的方法用取余(保证余数在0-25,对应a-z/A-Z)

但是需要特别注意的是在c语言中对一个负数取余,余数为负数,所以我们采用以下方法规避这个问题:

yushu=((n+offest)%26+26)%26

//(n+offest)%26  -->保证余数在-26~+25之间

//再加26保证全为正数

#include<stdio.h>
#include<string.h>
int main(){
    char s[80]="";
    gets(s);    //读入字符串
    int offset;
    scanf("%d",&offset);
    int n=strlen(s);
    for(int i=0;i<n;i++){
        if(s[i]<='z'&&s[i]>='a'){
            s[i]=((s[i]-'a'+offset)%26+26)%26+'a';//取余保证余数在0-25
        }
        else if(s[i]<='Z'&&s[i]>='A'){
            s[i]=((s[i]-'A'+offset)%26+26)%26+'A';
        }
    }
    puts(s);
}

实验7-3-8 输出大写英文字母

题目:

本题要求编写程序,顺序输出给定字符串中所出现过的大写英文字母,每个字母只输出一遍;若无大写英文字母则输出“Not Found”。

输入格式:

输入为一个以回车结束的字符串(少于80个字符)。

输出格式:

按照输入的顺序在一行中输出所出现过的大写英文字母,每个字母只输出一遍。若无大写英文字母则输出“Not Found”。

输入样例1:

FONTNAME and FILENAME

输出样例1:

FONTAMEIL

输入样例2:

fontname and filrname

输出样例2:

Not Found

思路:

本题的关键在于判断大写字母是否出现过,使用一个数组来记录是否出现过

a[26]来记录A-Z是否出现过,如果出现则该字母对应的下标上的值改为1

a[26]初始值均为0,表示均未出现

实现下标与字母一一对应:

eg. 'C'  -->  a['C'-'A']

char c  --> a[c-'A']

#include<stdio.h>
#include<stdio.h>
int main(){
    char s[81]="";
    gets(s);
    int a[26]={0};    //创建a以判断是否字母出现过
    int flag=0;    //flag记录是否出现大写字母
    int n=strlen(s);
    for(int i=0;i<n;i++){
        if(s[i]>='A'&&s[i]<='Z'&&a[s[i]-'A']==0){//判断 1.是否为大写字母 2.是否出现过
            a[s[i]-'A']=1;
            putchar(s[i]);
            flag=1;
        }
    }
      if(flag==0){
          printf("Not Found");
      }
}

实验7-3-9 删除重复字符

题目:

本题要求编写程序,将给定字符串去掉重复的字符后,按照字符ASCII码顺序从小到大排序后输出。

输入格式:

输入是一个以回车结束的非空字符串(少于80个字符)。

输出格式:

输出去重排序后的结果字符串。

输入样例:

ad2f3adjfeainzzzv

输出样例:

23adefijnvz

 思路:

看到题目的描述很容易就可以想到用的思想来解决

在这里详细讲述一下桶的思路:

1.创建一个桶,a[128],利用字符的ASCII值作为其下标一一对应(ASCII为0-127)

2.依次遍历,将下标上的值改为1  -->  相当于判断是否出现过改字符

eg:此时读到字符‘b’,ASCII为98 --> a['b']=1<-->a[98]=1

3.以此遍历a,如果下标上的值不为0,则输出

桶的好处在于,在记录字符出现的同时也将出现过的字符进行排序(利用ASCII码)

#include<stdio.h>
#include<string.h>
int main(){
    char s[81];
    gets(s);
    int a[128]={0};    //1.创建a[128]
    int n=strlen(s);
    for(int i=0;i<n;i++){//2.依次遍历并记录,同时相当于在排序
        a[s[i]]=1;
    }
    for(int i=0;i<128;i++){    //3.按顺序输出
        if(a[i]!=0){
            putchar(i);
         }
    }
}

  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值