Java面向对象程序程序设计PTA题目解析一


字符串操作

给定一个字符串。请去除串中的数字并反转。

输入格式: 原始串。

输出格式: 去除数字后的反转字符串。

输入样例: 在这里给出一组输入。例如: he11ll00o w0or8ld!

输出样例: 在这里给出相应的输出。例如: !dlrow olleh

import java.util.Scanner;  // 导入java.util包中的Scanner类,用于读取用户输入  
  
public class Main {  // 定义一个公开的类Main,它是这个程序的入口点  
    public static void main(String[] args) {  // 定义main方法,它是程序的入口点  
        Scanner s = new Scanner(System.in);  // 创建一个Scanner对象s,用于读取来自标准输入流(通常是键盘)的数据  
        String str = s.nextLine();  // 调用s的nextLine方法读取一行文本,并将其存储在字符串变量str中  
  
        // 使用for循环从字符串的最后一个字符开始向前遍历  
        for (int i = str.length() - 1; i >= 0; i--) {    
            char c = str.charAt(i);  // 在循环的每次迭代中,通过调用str的charAt方法并传入索引i来获取当前字符,然后将其存储在字符变量c中  
  
            // 使用Character类的isDigit静态方法来检查变量c中的字符是否为数字  
            if (!Character.isDigit(c)) {    
                // 如果c不是数字,则执行打印操作  
                System.out.print(c);  // 调用System.out的print方法将字符c输出到控制台,这里不会换行  
            }  
        }  
    }  
}

注意:这里使用的是System.out.print而不是System.out.println,这意味着输出将不会在每个字符后换行,而是连续输出直到所有非数字字符都被逆序打印出来。

str的charAt方法:在Java中,String 类的 charAt 方法用于获取字符串中指定索引位置上的字符。这个方法接受一个整数参数,即字符的索引(位置),并返回该位置上的 char 类型的值。索引值从0开始,即字符串的第一个字符的索引是0,第二个字符的索引是1,依此类推,直到字符串的最后一个字符。
如果索引值超出了字符串的范围(即小于0或大于等于字符串的长度),那么 charAt 方法会抛出一个 StringIndexOutOfBoundsException 异常。

public class Main {  
    public static void main(String[] args) {  
        String str = "Hello, World!";  
        // 获取索引为7的字符(注意:索引从0开始)  
        char ch = str.charAt(7);  
        // 输出结果将是 'W',因为 'W' 是字符串 "Hello, World!" 中索引为7的字符  
        System.out.println(ch);  
    }  
}

在这个例子中,字符串 str 包含文本 “Hello, World!”。我们通过调用 str.charAt(7) 来获取索引为7的字符,即 ‘W’,并将其存储在字符变量 ch 中。然后,我们使用 System.out.println(ch); 来打印这个字符。
需要注意的是,如果尝试访问一个不存在的索引(比如 str.charAt(str.length()) 或 str.charAt(-1)),那么将会抛出 StringIndexOutOfBoundsException 异常。因此,在使用 charAt 方法时,确保提供的索引在有效范围内是很重要的。

Character类的isDigit静态方法:Character 类的 isDigit 静态方法用于判断指定的字符是否是一个数字。该方法接受一个 char 类型的参数,如果参数是一个数字(即介于 ‘0’ 到 ‘9’ 之间的字符),则返回 true;否则,返回 false。

public class Main {  
    public static void main(String[] args) {  
        char ch1 = '5';  
        char ch2 = 'a';  
        char ch3 = '!';  
  
        // 检查ch1是否是数字  
        if (Character.isDigit(ch1)) {  
            System.out.println(ch1 + " 是一个数字");  
        } else {  
            System.out.println(ch1 + " 不是一个数字");  
        }  
  
        // 检查ch2是否是数字  
        if (Character.isDigit(ch2)) {  
            System.out.println(ch2 + " 是一个数字");  
        } else {  
            System.out.println(ch2 + " 不是一个数字");  
        }  
  
        // 检查ch3是否是数字  
        if (Character.isDigit(ch3)) {  
            System.out.println(ch3 + " 是一个数字");  
        } else {  
            System.out.println(ch3 + " 不是一个数字");  
        }  
    }  
}
5 是一个数字  
a 不是一个数字  
! 不是一个数字

Character.isDigit 方法能够准确地判断给定的字符是否为数字。这是因为它内部使用了字符的Unicode值来进行比较,而 ‘0’ 到 ‘9’ 的Unicode值恰好是连续的,且可以被轻松地识别出来。

N个数的排序与查

从键盘输入N个整数,并输出指定的某个整数在这N个整数中的按照由小到大的顺序排列的位次(最小的位次是1,最大的位次是N,指定的整数如果不在这N个数中,则其位次是-1)

输入格式: 整数个数,指定的整数值

