java编程强化练习(一)

1. 素数因子数字和

【问题描述】从键盘终端输入一个正的整数,求其所有素数因子各位上数字之和。例如:44=2*2*11,素数因子为2,2,11,和为2+2+1+1=4
【输入形式】一个正的整数
【输出形式】整数的所有素数因子各位上数字之和
【样例输入】100
【样例输出】14
【样例说明】
【评分标准】

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    public static boolean prime(int num)
    {
        for(int i=2;i<Math.sqrt(num);i++)
        {
            if(num%i==0)
                return false;
        }
        return true;
    }
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int num=scanner.nextInt();
        int sum=0;
        for (int i = 2; i <= num; i++) {
            while((num % i) == 0 &&prime(i))
            {
                    for(int j=i;j>0;j=j/10)
                    {
                        sum=sum+j%10;
                    }

                num=num/i;
            }
        }
        System.out.println(sum);
    }
}

2. 计算公式:求π的值b

【问题描述】

给定一个精度值e,用下列公式计算&pi;的近似值,要求前后两次&pi;的迭代之差的绝对值小于e,给出相应的最小迭代次数n和最后一次计算的&pi;的值。
&pi;/2=1+1!/3+2!/(3&times;5)+3!/(3&times;5&times;7)+&hellip;+(n-1)!/(3&times;5&times;7&times;&hellip;&times;(2n-1))

【输入形式】

从控制台输入e( e>=0.000001 )的值。

【输出形式】

输出迭代次数n和最后一次计算的&pi;的值(以一个空格分隔,并且输出&pi;时要求小数点后保留7位有效数字)。

【样例输入】

0.000003

【样例输出】

19 3.1415912

【样例说明】

输入的精度e为0.000003,当n为17时,计算的&pi;值为3.1415864,n为18时计算的&pi;值为3.1415896,两者之差为0.0000032,大于给定的精度值,所以需要继续计算。当n为19时,计算的&pi;值为3.1415912,与上次之差为0.0000016,小于给定的精度值,所以最小迭代次数为19,输出的&pi;值为3.1415912。

注意:
(1) 为保证计算精度,请使用double数据类型保存计算数据。
(2) 应至少迭代两次,即:n>=2。

【评分标准】

该题要求输出最小迭代次数和&pi;的值,共有5个测试点。

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Scanner;
class Main{
    public static void main(String arg[]) {
        Scanner scanner = new Scanner(System.in);
        double e = scanner.nextDouble();
        int a = 2;
        double sum = 1.0;
        double t = 1.0;
        while (2*t>=e) {
            double pro = 1.0;
            double b = 1.0;
            for (int i = 1; i <=a-1; i
                    ++) {
                pro = pro * i;
                b = b * (2 * i + 1);
            }
            t = pro / b;
            sum = sum + t;
            a++;
        }
        DecimalFormat s=new DecimalFormat("#0.0000000");
        System.out.print((a-1) + " ");
        System.out.println(s.format(sum*2.0) );
    }
        }

3. 字母频率统计

【问题描述】

编写程序从标准输入中读入一段英文,统计其中小写字母出现次数,并以柱状图的形式显示其出现次数。

【输入形式】

在标准输入上输入一段英文文章(可能有一行,也可能有多行),在新的一行的开头输入ctrl+z键表示结束。

【输出形式】

在屏幕上依次输出表示每个小写字母出现次数的柱状图(以&ldquo;*&rdquo;字符表示柱状图,空白处用空格字符表示,某个小写字母出现多少次,就显示多少&ldquo;*&rdquo;字符;柱状图的高度以出现最多的字母次数为准),在最后一行依次输出26个小写字母。

【样例输入】

The computing world has undergone a
revolution since the publication of
The C Programming Language in 1978.


【样例输出】

【样例说明】

在输入的英文短文中,小写字母a出现了6次,所以其上输出了6个字符"*"。出现次数最多的是字母n,所以柱状图的高度为9个字符。字母j没有出现,所以其上都为空格字符。

