算法入门——洛谷第五章_字符串(JAVA)

目录

        P5733 【深基6.例1】自动修正

        P1914 小书童——凯撒密码

        P1125 [NOIP2008 提高组] 笨小猴

        P1957 口算练习题

        P5015 [NOIP2018 普及组] 标题统计

        P5734 【深基6.例6】文字处理软件

        P1308 [NOIP2011 普及组] 统计单词数

        P1765 手机

        P3741 honoka的键盘

        P1321 单词覆盖还原

        P1553 数字反转(升级版)

        P1603 斯诺登的密码

        P1200 [USACO1.1] 你的飞碟在这儿 Your Ride Is Here

        P1597 语句解析

        P1598 垂直柱状图


P5733 【深基6.例1】自动修正

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str  = sc.nextLine();
        System.out.println(str.toUpperCase());
    }
}

str.toUpperCase() --- 将str中所有小写字母转为大写字母


P1914 小书童——凯撒密码

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.nextLine();
        String str = sc.nextLine();
        for(int i = 0;i<str.length();i++){
            int a = (int)str.charAt(i)+n;
            while(a>'z')
                a = a-'z'-1+'a';
            System.out.print((char)a);
        }
    }
}

nextInt(),next()和nextLine():

        nextInt()只会读取数字,不会读取其他字符,如空格和回车

        nextLine():遇到回车停止,并且会将回车从缓冲区读出

        next():从第一个有效字符开始检测,遇到回车或者空格停止,不会将空格或回车读出

为什么要whlie(a>'z')

        因为有可能n过于大,减小一次之后仍大于‘z’

为什么 a = a - 'z' - 1 + 'a'

        因为'z'+1 = 'a' 所以 a = a - ('z' + 1) + 'a' ,脱去括号就可得上式


P1125 [NOIP2008 提高组] 笨小猴

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] arr = new int[26];
        int max = 1;
        int min = 100;
        boolean ansb = false;
        String str = sc.nextLine();
        for(int i = 0;i<str.length();i++){
            int a = str.charAt(i)-'a';
            arr[a]++;
        }
        for(int i = 0 ;i<26;i++){
            if(arr[i]!=0) {
                if (arr[i] < min)
                    min = arr[i];
                if (arr[i] > max)
                    max = arr[i];
            }
        }
        int ans = max- min;
        int[] pri = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};//打表
        for (int j : pri) {
            if (ans == j) {
                ansb = true;
                break;
            }
        }
        if(ansb) {
            System.out.println("Lucky Word");
            System.out.println(ans);
        }

        else{
            System.out.println("No Answer");
            System.out.println(0);
        }
    }
}

统计单次中的字母出现次数

        charAt将单词中的每个字母读出来,然后减‘a’就可以得到这个字母比a大多少,再对数组中的这个索引处的数++,

质数怎么获取?

        打表,简单粗暴


P1957 口算练习题

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int c;
        char o = 'a';
        int ans = 0;
        String equ = "";
        for(int i = 0;i<a;i++) {
            int b = 0;
            String str = sc.next();
            if((int)str.charAt(0)-'a'>= 0) {
                o = str.charAt(0);
                b = sc.nextInt();
            }
            else{
                for(int m = 0;m<str.length();m++){
                    b = Integer.parseInt(str);
                }
            }
            c = sc.nextInt();
            switch(o){
                case 'a':
                    ans = b+c;
                    equ = b+"+"+c+"="+ans;
                    System.out.println(equ);
                    System.out.println(equ.length());
                    break;
                case 'b':
                    ans = b-c;
                    equ = b+"-"+c+"="+ans;
                    System.out.println(equ);
                    System.out.println(equ.length());
                    break;
                case 'c':
                    ans = b*c;
                    equ = b+"*"+c+"="+ans;
                    System.out.println(equ);
                    System.out.println(equ.length());
                    break;
            }
        }
    }
}

思路:因为每行至多有三个或者两个数据,所以先用next读一个数据,如果这个数据大于'a',则说明先读入的这个数据是一个字母,就需要改变之后的运算,而如果小于说明这是个数字,就需要按照之前的运算来进行。


P5015 [NOIP2018 普及组] 标题统计

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int a = 0;
        for(int i = 0;i<str.length();i++){
            if((int)str.charAt(i) != 32)
                a++;
        }
        System.out.println(a);
    }
}

只要这个字符不是空格长度就加一