输出格式: 指定的整数的位次

输入样例: 在这里给出一组输入。例如: 3 12 4 7 4

输出样例: 在这里给出相应的输出。例如: 1

import java.util.Scanner;  // 导入Scanner类,用于接收用户输入  
  
public class Main {  // 定义一个名为Main的公共类  
    public static void main(String[] args) {  // 主方法,程序的入口点  
        Scanner in = new Scanner(System.in);  // 创建一个Scanner对象in,用于从标准输入(通常是键盘)读取数据  
        int a = in.nextInt(); // 读取用户输入的第一个整数,作为数组的长度  
        int[] b = new int[a];  // 根据用户输入的长度a,创建一个整型数组b  
    
        // 使用for循环读取用户输入的数组元素  
        for (int i = 0; i < a; i++) {    
            b[i] = in.nextInt();  // 读取用户输入的下一个整数,并将其存储在数组b的索引i处  
        }    
    
        int c = in.nextInt(); // 读取用户输入的另一个整数c,作为要查找的元素  
    
        // 使用冒泡排序算法对数组b进行升序排序  
        for (int m = 0; m < a - 1; m++) {    
            for (int i = 0; i < a - m - 1; i++) {    
                if (b[i] > b[i + 1]) {  // 如果当前元素大于下一个元素  
                    int temp = b[i];  // 交换两个元素的位置  
                    b[i] = b[i + 1];    
                    b[i + 1] = temp;    
                }    
            }    
        }    
    
        int j = -1; // 初始化变量j为-1,用于表示如果未找到元素c,则输出-1  
    
        // 使用for循环查找元素c在数组b中的位置  
        for (int m = 0; m < a; m++) {    
            if (c == b[m]) {  // 如果当前元素等于c  
                j = m + 1; // 更新j为当前元素的索引+1(因为索引从0开始,而题目要求从1开始计数)  
                break; // 找到后退出循环  
            }    
        }    
    
        System.out.println(j); // 输出变量j的值,即元素c在数组b中的位置(如果找到的话),或者-1(如果未找到)  
    }    
}

冒泡排序(Bubble Sort) 是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小(或越大)的元素会经由交换慢慢“浮”到数列的顶端。
冒泡排序算法的工作原理如下:
比较相邻的元素。如果第一个比第二个大(升序排序),就交换它们两个;
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数;
针对所有的元素重复以上的步骤,除了最后一个;
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
下面是冒泡排序的一个基本实现(Java语言):

public class BubbleSort {  
    public static void bubbleSort(int[] arr) {  
        int n = arr.length;  
        boolean swapped;  
        for (int i = 0; i < n - 1; i++) {  
            swapped = false;  
            for (int j = 0; j < n - i - 1; j++) {  
                if (arr[j] > arr[j + 1]) {  
                    // 交换 arr[j+1] 和 arr[j]  
                    int temp = arr[j];  
                    arr[j] = arr[j + 1];  
                    arr[j + 1] = temp;  
                    swapped = true;  
                }  
            }  
            // 如果在这一趟遍历中没有发生交换,说明数组已经有序,可以提前结束  
            if (!swapped)  
                break;  
        }  
    }  
  
    public static void main(String[] args) {  
        int[] arr = {64, 34, 25, 12, 22, 11, 90};  
        bubbleSort(arr);  
        System.out.println("Sorted array: ");  
        for (int i = 0; i < arr.length; i++)  
            System.out.print(arr[i] + " ");  
        System.out.println();  
    }  
}

在这个实现中,我们添加了一个swapped标志,用于检查在一次遍历中是否发生了交换。如果没有发生交换,这意味着数组已经是有序的,因此可以提前结束排序过程。这是一个优化,可以在最好的情况下(即数组已经是有序的)将时间复杂度降低到O(n)。然而,在最坏的情况下(即数组完全逆序),时间复杂度仍然是O(n^2)。

期末编程作业计分规则

PTA上的题目集的排名页以总分(满分不一定是100分)的形式按排名顺序显示每个同学的成绩,但相同分数的同学无论排名是靠前还是最后得分都是一样的。为了表示排名区分度,根据排名给出了一个简单的计分规则,以示有所区分。计分规则如下:
成绩折合成100分(取整),然后将班级人数按输入的百分比分成四个个档(如前三档人数的百分比分别为10%、40%、40%,则输入10、40
、40,各档人数均向上取整,剩下的则为最后一档人数),给出一个减分序列,每档所要减去的分数为减分序列中对应的位置及之前的值的总和。
如一个班级有10个同学,若得分都是100分,减分序列为1、3、2、2,若按10%、40%、40%的人数比例的排名分别减去1分、4分、6分、8分。这样每个同学最后的总分得分依次为:100、96、96、96、96、94、94、94、94、92。
要求编程实现根据上述计分规则计算后的成绩得分,按原排名先后输出每个同学的百分制最后得分。