【评分标准】

该题要求输出柱状图表示的字母出现次数,共有5个测试点。

import java.util.Scanner;

public class LetterHistogram {
    public static void main(String[] args) {
        // 读取输入文本
        Scanner scanner = new Scanner(System.in); // 创建Scanner对象以读取用户输入
        StringBuilder builder = new StringBuilder(); // 用于构建用户输入的文本
        while (scanner.hasNextLine()) { // 检查是否还有下一行输入,这个方法也可以记一下。如果存在下一行,则返回true;如果输入源已经没有更多的行可供读取,则返回false。
            String line = scanner.nextLine(); // 读取用户输入的当前行,就是输入哪
            if (line.isEmpty()) { // 如果当前行为空行,则退出循环
                break;
            }
            builder.append(line).append("\n"); // 将当前行添加到StringBuilder对象中,就相当于是将三个不同的对象合为一个对象,便于遍历和输出(append就是附加增补的意思,可以记住这个方法)。
        }
        String text = builder.toString(); // 将StringBuilder对象转换为字符串,得到用户输入的完整文本

        // 统计小写字母出现次数
        int[] letterCounts = new int[26]; // 创建长度为26的整型数组,用于存储每个字母出现的次数
        for (char c : text.toCharArray()) { // 遍历文本中的每个字符,text.toCharArray()将字符串转换为一个字符数组,以便可以遍历每个字符并进行相应的操作。
            if (Character.isLowerCase(c)) { // 如果字符是小写字母
                letterCounts[c - 'a']++; // 增加对应字母的计数
            }
        }

        // 计算最多出现次数
        int maxCount = 0; // 用于存储出现次数的最大值
        for (int count : letterCounts) { // 遍历字母计数数组
            if (count > maxCount) { // 如果当前计数大于最大值
                maxCount = count; // 更新最大值
            }
        }

        // 输出柱状图
        for (int i = maxCount; i > 0; i--) { // 从最大值开始递减
            StringBuilder row = new StringBuilder(); // 用于构建柱状图的每一行
            for (int count : letterCounts) { // 遍历字母计数数组
                if (count >= i) { // 如果计数大于等于当前行数
                    row.append("*"); // 添加"*"表示该位置有一个小写字母
                } else {
                    row.append(" "); // 添加空格表示该位置没有小写字母
                }
            }
            System.out.println(row); // 输出当前行的柱状图
        }

        // 输出字母
        for (char c = 'a'; c <= 'z'; c++) { // 遍历小写字母
            System.out.print(c); // 输出字母
        }
    }
}

scanner.nextLine(); // 读取换行符,在这里解释一下为什么,这一句能不能去掉         //如果不使用scanner.nextLine()读取换行符,会导致在读取方阵元素之前,下一行的第一个元素会被跳过。         //在Java中,当你使用nextInt()方法读取一个整数后,光标会停留在该整数后的换行符上。         // 如果直接进入下一个循环,使用nextLine()读取下一行时,会返回一个空字符串,因为它会读取到之前的换行符,而不是下一行的内容。         //为了解决这个问题,我们需要在调用nextLine()之前,使用一个额外的scanner.nextLine()来读取并忽略掉前一个整数后的换行符。这样,下一行的内容才会被正确读取。         //所以一定要记住这种多行输入的字符串要先读取换行符,否则整个程序的运行会出现无法找到的错误。

4.求三角形面积

【问题描述】

若已知三角形三个边的长度分别为a,b,c(并假设三个边长度的单位一致,在本编程题中忽略其单位),则可以利用公式:

    

求得三角形的面积,其中:s=(a+b+c)/2。编程实现从控制台读入以整数表示的三个边的长度(假设输入的长度肯定可以形成三角形),然后利用上述公式计算面积并输出,结果小数点后保留3位有效数字。

【输入形式】

