算法训练:密码传纸条

题目:

李雷和韩梅梅坐前后排,上课想说话怕被老师发现,所以改为传纸条。为了不被老师发现他们纸条上写的是啥,,他们约定了如下方法传递信息:

将26个大写英文字母,外加空格,一共27个字符分成三组,每组9个。也就是ABCDEFGHI是第一组,JKLMNOPQR是第二组,STUVWXYZ*是第三组(此处用*代表空格)。

先根据月份数m,一整个分组为单位进行左移,移动(m-1)次。

然后根据日期数d,对每个分组内的字符进行循环左移,移动(n-1)次。

以3月8日为例,首先移动分组3-1=2次,变成:

STUVWXYZ*  ABCDEFGHI  JKLMNOPQR21

然后每组内字符移动8-1 = 7次,最终编码为:

Z*STUVWXY  HIABCDEFG  QRJKLMNOP

对于要传递的信息中的每个字符,用组号和组内序号两个数字来表示。

如果在3月8日传递信息 “HAPPY”,那么H位于第2组的第1个,A位于第二组 第3个 .....一次类推,纸条上会写成:

21,23,39,39,19

输入要求:

每个输入包含两行。第一行使用空格分隔的两个数字,第一个数字是月份,第二个数字是日期。输入保证是一个合法日期。

第二个行为需要编码的字符串,仅由A~Z和空格组成,长度不超过1024个字符

 

输出规范:

对每个输入,打印对应的编码,数字之间用空格分隔,每个输出占一行。

 

输入示例:

1 1

HI

输出示例:

18 19

 

解体思路:

通过阅读题目,可知,因分为两步。

    第一,根据月份和日期,将27个字母重新排列

            1)  因为只有有三组,并且往一个方向移动,不管移动几次,都只有3种可能,假设每一个分组都是一个字符串,并且存放在一个字符串数组中。每个组位置是

  (m-1)%3   =0则不变 等于1 则左移1  等于 2 则左移2

 

算法训练:密码传纸条_第1张图片

            2)组内字符串移动,因为每组有9个字符,所以最终结果同上理,每组字符的位置  是 (d-1)%9 种位置

 

 

  第二,遍历输入的字符,判断输入的每一个字符在哪一组中出现,并返回出现位置的索引,加1即可(因为索引位置从0开始)。

           

 

所有代码如下:

package com.xuanqi;

import java.util.Scanner;

public class test {
    public static void main(String[] arges) {

        String[] strs = new String[]{"ABCDEFGHI", "JKLMNOPQR", "STUVWXYZ*"}; //定义一个字符串数组,存放三组字符串
        String str1 = strs[0];  //分别放进三个字符串内
        String str2 = strs[1];
        String str3 = strs[2];

        Scanner sc1 = new Scanner(System.in); //输入月份和日期
        Scanner sc2 = new Scanner(System.in); //输入 大写字母字符串
        //接受输入参数
        String m = sc1.nextLine();
        String n = sc2.nextLine();


        String tempn = n.replaceAll("\\s", "*"); //将输入的字符串中的空格转换成*

        String temp[] = m.split("\\s+"); //按空格分隔,获取输入的月份 和 日期
        int c = Integer.parseInt(temp[0]);
        int d = Integer.parseInt(temp[1]);

        if(c>12||c<0){
            System.out.println("输入月份不合法");
            return;
        }
        if(d<0||d>31){
            System.out.println("输入日期不合法");
            return;
        }


        int x = (c - 1) % 3; //获取分组左移的位置

        int y = (d - 1) % 9; //获取组内左移的位置


        if (x == 0) {
            strs[0] = str1;
            strs[1] = str2;
            strs[2] = str3;
        } else if (x == 1) {
            strs[0] = str2;
            strs[1] = str3;
            strs[2] = str1;
        } else if (x == 2) {
            strs[0] = str3;
            strs[1] = str1;
            strs[2] = str2;
        }

        System.out.println(strs[0] + " "+strs[1] + " "+strs[2]);

        char[] ch = tempn.toCharArray();//将输入的字符串转成字符数组

        for (int i = 0; i < strs.length; i++) {
            strs[i] = leftMoveIndex(strs[i], y); //组内字符左移

        }
        System.out.println(strs[0] + " "+strs[1] + " "+strs[2]);

        for (int j = 0; j < ch.length; j++) { //循环输入的字符数组 ,若出现在分组中,则输出 分组的位置 和 字符出现的位置
            if(!"ABCDEFGHIJKLMNOPQRSTUVWXYZ*".contains(ch[j]+"")){
                System.out.println("输入字符串不合法");
                return;
            }else {
                for (int i = 0; i < strs.length; i++) {
                    if (strs[i].contains(ch[j] + "")) {
                        System.out.print((i + 1) + "" + (strs[i].indexOf(ch[j] + "") + 1) + " ");
                    }
                }
            }
        }

    }


    public static String leftMoveIndex(String from, int index) {
        String first = from.substring(0, index);
        String second = from.substring(index);
        first = reChange(first);
        second = reChange(second);
        from = first + second;
        from = reChange(from);
        return from;
    }

    /**
     * 循环反转字符串
     * @param from
     * @return
     */
    public static String reChange(String from) {
        char[] froms = from.toCharArray();
        int length = froms.length;
        for (int i = 0; i < length / 2; i++) {
            char temp = froms[i];
            froms[i] = froms[length - 1 - i];
            froms[length - 1 - i] = temp;
        }
        return String.valueOf(froms);
    }
}

 

你可能感兴趣的:(java,算法,面试)