使用StringBuilder获取null作为输出

时间:2016-10-01 09:00:18

标签: java string collections stringbuilder

我正在做一个编码问题,我尝试解密输入字符串。解密的过程是: 从0到9它代表从a到i的字母表。 然后10#表示j,11#代表k等。

import java.util.HashMap;

public class Julia {

    public static void main(String[] args) {

        String s="10#21#12#91";
        Julia obj=new Julia();
        String result=obj.decrypt(s);
        System.out.println(result);
    }
    public String decrypt(String msg)
    {
        HashMap<String,Character> hs=new HashMap<>();
        hs.put("1",'a');
        hs.put("2",'b');
        hs.put("3",'c');
        hs.put("4",'d');
        hs.put("5",'e');
        hs.put("6",'f');
        hs.put("7",'g');
        hs.put("8",'h');
        hs.put("9",'i');
        hs.put("10",'j');
        hs.put("11",'k');
        hs.put("12",'l');
        hs.put("13",'m');
        hs.put("14",'n');
        hs.put("15",'o');
        hs.put("16",'p');
        hs.put("17",'q');
        hs.put("18",'r');
        hs.put("19",'s');
        hs.put("20",'t');
        hs.put("21",'u');
        hs.put("22",'v');
        hs.put("23",'w');
        hs.put("24",'x');
        hs.put("25",'y');
        hs.put("26",'x');
        StringBuilder n=new StringBuilder();
        for(int i=msg.length()-1;i>=0;i--)
        {

            if(msg.charAt(i)=='#' && i>=2)
            {
                StringBuilder s=new StringBuilder().append(msg.charAt(i-2)).append(msg.charAt(i-1));
                System.out.println(s);
                n.append(hs.get(s));
                System.out.println(n);
                i=i-2;
            }
            else
            {
                n.append(hs.get(msg.charAt(i)));
            }

        }
        return n.toString();
    }
}

那是我写的代码。但我得到的输出是nullnullnullnullnull。 我认为问题出在StringBuilder上。任何人都可以帮助我并解释这个概念吗?如果有人有更好的解决方案,请指导。

6 个答案:

答案 0 :(得分:4)

当您使用简单公式时,不应使用数据(地图)。

我的建议:

import java.util.ArrayList;
import java.util.List;

public final class Julia {

    public static void main(final String[] args) {
        final String s = "10#21#12#91";
        final String result = decrypt(s);
        System.out.println(result);
    }

    private static String decrypt(final String s) {
        final List<Integer> crypt = new ArrayList<>();
        final String[] groups = s.split("#");
        for (int i = 0; i < groups.length; i++) {
            final String group = groups[i];
            int j = 0;
            // Special case for last group
            if ((i == (groups.length - 1)) && !s.endsWith("#")) {
                j = group.length();
            }
            if (group.length() > 2) {
                j = group.length() - 2;
            }
            for (int k = 0; k < j; k++) {
                crypt.add(Integer.valueOf(group.substring(k, k + 1)));
            }
            if (j < group.length()) {
                crypt.add(Integer.valueOf(group.substring(j, group.length())));
            }
        }
        final StringBuilder n = new StringBuilder(crypt.size());
        for (final Integer c : crypt) {
            final char d = (char) (('a' + c) - 1);
            n.append(d);
        }
        return n.toString();
    }
}

请注意,问题中有两个错误:字母a是1而不是零,26的值是z,而不是x。当您使用公式可以使用的数据时,后一种错误是典型的。

由于你正在学习,我会注意到解密方法 - 我的建议和你的建议 - 都应该是静态的,因为它们不使用任何字段,所以实例化不是必需的。

答案 1 :(得分:3)

这是模式匹配问题,可以通过正则表达式来解决。

您的代码存在一些错误,其他人已经指出了这些错误。我没有看到任何比简单的正则表达式解决方案更好的解决方案。

以下正则表达式代码将输出&#39; julia &#39;输入&#39; 10#21#12#91 &#39;。

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

public class Julia {

public static void main(String[] args) {

    String s="10#21#12#91";

    Julia obj=new Julia();
    String result=obj.decrypt(s);
    System.out.println(result);
}

public String decrypt(String msg)
{
    Pattern regex = Pattern.compile("((\\d\\d#)|(\\d))");
    Matcher regexMatcher = regex.matcher(msg);
    StringBuffer result = new StringBuffer();
    while (regexMatcher.find())
        regexMatcher.appendReplacement(result, getCharForNumber(Integer.parseInt(regexMatcher.group(1).replace("#",""))));
    return result.toString();
}

private String getCharForNumber(int i) {
    return i > 0 && i < 27 ? String.valueOf((char)(i + 96)) : null;
}
}

我希望它有所帮助。

答案 2 :(得分:2)

hs.get(s)将始终返回null,因为s不是String

尝试hs.get(s.toString())

hs.get(msg.charAt(i))也将始终返回null,因为您将char传递给get而不是String

您的代码中可能还存在逻辑问题,但很难说。

答案 3 :(得分:1)

优化版代码

mysqldump -u [uname] -p db_name > db_backup.sql

答案 4 :(得分:1)

Regex确实是要走的路,Pirate_Jack提出的代码可以改进。它将昂贵的正则表达式称为两个多余的时间(替换是正则表达式操作)。

以下是一个改进的版本:

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

   public final class Julia3 {

       public static void main(final String[] args) {

           final String s = "10#21#12#91";

           final String result = decrypt(s);
           System.out.println(result);
       }

       public static String decrypt(final String msg) {
           final Pattern regex = Pattern.compile("((\\d\\d)(#)|(\\d))");
           final Matcher regexMatcher = regex.matcher(msg);
           final StringBuffer result = new StringBuffer();
           String c;
           while (regexMatcher.find()) {
               if (regexMatcher.group(2) == null) {
                   c = regexMatcher.group(1);
               } else {
                   c = regexMatcher.group(2);
               }
               result.append((char) ((Integer.parseInt(c) + 'a') - 1));
           }
           return result.toString();
       }
   }

答案 5 :(得分:0)

这是不对的:

hs.get(s)

s是StringBuilder。它应该是hs.get(Char)

修改:可选的不同解决方案:

    public class Julia {

    public static void main(String[] args) {

        String s="10#21#12#91";

        List<String> numbers = splitToNumbers(s);

        Julia obj=new Julia();
        String result=obj.decrypt(numbers);
        System.out.println(result);
    }

    /**
     *@param s
     *@return
     */
    private static List<String> splitToNumbers(String s) {

        //add check s is not null

        char[] chars = s.toCharArray();
        char delimiter = '#';
        List<String> numberAsStrings = new ArrayList<String>();

        int charIndex = 0;

        while (charIndex < (chars.length -3)) {

            char theirdChar = chars[charIndex+2];
            if(theirdChar == delimiter) {

                numberAsStrings.add(""+chars[charIndex]+chars[charIndex+1]);
                charIndex +=3;

            }else {

                numberAsStrings.add(""+chars[charIndex]);
                charIndex ++;
            }
        }

        //add what's left
        while (charIndex < chars.length) {

            numberAsStrings.add(""+chars[charIndex]);
            charIndex++;
        }

        return numberAsStrings;
    }

    public String decrypt(List<String> numbersAsStings){

        StringBuilder sb=new StringBuilder();

        for (String number : numbersAsStings) {

            int num = Integer.valueOf(number);
            sb.append(intToChar(num-1));
        }

        return sb.toString();
    }

    private char intToChar(int num) {

        if((num<0) || (num>25) ) {
            return '?' ;
        }
        return (char)('a' + num);
    }
}