算法分析(含答案)笔试题

本文涵盖了多个算法笔试题目,包括身份证号验证、字符串处理、数组拷贝、排序算法、二分查找、回文素数等。通过实例代码详细解释了如何解决这些问题,涉及正则表达式、字符串截取、递归、冒泡排序、动态规划等多种编程技巧。
摘要由CSDN通过智能技术生成
  1. 判断身份证:要么是 15 位,要么是 18 位,最后一位可以为字母,并写
    出程序提出其中年月日。要求:
    写出合格的身份证的正则表达式,
    ^(\d{15}|\d{17}[\dx])$
    写程序提取身份证中的年月日
    public class IdCard
    {
    private String idCard;//私有变量
    public IdCard(){}//构造方法
    //构造方法
    public IdCard(String idCard){
    this.idCard=idCard;
    }

public void setIdCard(String idCard)
{
this.idCard=idCard;
}

public String getIdCard()
{
return idCard;
}

//从身份证号码中截取生日
public String getBirthday()
{
return this.getIdCard().substring(6, 14);
}

public static void main(String args[])
{
ShenFenZheng sfz = new
ShenFenZheng("420154199908157841");
//调用 getBirthday()方法获取生日
System.out.println("生日:" + sfz.getBirthday());
} }
627. 对于一个字符串,请设计一个高效算法,找到第一次重复出现的字符保
证字符串中有重复的字符,字符串的长度小于等于 500.
package com.bjsxt;
import java.util.ArrayList;
import java.util.List;
public class FirstRepeat {
public static void main(String[] args) {
System.out.println(findFirstRepeat("pmedmitjtckhxwhvpwemznh
mhzhpueainchqrftkmbjlradhmjekcqzansyzkvqhwnrdgzdbzewdmxkzrscik
daugbvygntrifnolehdtrqjlasofuvzeijbmzehkxknmjekcxswqldknysfsxr
qaqzp",152));
}
//返回:y
public static char findFirstRepeat(String A, int n) {
String[] str=A.split("");
for(int x=0;x<n;x++){
int index=0;
int num=0;
//对于每一个值,都需要从前开始遍历
while(index<=x){
if(str[index].equals(str[x])){
num++;
}
index++;
}
//该值出现了两次,说明重复了
if(num>1){
char flag='x';
flag=str[x].toCharArray()[0];
return flag;
}
}
//返回该值说明已经没有重复的
return 'p';
}
}
628. 写一个完整函数,实现拷贝数组
public class test {
public static void main(String[] args) {
int [] arr1 = {10,20,30,40,50};
int [] arr2 = CopyArray(arr1);
System.out.println(Arrays.toString(arr2));
}
private static int[] CopyArray(int[] arr) {
int [] arr2 = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
arr2[i] = arr[i];
}
return null; } }
629. 写一排序算法,输入 10 个数字,以逗号分开,可根据参数选择升序或者
降序排序,须注明是何种排序算法。
package cn.bjsxt.demo;
import java.util.Scanner;
public class SortDemo {
/**

  • 给定的字符串使用,号分隔
  • @param strNumber
  • @return/
    public static String [] split(String strNumber){
    String [] strSplit=strNumber.split(",");
    return strSplit;
    }
    /
    *
  • 将String类型的数组转换成int类型的数组
  • @param strSplit
  • @return/
    public static int [] getInt(String [] strSplit){
    int arr[]=new int[strSplit.length];
    for (int i = 0; i < strSplit.length; i++) {
    arr[i]=Integer.parseInt(strSplit[i]);
    }
    return arr;
    }
    /
    *
  • 冒泡排序
  • @param arr/
    public static void sort(int [] arr){
    for (int i = 0; i < arr.length-1; i++) {
    for (int j = 0; j < arr.length-1-i; j++) {
    if (arr[j]>arr[j+1]) {
    change(arr,j,j+1);
    } } } }
    /
    *
  • 两数交换的方法
  • @param arr 数组
  • @param x 数组中元素的下标
  • @param y 数组中元素的下标/
    public static void change(int [] arr,int x,int y){
    int temp=arr[x];
    arr[x]=arr[y];
    arr[y]=temp;
    }
    /
    *
  • 测试类
  • @param args
    */
    public static void main(String[] args) {
    Scanner input=new Scanner(System.in);
    System.out.println("请输入一个数字串,每个数字以逗号分隔
    ");
    String str=input.next();
    //调用方法
    String [] s=split(str);//使用逗号分隔
    int [] arr=getInt(s);//调有获得整型数组的方法
    sort(arr);//调用排序的方法
    for (int i : arr) {
    System.out.print(i+"\t");
    } } }
  1. 判断字符串是否是这样的组成的,第一个字母,后面可以是字母、数字、
    下划线、总长度为 5-20。
    package cn.bjsxt.demo;
    import java.util.Scanner;
    public class StringDemo {
    public static void main(String[] args) {
    Scanner input=new Scanner(System.in);
    System.out.println("请输入一个字符串,第一个字符必须是字母:
    ");
    String str=input.next();
    if (str.length()<5||str.length()>20) {
    System.out.println("对不起,字符串的长度必须在5-20之 间!");
    }else{
    char []ch=str.toCharArray();
    if (Character.isLetter(ch[0])) {//判断第一个字符是否是
    字母
    for (int i = 1; i < ch.length; i++) {
    if
    (!Character.isLetterOrDigit(ch[i])&&ch[i]!='_') {
    System.out.println("字符串不符合要求");
    break; } } } } } }
  2. 已排好序的数组 A,一般来说可用二分查找可以很快找到,现有一特殊
    数组 A,它是循环递增的,如 a[]={17, 19 ,20, 25, 1, 4, 7, 9},在这样的
    数组中找一元素,看看是否存在。请写出你的算法,必要时可写伪代码,并
    分析其空间,时间复杂度。
    思路说明:循环递增数组有这么一个性质:以数组中间元素将循环递增数组划分为两部
    分,则一部分为一个严格递增数组,而另一部分为一个更小的循环递增数组。当中间元
    素大于首元素时,前半部分为严格递增数组,后半部分为循环递增数组;当中间元素小
    于首元素时,前半部分为循环递增数组;后半部分为严格递增数组。
    记要检索的元素为 e,数组的首元素为 a[low],中间元素为 a[mid],末尾元素为 a[high]。
    则当 e 等于 a[mid] 时,直接返回 mid 的值即可;当 e 不等于 a[mid] 时:
  1. a[mid] > a[low],即数组前半部分为严格递增数组,后半部分为循环递增数组时,若
    key 小于 a[mid]并且不小于 a[low]时,则 key 落在数组前半部分;否则,key 落在数组
    后半部分。
  2. a[mid] < a[high],即数组前半部分为循环递增数组,后半部分为严格递增数组时,
    若 key 大于 a[mid]并且不大于 a[high]时,则 key 落在数组后半部分;否则,key 落在
    数组前半部分。
    这种方式的时间复杂度为:O(log(n)),空间复杂度为 O(1)。
    public class TestBinarySearch {
    public static void main(String[] args) {
    // 定义数组
    int[] a = { 17, 19, 20, 21, 25, 1, 4, 7 };
    // 调用改进后的二分查找法求索引
    int pos = search(a, 7);
    System.out.println("要查找的元素的索引为:" + pos);
    }
    /** 改进后的二分查找法:e 为要查找的元素 */
    public static int search(int[] a, int e) {
    int low = 0;
    int high = a.length - 1;
    int mid = 0;
    int pos = -1; // 返回-1,表示查找失败
    // 如果 low < high,说明循环查找结束,直接返回-1;否则循环查

    while (low <= high) {
    // mid 为中间值索引
    mid = (low + high) / 2;
    // 如果中间值刚好是 e,则查找成功,终止查找,e 的索引为 mid
    if (a[mid] == e) {
    pos = mid;
    break;
    }
    // 如果 a[low] <= a[mid],说明原数组的前半部分是严格递增
    的,后半部分是一个更小的循环递增数组
    if (a[low] <= a[mid]) {
    // 如果要查找的元素 e 小于 a[mid]并且不小于 a[low]时,
    则说明 e 落在数组前半部分
    if (a[low] <= e && e < a[mid]) {
    high = mid - 1;
    } else {// 否则的话,需要在数组的后半部分继续查找
    low = mid + 1;
    }
    } else {// 否则,后半部分是严格递增的,前半部分是一个更
    小的循环递增数组
    // 如果要查找的元素 e 大于 a[mid]并且不大于 a[high]时,
    则说明 e 落在数组后半部分
    if (a[mid] < e && e <= a[high]) {
    low = mid + 1;
    } else {// 否则的话,需要在数组的前半部分继续查找
    high = mid - 1;
    } } }
    return pos; } }
  1. 请编写一个完整的程序,实现如下功能:从键盘输入数字 n,程序自动
    计算 n!并输出。(注 1:n!=123...n, 注 2:请使用递归实现)
    思路说明:因为 n! = (n-1)! * n,所以要求 n!首先要求出(n-1)!,而(n-1)! = (n-1-1)! *
    (n-1),以此类推,直到 n = 1 为止。
    import java.util.Scanner;
    public class TestFactorial {
    public static void main(String[] args) {
    System.out.print("请输入一个整数:");
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    System.out.println(n + "的阶乘是:" + factorial(n));
    }
    /**求阶乘的方法
    /
    public static int factorial(int n) {
    if(n == 1){
    return 1;
    }
    return factorial(n - 1) * n; } }
  2. 请用递归的方法计算斐波那契数列的同项 F(n),已知
    F0=0,F1=1,F(n)=F(n-1)+F(n-2)(n>=2,n∈N*).
    思路说明:斐波那契数列的排列是:0,1,1,2,3,5,8,13,21,34,55,89,
    144……,特别指出的是 0 不是第一项而是第 0 项;因为 F(n)=F(n-1)+F(n-2),所以要
    求 F(n)首先要求出 F(n-1)和 F(n-2),而 F(n-1)=F(n-1-1)+F(n-1-2),以此类推,直
    到,F(2)=F(1)+F(0)为止,已知 F(1) = 1,F(0) = 0。
    import java.util.Scanner;
    public class TestFibo {
    public static void main(String[] args) {
    System.out.print("请输要求斐波那契数列的第几项:");
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    System.out.println("斐波那契数列的第"+ n + "是:" +
    fibo(n));
    }
    public static int fibo(int n) {
    if(n == 0){
    return 0;
    } else if(n == 1){
    return 1;
    }
    return fibo(n -1) + fibo(n - 2);
    } }
  3. 现在有整数数组{11,66,22,0,55,32},请任意选择一种排序算法,用
    Java 程序实现
    冒泡思路说明:
    (1) 最开始将数组看做一个无序数列(个数是数组的长度)与一个有序数列(0 个)的组合;
    (2) 每一趟比较完后, 找到了无序数列的最大值, 将其放到有序数列中(有序数列个数+1);
    (3) N 个数, 比较 N-1 趟;
    (4) 每一趟挨个进行比较:从数组的第一个元素开始, 到无序数列的最后一个为止;
    (5) 如果前边一个大于后边一个, 那么交换位置;
    (6) 每趟比较的次数与趟数有关;
    (7) 根据每趟比较是否发生了交换判断数据是否已经有序,从而进行优化。
    public class TestSort {
    public static void main(String[] args) {
    int[] arr = {11, 66, 22, 0, 55, 32};
    // 调用排序方法
    sort(arr);
    // 输出排除后的数组
    for (int num : arr) {
    System.out.print(num + "\t");
    } }
    public static void sort(int[] arr) {
    // 定义标记
    boolean flag = false;
    int temp;
    // 排序
    // 外层循环控制的是比较的趟数
    for (int i = 0; i < arr.length - 1; i++) {
    // 每一趟比较之前初始化, 否则会保留上一堂比较的结果
    flag = false;
    // 内层循环控制的是每趟比较的次数
    for (int j = 0; j < arr.length - 1 - i; j++) {
    // 挨个进行比较: 从数组的第一个元素开始, 到无序数列的
    最后一个
    if (arr[j] > arr[j + 1]) {
    // 交换
    temp = arr[j];
    arr[j] = arr[j + 1];
    arr[j + 1] = temp;
    //如果发生交换,改变 flag 的值
    flag = true; } }
    if (!flag) {
    break; } } } }
  4. 请根据注释,编码实现下面类的方法
    // 这个类用于存取一组权限,每个权限用非负整数表示的.这组枳限存储在
    // righiString 属性中。如果权限 N 权限存在,rightString 第 N 个字符为“1”,
    否则, 为空格。
    class RightStore {
    public String righString = "";
    // 如果传入的权限 right 存在,该方法返回 true.否期,为 false.,
    // right 为传入的权限的整数值.
    public boolean getRight(int right) {
    return true; }
    // 该方法存储或消除传入的权限.如果 value 为 true,存储传入的权限,
    // 否则淸除该权限.
    // right 为传入的权限的整数值.
    public void setRight(int right, boolean value) {
    } }
    思路说明:我们首先要读懂这道题的意思:righString 这个字符串是用来存储一系列权
    限的,并且权限的取值只有两种:有和没有;在 righString 中使用字符‘1’表示有权
    限,字符空格‘ ’表示没有权限。举个例子:如果 righString 的长度为 3,第一位表示
    对订单系统是否有权限,第二位表示对人员管理系统是否有权限,第三位表示对库存系
    统是否有权限。而方法中的 int right 参数则表示的是字符串的第几位。
    上边这些搞明白之后,方法的编写就简单多了。
    public class RightStore {
    public String righString = "";
    public boolean getRight(int right) {
    //先求得第 right 个字符
    char ch = righString.charAt(right - 1);
    //如果 ch 为'1',返回 true,否则返回 false
    return ch == '1'; }
    public void setRight(int right, boolean value) {
    //如果 value 为 true,存储传入的权限,否则消除权限(改为空格)
    righString.replace(righString.charAt(right - 1), value ?
    '1' : ' ');
    } }
  5. 二分法查询(递归实现)
    思路说明:假设在一个已经排好序的有序序列(N 个元素,升序排
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第一章 绪论作业答案(共50分) 一、分析如下程序中 (1)~ (10)各语句的频度。(每个1分,共10分) Ex( ) { int i , j , t ; (1) for( i=1 ; i<10 ; i++) //n = (2) printf(“\n %d” , i ); //n = (3) for(i=1; i<=2; i++) //n = (4) printf(“\n”); //n = (5) for(i=1; i<=9; i++) //n = { (6) for(j=1; j <= i ; j++) //n = { (7) t = i * j ; //n = (8) printf(“]”,t); //n = } (9) for(j=1; j 0) { if(x > 100) {x -= 10 ; y -- ;} else x ++ ; } 问if 语句执行了多少次?(2分) y--执行了多少次?(2分) x ++执行了多少次?(2分) 三、回答问题(共25分) 书中16页的起泡排序如下: void bubble_sort(int a[],int n){ //将a中整数序列重新排列成自小至大有序的整数序列。 for(i=n-1,change=TRUE;i>=1&&change;--i){ change=FALSE; for(j=0;ja[j+1]{a[j]<-->a[j+1];change=TRUE; } } }//bubble_sort 1.(共15分)分析算法的最佳情况 ,最坏情况和平均情况下各自的时间复杂度(给出分析思路与过程)。 (1) 最佳情况的时间复杂度分析(5分): (2) 最坏情况的时间复杂度分析(5分): (3) 平均情况的时间复杂度分析(5分): 2.(共10分)比较与C语言书中的起泡排序异同,并从时空效率角度说明谁更优。 四、完成如下选择题(每3分,共9分)。 1. 设f为原操作,则如下算法的时间复杂度是( )。 for (i = 1; i*i=1;i--) for(j=1;jA[j+1]) A[j]与A[j+1]对换; 其中n为正整数,则算法在最坏情况下的时间复杂度为( )。 A.O(n) B.O(nlog2n) C. O(n3) D. O(n2)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值