从控制台输入三个整数表示三角形三个边的长度,以空格分隔三个整数。

【输出形式】

向控制台输出求得的三角形的面积,小数点后保留三位有效数字。

【输入样例】

4 4 6

【输出样例】

7.937

【样例说明】

输入的三角形三个边的长度分别为4、4、6,利用上述计算公式可以求得三角形的面积为7.937,小数点后保留三位有效数字。

【评分标准】

该题要求输出三角形的面积,共有5个测试点。

import java.util.Scanner;

public class TriangleArea {
    public static void main(String[] args) {
        // 读取三个整数表示三角形的边长
        Scanner scanner = new Scanner(System.in);//输入
        int a = scanner.nextInt();//输入a
        int b = scanner.nextInt();//输入b
        int c = scanner.nextInt();//输入c

        // 计算半周长
        double s = (a + b + c) / 2.0;//这里要注意要取浮点型,否则最后结果会出错。

        // 计算三角形的面积
        double area = Math.sqrt(s * (s - a) * (s - b) * (s - c));

        // 输出结果,保留三位有效数字
        System.out.printf("%.3f", area);//这种保留小数的方法是比较简单的,还有其他方法,但这个最好用,在第二题中就有一种。
    }
}

5.求小岛面积

【问题描述】

用一个二维方阵(最小为3X3,最大为9X9)表示一片海域。方阵中的元素只由0和1组成。1表示海岸线。计算由海岸线围起来的小岛面积(即:由1围起来的区域中0的个数)。如下图所示6X6方阵表示的小岛面积为9:
0 0 0 1 0 0
0 0 1 0 1 0
0 1 0 0 0 1
1 0 0 0 1 0
1 0 1 0 1 0
1 1 0 1 1 1
上述方阵表示的海域满足下面两个要求:
1、小岛只有一个。
2、用1表示的海岸线肯定可以封闭成一个小岛,但有可能是凸的,也有可能是凹的。所以在判断时:对于方阵中的任意一个元素0,如果其位于同一行上的两个1之间,并且位于同一列上的两个1之间,则该元素肯定在1围起来的区域中。不符合该规定的其它情况不考虑。

【输入形式】

先从标准输入中输入方阵的阶数,然后从下一行开始输入方阵的元素(只会输入0或1),各元素之间以一个空格分隔,每行最后一个元素后没有空格,但会有回车换行符。

【输出形式】

在标准输出上输出用整数表示的小岛面积。

【输入样例】

6
0 0 0 1 0 0
0 0 1 0 1 0
0 1 0 0 0 1
1 0 0 0 1 0
1 0 1 0 1 0
1 1 0 1 1 1

【输出样例】

9

【样例说明】

输入是6X6的方阵。该方阵中由1围起来的区域内有9个0,所以输出的小岛面积为9。注意:最下方的三个元素1(即第5行第3列的1、第6行第2列的1、第6行第4列的1)组成了一个凹形的海岸线,第6行第3列的0不在海岸线内,所以不应算作小岛面积。

【评分标准】

该题要求输出用整数表示的小岛面积,共有5个测试点。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int[][] a;
        int i, j, n, d = 0, p = 0, x, y;
        n = scanner.nextInt(); // 方阵阶数
        a = new int[n][n];
        // 根据阶数创建方阵
        for (i = 0; i <= n - 1; i++) {
            for (j = 0; j <= n - 1; j++) {
                a[i][j] = scanner.nextInt();
            }
        }
        // 遍历方阵
        for (i = 0; i <= n - 1; i++) {
            for (j = 0; j <= n - 1; j++) {
                if (a[i][j] == 1) // 遇到“1”则跳过
                    continue;
                p = 0; // 用来记被遍历到的数字的上下左右遇到的1的个数
                // 判断左边有无1,有则p+1
                for (x = i; x >= 0; x--) {
                    y = j;
                    if (a[x][y] == 1) {
                        p++;
                        break;
                    }
                }
                // 判断右边有无1,有则p+1
                for (x = i; x <= n - 1; x++) {
                    y = j;
                    if (a[x][y] == 1) {
                        p++;
                        break;
                    }
                }
                // 判断下边有无1,有则p+1
                for (y = j; y >= 0; y--) {
                    x = i;
                    if (a[x][y] == 1) {
                        p++;
                        break;
                    }
                }
                // 判断上边有无1,有则p+1
                for (y = j; y <= n - 1; y++) {
                    x = i;
                    if (a[x][y] == 1) {
                        p++;
                        break;
                    }
                }
                if (p == 4) // 上下左右都有1说明该点在岛上,则d+1
                    d++;
            }
        }
        System.out.println(d);
    }
}

