【精选】JAVA入门算法题(三)

版权声明:很高兴认识你,我叫邵龙飞 原创文章,转载请注明 https://blog.csdn.net/qq_37482202/article/details/84714036

把敬业变成习惯。短期来看是为了雇主,长期来看是为了自己。

1.题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。

估计统计字符是所有人都做过的题

这里给出两种思路,第一种思路是比较ASCII码,第二种是使用正则匹配

private static void Method1() {
        int letter=0;
        int space=0;
        int number=0;
        int other=0;
        Scanner scanner=new Scanner(System.in);
        String string=scanner.nextLine();
        char[] chars=string.toCharArray();
        for (char i:chars){
            if ('0'<=i&&i<='9'){
                number++;
            }else if (('a'<=i&&i<='z')||('A'<=i&&i<'Z')){
                letter++;
            }else if (' '==i){
                space++;
            }else {
                other++;
            }
        }
        System.out.println("字符个数:"+letter+" 空格个数:"+space+" 数字个数:"+number+" 其他个数:"+other);
    }
private static void Method2() {
        String E1 = "[a-zA-Z]";//字母
        String E2 = "[0-9]";//数字
        String E3 = "\\s";//空格
        int letter=0;
        int space=0;
        int number=0;
        int other=0;
        Scanner scanner=new Scanner(System.in);
        String string=scanner.nextLine();
        String[] strings=string.split("");
        for (String s:strings){
            if (s.matches(E1)){
                letter++;
            }else if (s.matches(E2)){
                number++;
            }else if (s.matches(E3)){
                space++;
            }else {
                other++;
            }
        }
        System.out.println("字符个数:"+letter+" 空格个数:"+space+" 数字个数:"+number+" 其他个数:"+other);
    }

2.题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。 有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程找出三队赛手的名单。

这道题也是一道非常经典的问题,主要考察全排列的思维,随后筛除

我的第一种解法可能和大家都不一样,个人非常喜欢操作字符串,我于是把所有情况遍历出来,然后使用reolace方法替换掉不符合条件的情况

List<String> yi=Arrays.asList("X","Y","Z");
        List<String> duilie=new ArrayList<>();
        for (int i=0;i<yi.size();i++){
            for (int j=0;j<yi.size();j++){
                for (int k=0;k<yi.size();k++){
                    if (j!=i&&k!=j&k!=i){
                        duilie.add("A:"+yi.get(i)+",B:"+yi.get(j)+",C:"+yi.get(k));
                    }
                }
            }
        }
        System.out.println(duilie);
        for (String s:duilie){
            int length=s.length();
            s=s.replace("A:X","").replace("C:Z","").replace("C:X","");
            if (s.length()==length){
                System.out.println(s);
            }
        }

第二种解法就是大家都能想到的for循环嵌套,if筛选了

char a, b, c;
        for (a = 'x'; a <= 'z'; a++) {
            for (b = 'x'; b <= 'z'; b++) {
                if (a != b) {
                    for (c = 'x'; c <= 'z'; c++) {
                        if (a != c && b != c) {
                            if (a != 'x' && c != 'x' && c != 'z') {
                                System.out.println("A的对手是" + a);
                                System.out.println("B的对手是" + b);
                                System.out.println("C的对手是" + c);
                            }
                        }

                    }
                }
            }
        }

3.题目:一个偶数总能表示为两个素数之和。

(注:哥德巴赫猜想:任一大于2的偶数都可写成两个质数之和。)