P5734 【深基6.例6】文字处理软件

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = 0;
        int b = 0;
        String s1 = "";
        int q = sc.nextInt();
        String str = sc.next();
        for(int i = 0 ;i < q;i++){
            int o = sc.nextInt();
            switch (o){
                case 1:
                    s1 = sc.next();
                    str = str+s1;
                    System.out.println(str);
                    break;
                case 2:
                    a = sc.nextInt();
                    b = sc.nextInt();
                    str = str.substring(a,a+b);
                    System.out.println(str);
                    break;
                case 3:
                    a = sc.nextInt();
                    s1 = sc.next();
                    StringBuilder sb = new StringBuilder(str);
                    sb.insert(a,s1);
                    str = sb.toString();
                    System.out.println(str);
                    break;
                case 4:
                    s1 = sc.next();
                    System.out.println(str.indexOf(s1));
            }
        }
    }
}

StringBuilder对象中有insert(int,String)方法,可以在指定位置插入字符串


P1308 [NOIP2011 普及组] 统计单词数

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine().toUpperCase();
        String str2 = sc.nextLine().toUpperCase();
        boolean t = true;
        int a = str2.indexOf(str1);
        int b = -1;
        int cont = 0;
        while(a != -1){
            if((a==0 || str2.charAt(a-1)==' ') && (a+str1.length() == str2.length() || str2.charAt(a+str1.length()) == ' ')) {
                cont++;
                if(t){
                    b = a;
                    t = false;
                }
            }
            a = str2.indexOf(str1,a+str1.length());
        }
        if(cont == 0)
            System.out.println(-1);
        else
            System.out.printf("%d %d",cont,b);
    }
}

由于输入的字符串有大写有小写,故我们先统一一下,都统一转成大写


P1765 手机

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s1 = "adgjmptw ";
        String s2 = "behknqux";
        String s3 = "cfilorvy";
        String s4 = "sz";
        int ans = 0;
        String str = sc.nextLine();
        for(int i = 0;i<str.length();i++){
                if(s1.indexOf(str.charAt(i)) != -1)
                    ans +=1;
                if(s2.indexOf(str.charAt(i)) != -1)
                    ans +=2;
                if(s3.indexOf(str.charAt(i)) != -1)
                    ans +=3;
                if(s4.indexOf(str.charAt(i)) != -1)
                    ans +=4;
        }
        System.out.println(ans);
    }
}

打表,不多说了


P3741 honoka的键盘

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int ans = 0;
        String str = sc.next();
        int ad = str.indexOf("VK");
        while(ad != -1){
            ans++;
            ad = str.indexOf("VK",ad+2);
        }
        str = str.replaceAll("VK","00");
        if(str.contains("VV") || str.contains("KK"))
            ans++;
        System.out.println(ans);
    }
}

while循环内找出现有的VK,计数

再将所有的VK替换掉,如果替换之后还有VV 或者 KK 则改变一个字符后可以使VK数量+1


P1321 单词覆盖还原

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int B = 0;
        int G = 0;
        for(int i = 0;i<str.length()-2;i++)
            if(str.charAt(i) == 'b' || str.charAt(i+1) == 'o' || str.charAt(i+2) == 'y')
                B++;
        for(int i = 0;i<str.length()-3;i++)
            if(str.charAt(i) == 'g' || str.charAt(i+1) == 'i' ||str.charAt(i+2) == 'r' ||str.charAt(i+3) == 'l' )
                G++;
        System.out.println(B);
        System.out.println(G);
    }
}

为什么for循环的次数不一样?

        根据题意,这串字符串被反复贴有单词,所以贴的单次长度肯定不能超出字符串,即如果按照顺序来看,如果要贴boy这个单词,在字符串第一个字母的位置只有可能是b(如果是其他字母就代表boy这个单词贴到字符串外了),同理可得,最后一个字母的位置只有可能是y。

        所以如果字符串当前位置为b或者下一个位置为o或者下下个位置为y,都可以代表boy这个单词被贴到这里了

        所以只需要循环所贴单词的最后一个字母恰好落在字符串末尾时即可

简单来说,就是相当于拿着要贴的单词在这串字符串上移动。


P1553 数字反转(升级版)

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String o = "/.%";
        String str = sc.nextLine();
        String s1 = "";
        String s2 = "";
        String a = "";
        boolean t = true;
        for(int i  = 0;i < str.length();i++){
            if(!o.contains(str.charAt(i)+"") && t) {
                s1 = str.charAt(i) + s1;
            }
            else {
                t = false;
                a = a+str.charAt(i);
                s2 = str.charAt(i) + s2;
            }
        }
        s1 = s1.replaceAll("^(0+)","");
        s1 = s1.length() == 0?"0":s1;
        if(a.length()>1) {
            s2 = s2.substring(0, s2.length() - 1);
            if(a.charAt(0) == '.')
                s2 = s2.replaceAll("(0+)$","");
            else
                s2 = s2.replaceAll("^(0+)","");
            s2 = s2.length() == 0?"0":s2;
            System.out.println(s1+a.charAt(0)+s2);
        }
        else
            System.out.println(s1+a);
    }
}