6.查找关键字出现的位置(标准输入)

【问题描述】

从标准输入中读入一行C源程序,查找该行程序中控制流关键字(while, for, if)的出现位置。按出现顺序输出其出现的位置(用在该行上第几个字符表示)。要求字符串常量中出现的关键字不应计算,同时该行C程序满足下列规定:
1、该行程序符合C语言语法要求,在该行程序上有可能有多条C语言语句,字符数不会超过300。
2、双引号只会用在字符串常量中,其它地方不会出现双引号字符。
3、程序中的所有标识符只由字母和数字组成。
4、程序中没有注释语句。

【输入形式】

从标准输入中读入一行C语言源程序,在行的末尾有回车换行。

【输出形式】

按照出现顺序在标准输出上输出关键字出现的位置,每行输出一个关键字的位置。位置的输出格式是:先输出关键字,后面紧跟着冒号:,然后是用整数表示的在该行上的位置。若没有关键字则什么都不输出。

【输入样例1】

假如从标准输入读入的一行程序为:
scanf ( "%d" , &ifn ); for ( i=0 ; i<ifn ; i++ ) scanf ( "%d" , &a[i] );

【输出样例1】

for:24

【样例说明1】

在输入的一行C语言程序中只有一个控制流关键字for。for关键字在该行上的第24个字符位置处,所以输出:for:24。

【输入样例2】

假如从标准输入读入的一行程序为:
while (i<n) {  if(if1<forAndwhile[i])    if1=forAndwhile[i]; }  for(i=0;i<n;i++)sum+=forAndwhile[i]; for(i=0;i<n;i++)mul*=forAndwhile[i]; printf("The max of for and while is :%d\n",if1);

【输出样例2】

while:1
if:16
for:65
for:102

【样例说明2】

在该程序中有一个while、一个if和两个for关键字。其中while位于第1个字符处,if在第16个字符处,第一个for在第65个字符处,第二个for在第102个字符处,分别按顺序输出。注意:字符串常量中出现的for和while不是关键字,所以不应输出。同样,在一些变量名中作为子串出现的if、for和while也不是关键字。

【评分标准】

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();

        // 使用正则表达式匹配控制流关键字
        Pattern pattern = Pattern.compile("\\b(while|for|if)\\b");
        Matcher matcher = pattern.matcher(line);

        int index = 0;
        while (matcher.find()) {
            String keyword = matcher.group();

            // 检查关键字是否在字符串常量中
            if (!isInsideStringConstant(line, matcher.start())) {
                index++;
                System.out.println(keyword + ":" + (matcher.start()+1));
            }
        }
    }

    // 检查指定位置是否在字符串常量中
    private static boolean isInsideStringConstant(String line, int position) {
        boolean insideString = false;
        boolean insideEscapeSequence = false;

        for (int i = 0; i <position; i++) {
            char currentChar = line.charAt(i);

            if (!insideEscapeSequence) {
                if (currentChar == '\"') {
                    insideString = !insideString;
                } else if (currentChar == '\\') {
                    insideEscapeSequence = true;
                }
            } else {
                insideEscapeSequence = false;
            }
        }

        return insideString;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值