面试算法题解析:密码传纸条

题目:

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

将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

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

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

           

所有代码如下:

import java.util.Scanner;

public class Question{

    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;
        String n;
        m = sc1.nextLine();
        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]);
        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;
        }
        
        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++) {  //遍历字符
            for (int i = 0; i < strs.length; i++) { //遍历字符串数组
                if (strs[i].contains(ch[j] + "")) { //判断字符是否在组内  
                    //如果在组内,则返回索引值+1
                    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;
    }

    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);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36657997/article/details/81810729