思路:先把目标i字符串读取过来,然后利用for循环将这个字符串反着读入s1,一旦读取遇到了“/.%”三个符号之一,再反着将剩下的字符读入s2,a用于储存这个符号到底是什么

               反转完成后去掉首位的0,如果去除后首位没长度了,则补一个0

                如果a中字符串长度大于1,则说明符号位于原数据的中间,则不可能是%,然后再进一步判断到底是哪个符号,如果是小数点,则去除s2尾部的零,如果是/,则去除s2首位的零

给大家举三个例子,对照代码看一下应该就能看懂了


P1603 斯诺登的密码

import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s1 = "a+one+anther+first two+both+second three+third four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty";
        String s2 = sc.nextLine();
        String s3 = "";
        int[] arr = new int[6];
        String[] sp2 = s2.split(" ");
        String[] sp1 = s1.split(" ");
        for(int i = 0;i<6;i++){
            for(int m = 0;m<sp1.length;m++){
                if(sp1[m].contains(sp2[i])) {
                    arr[i] = m + 1;
                    break;
                }
            }
        }
        for(int i = 0;i<arr.length;i++)
            arr[i] = arr[i]*arr[i] % 100;
        Arrays.sort(arr);
        for(int i = 0;i<arr.length;i++) {
            if(arr[i]<10)
                s3 = s3 + '0';
            s3 = s3 + arr[i];
        }
        s3 = s3.replaceAll("^(0+)","");
        if(s3.length() == 0)
            s3 = "0";
        System.out.println(s3);
    }
}

将代表不同数字的单词存到标准字符串数组里,再检查对应的单词是否在标准字符串中出现,就可以知道每个单词代表的数字,之后再进行操作就可以了。

如何保证最小呢?

        位数越高,对应的数字越小,这个数字整体就越小


P1200 [USACO1.1] 你的飞碟在这儿 Your Ride Is Here

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s1 = sc.nextLine();
        String s2 = sc.nextLine();
        int a = 1;
        int b = 1;
        for(int i = 0; i<Math.max(s1.length(),s2.length());i++) {
            if (i < s1.length())
                a *= (s1.charAt(i) - 'A' + 1);
            if (i < s2.length())
                b *= (s2.charAt(i) - 'A' + 1);
        }
        if(b%47 == a%47)
            System.out.println("GO");
        else
            System.out.println("STAY");
    }
}

P1597 语句解析

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int[] arr = new int[3];
        for(int i = 0;i<str.length()/5;i++){
            int a = str.charAt(i*5) - 'a';
            int b = str.charAt(3+i*5);
            arr[a] = b<='9'?b-'0':arr[b-'a'];
        }
        System.out.printf("%d %d %d",arr[0],arr[1],arr[2]);
    }
}

五个字符算一个语句,所以长度/5

a读取被赋值的变量  b读取赋值的变量或数字

如果b<=‘9’ 就说明b是数字  否则就是变量


P1598 垂直柱状图

 

import java.util.*;
public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s1 = sc.nextLine();
        String s2 = sc.nextLine();
        String s3 = sc.nextLine();
        String s4 = sc.nextLine();
        String s = s1+s2+s3+s4;
        int[] arr = new int[26];
        for(int i = 0;i<s.length();i++){
            if(s.charAt(i) - 'A'>=0)
                arr[s.charAt(i) - 'A']++;
        }
        int[] a1 = Arrays.copyOf(arr,26);
        Arrays.sort(a1);
        int a = a1[25];
        for(int i = 0;i<a1[25];i++){
            for(int k = 0;k<arr.length;k++){
                if(k != arr.length-1) {
                    if (arr[k] - a >= 0) {
                        System.out.print("* ");
                    } else
                        System.out.print("  ");
                }
                else {
                    if (arr[k] - a >= 0) {
                        System.out.print("*");
                    } else
                        System.out.print(" ");
                }
            }
            a--;
            System.out.println();
        }
        System.out.print("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");
    }
}

a里面存入做多出现字母的次数,然后依次减小,大于a就可以输出*,小于a就用空格占位


有问题欢迎大家来评论区留言

我们下次见喵~

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值