我是采用的这样的思路,先对这个数找到所有该范围的素数,然后循环如果这个数减去范围内一个素数的结果是一个宿舍的话就证明是对的,之前找素数和验证素数的思路都有说过

 private static void Method1() {
        Scanner scanner=new Scanner(System.in);
        int number=scanner.nextInt();
        List<Integer> integerList=getPrimeNumber(number);
        for (int i=0;i<integerList.size();i++){
            if (integerList.get(i)>number/2){
                break;
            }
            if (isPerimeNumber(number-integerList.get(i))){
                System.out.println(number+"="+integerList.get(i)+"+"+(number-integerList.get(i)));
            }
        }
    }

    private static boolean isPerimeNumber(int number) {
        int j=0;
        int k=0;
        for (int i=2;i<=number;i++){
            k=(int)sqrt(i+1);
            for (j=2;j<=k;j++){
                if (i%j==0){
                    break;
                }
            }
            if (j==k+1){
                return true;
            }
        }
        return false;
    }

    private static List<Integer> getPrimeNumber(int number) {
        List<Integer> integerList=new ArrayList<>();
        int j=0;
        int k=0;
        for (int i=2;i<=number;i++){
            k=(int)sqrt(i+1);
            for (j=2;j<=k;j++){
                if (i%j==0){
                    break;
                }
            }
            if (j==k+1){
                integerList.add(i);
            }
        }
        return integerList;
    }

4.题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数), 凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

这样的问题统称为约瑟夫环,是一种很有意思的题,如果你之前看过我写的python入门算法题的话用java实现的思路也是一样的。

做这道题一共三个步骤,首先先把能报到3的人添加到一个列表里面,然后统一移除,最后把最后几个没报数的人放到列表前面,重复上述步骤直到人数为2,然后把输出第二个人,因为两个人数3,出去的肯定是第一个

注意一下我用的列表CopyOnWriteArrayList,如果你使用普通的arraylist你就会遇到一个错误,叫做运行时修改错误,就是告诉你你不能对这个列表有增减操作时获取它的信息,使用CopyOnWriteArrayList可以避免这个错误

private static void Method1() {
        CopyOnWriteArrayList<Integer> integerList = new CopyOnWriteArrayList();
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        for (int i = 1; i <= n; i++) {
            integerList.add(i);
        }
        while (integerList.size()>2){
            int y=integerList.size()%3;
            CopyOnWriteArrayList<Integer> integers=new CopyOnWriteArrayList();
            for (int i=1;i<integerList.size()/3+1;i++){
                integers.add(integerList.get(3*i-1));
            }
            System.out.println("移除:"+integers);
            integerList.removeAll(integers);
            integerList=move(integerList,y);
        }
        System.out.println(integerList.get(1));
    }

    private static CopyOnWriteArrayList<Integer> move(CopyOnWriteArrayList<Integer> integerList, int y) {
        CopyOnWriteArrayList<Integer> integers=new CopyOnWriteArrayList<>();
        integers.addAll(integerList.subList(integerList.size()-y,integerList.size()));
        integers.addAll(integerList.subList(0,integerList.size()-y));
        System.out.println("拼接:"+integerList.subList(integerList.size()-y,integerList.size())+"    "+integerList.subList(0,integerList.size()-y));
        return integers;
    }

当然还有另一种思路,我们可以让这个圈的人数到三的挂个牌,告诉其它人我已经出局了,别搭理我了,而不是走出这个圈。

每当下标等于人数时就把下标置零,这样实现循环数数。不断循环直到存活人数为1时退出循环,找到没挂牌的那个人,输出

 private static void Method2() {
        System.out.println("请输人数n:");
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        boolean[] arr = new boolean[n];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = true; //下标为TRUE时说明还在圈里
        }
        int leftCount = n;
        int countNum = 0;
        int index = 0;
        while (leftCount > 1) {
            if (arr[index] == true) { //当在圈里时
                countNum++;  //报数递加
                if (countNum == 3) { //报数为3时
                    countNum = 0; //从零开始继续报数
                    arr[index] = false; //此人退出圈子
                    for (int i = 0; i < n; i++) {
                        System.out.print(arr[i]+" ");
                    }
                    System.out.println();
                    leftCount--; //剩余人数减一
                }
            }
            index++; //每报一次数,下标加一
            if (index == n) { //是循环数数,当下标大于n时,说明已经数了一圈,
                index = 0; //将下标设为零重新开始。
            }
        }
        for (int i = 0; i < n; i++) {
            if (arr[i] == true) {
                System.out.println(i+1);
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_37482202/article/details/84714036