输入格式:
输入四行,第一行输入班级人数和满分分数,第二行按排名顺序输入每个同学的分数,第三行输入各档分数的人数百分比(三项),第四行输入减分序列。

输出格式: 输出根据计分规则计算后的百分制得分,两个成绩之间以两个空格隔开

注意:最后一个数后面有两个空格

输入样例1: 在这里给出一组输入。例如: 10 100 100 100 100 100 100 100 100 100 100 100 10
40 40 1 3 2 2

输出样例1: 在这里给出相应的输出。例如: 99 96 96 96 96 94 94 94 94 92

输入样例2: 在这里给出一组输入。例如: 7 120 110 95 95 92 92 92 88 10 20 40 0 1 1 1

输出样例2: 在这里给出相应的输出。例如: 91 78 78 74 74 74 70

import java.util.Scanner; // 导入Scanner类,用于从标准输入读取数据  
  
public class Main { // 定义一个公共类Main  
  
    public static void main(String[] args) { // 主方法,程序的入口点  
        Scanner scanner = new Scanner(System.in); // 创建一个Scanner对象,用于读取标准输入  
  
        // 输入班级人数和满分分数  
        int numStudents = scanner.nextInt(); // 读取班级人数  
        int fullScore = scanner.nextInt(); // 读取满分分数  
  
        // 输入每个同学的分数  
        int[] scores = new int[numStudents]; // 创建一个整型数组,用于存储每个学生的分数  
        for (int i = 0; i < numStudents; i++) { // 遍历数组,为每个学生的分数赋值  
            scores[i] = scanner.nextInt(); // 读取每个学生的分数  
        }  
  
        // 输入各档分数的人数百分比  
        int[] percentage = new int[4]; // 创建一个整型数组,用于存储各档的人数百分比
        for (int i = 0; i < 3; i++) { // 遍历数组,为各档的人数百分比赋值  
            percentage[i] = scanner.nextInt(); // 读取每个档的人数百分比  
        }  
  
        // 输入减分序列  
        int[] deduction = new int[4]; // 创建一个整型数组,用于存储减分序列
        for (int i = 0; i < 4; i++) { // 遍历数组,为减分序列赋值  
            deduction[i] = scanner.nextInt(); // 读取每个减分数  
        }  
  
        // 计算每个同学的最终得分  
        int[] finalScores = calculateFinalScores(numStudents, fullScore, scores, percentage, deduction); // 调用方法计算每个学生的最终得分  
  
        // 输出最终得分  
        for (int i = 0; i < numStudents; i++) { // 遍历数组,输出每个学生的最终得分  
            System.out.print(finalScores[i] + "  "); // 打印每个学生的最终得分,后跟两个空格  
        }  
        System.out.println(); // 打印换行符,结束输出  
    }  
  
    // 计算每个同学的最终得分  
    private static int[] calculateFinalScores(int numStudents, int fullScore, int[] scores, int[] percentage, int[] deduction) { // 定义一个私有静态方法,用于计算每个学生的最终得分  
        int[] finalScores = new int[numStudents]; // 创建一个整型数组,用于存储每个学生的最终得分  
  
        // 将成绩折合成100分  
        for (int i = 0; i < numStudents; i++) { // 遍历数组,将每个学生的分数折合成100分制  
            finalScores[i] = (int) Math.round(((double) scores[i] / fullScore) * 100); // 计算每个学生的折合分数,并四舍五入  
        }  
  
        // 计算各档人数  
        int[] tierSizes = calculateTierSizes(numStudents, percentage); // 调用方法计算各档人数  
  
        // 计算每个同学的减分  
        int currentDeduction = 0; // 初始化当前减分数为0  
        int tierIndex = 0; // 初始化当前档次索引为0  
        int currentTierSize = tierSizes[tierIndex]; // 初始化当前档次的人数  
        for (int i = 0; i < numStudents; i++) { // 遍历数组,计算每个学生的减分  
            if (i < currentTierSize) { // 如果当前学生在当前档次内  
                finalScores[i] -= currentDeduction; // 从学生的折合分数中减去当前减分数  
            } else { // 如果当前学生不在当前档次内  
                tierIndex++; // 移到下一个档次  
                currentTierSize += tierSizes[tierIndex]; // 更新当前档次的人数(这里应该是错误的,因为currentTierSize应该只存储当前档次的学生数)  
                currentDeduction += deduction[tierIndex]; // 更新当前减分数  
                finalScores[i] -= currentDeduction; // 从学生的折合分数中减去更新后的减分数  
            }  
        }  
  
        return finalScores; // 返回存储每个学生最终得分的数组  
    }  
  
    // 计算各档人数  
    private static int[] calculateTierSizes(int numStudents, int[] percentage) { // 定义一个私有静态方法,用于计算各档人数  
        int[] tierSizes = new int[4]; // 创建一个整型数组,用于存储各档人数(这里分配了4个元素,但percentage可能只有3个元素)  
        int remainingStudents = numStudents; // 初始化剩余学生数为班级总人数  
        for (int i = 0; i < 3; i++) { // 遍历percentage数组(但只到第3个元素)  
            tierSizes[i] = (int) Math.ceil(((double) percentage[i] / 100) * numStudents); // 计算当前档次的学生数,并向上取整  
            remainingStudents -= tierSizes[i]; // 更新剩余学生数  
        }  
        tierSizes[3] = remainingStudents; // 将剩余学生数分配给最后一个档次  
        return tierSizes; // 返回存储各档人数的数组  
    }  
}

二维方阵变变变

有4行,4列的数据组成的矩阵。
1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

它经过顺时针90度旋转后的效果为:(旋转角度值设为 90 )
13 9 5 1

14 10 6 2

15 11 7 3

16 12 8 4

顺时针180度旋转后的效果为:(旋转角度值设为 180 )
16 15 14 13

12 11 10 9

8 7 6 5

4 3 2 1

逆时针90度旋转后的结果为:(旋转角度值设为 -90 )
4 8 12 16

3 7 11 15

2 6 10 14

1 5 9 13

输入格式: 首行包括:(1)二维矩阵的行(列)数n,(2)矩阵旋转的角度,从90、180、-90中取一个;
接下来是n行n列的整数,数据之间以空格分隔,组成一个方阵。

输出格式: 矩阵按指定角度旋转后的结果。输出时按行、列进行组织。每行的数据之间有一个空格;行末尾数据后没有空格。

输入样例1:
4 90

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

输出样例1:
13 9 5 1

14 10 6 2

15 11 7 3

16 12 8 4

输入样例2:
4 180

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

输出样例2:
16 15 14 13

12 11 10 9

8 7 6 5

4 3 2 1

输入样例3:
4 -90

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

输出样例3:
4 8 12 16

3 7 11 15

2 6 10 14

1 5 9 13

import java.util.Scanner; // 导入Scanner类,用于接收用户输入  
  
public class Main { // 定义一个名为Main的公共类  
    public static void main (String[] args) { // 主方法的定义,程序的入口点  
        Scanner sc=new Scanner(System.in); // 创建一个Scanner对象sc,用于从标准输入(键盘)读取数据  
        int n=sc.nextInt(); // 读取一个整数n,表示矩阵的维度(n*n)  
        int du=sc.nextInt(); // 读取一个整数du,表示旋转的度数  
        sc.nextLine(); // 读取并丢弃输入中的当前行剩余部分,主要是用来消耗掉输入整数后的换行符  
        int[][] arr=new int[n][n]; // 根据n的值,初始化一个n*n的二维数组arr  
        int i,j; // 声明两个整型变量i和j,用于循环遍历二维数组  
        for(i=0;i<n;i++) // 外层循环,遍历矩阵的行  
            for(j=0;j<n;j++) // 内层循环,遍历矩阵的列  
                arr[i][j]=sc.nextInt(); // 读取输入值并赋值给二维数组arr的相应位置  
          
        // 根据旋转度数du的值,执行不同的旋转操作  
        if(du==90) // 如果旋转度数为90度  
            for(j=0;j<n;j++) // 遍历列  
            {  
                for(i=n-1;i>0;i--) // 从倒数第二行开始向上遍历行  
                    System.out.print(arr[i][j]+" "); // 打印当前元素后跟一个空格  
                System.out.println(arr[0][j]); // 打印第一行的元素,并换行  
            }  
        else if(du==180) // 如果旋转度数为180度  
            for(i=n-1;i>=0;i--){ // 从最后一行开始向下遍历行  
                for(j=n-1;j>0;j--) // 从倒数第二列开始向左遍历列  
                    System.out.print(arr[i][j]+" "); // 打印当前元素后跟一个空格  
                System.out.println(arr[i][0]); // 打印当前行的第一列元素,并换行  
                // 注意:这里的缩进和括号使用可能导致误解,原意是在内层循环结束后换行  
            }  
        else // 如果旋转度数不是90度或180度(这里默认是270度或未指定,但代码只处理了270度的情况)  
            for(j=n-1;j>=0;j--) // 遍历列,从最后一列开始  
                {  
                for(i=0;i<n-1;i++) // 遍历行,但不包括最后一行  
                    System.out.print(arr[i][j]+" "); // 打印当前元素后跟一个空格  
                System.out.println(arr[n-1][j]); // 打印最后一行的当前列元素,并换行  
                }  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甘一十

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值