读书人

一个算法题

发布时间: 2014-03-19 15:10:26 作者: rapoo

求助一个算法题
今天笔试做的一个算法题,当时觉得很容易,结果越写越复杂,还求助一下各位网友给个答案。
题目是我映像中写下来的。
从控制台输入一个字符串,要求返回其二进制数。输入的数当成十六进制数处理,如输入3A,返回111010,输入17返回10001。如果输入的字符串不合法则提示错误,当然,要区分是因为输入的字符串是不能组成十六进制数的错误还是输入的数超过了范围的错误。
[解决办法]
Integer.toBinaryString(Integer.parseInt(str,16));
[解决办法]


[解决办法]
这边有个想法,纸上谈兵一下:
1. 初始化一个Map<String,String>,0~9、A(a)~F(f)为key,0000~1001、1010~1111为value(16进制对应的2进制)
2. 入参解析,可以将字符串拆分成一个个单个字符的字符串,用Map一个个取对应value,也可以考虑用正则表达式匹配
3. 按位转换为2进制(16进制与2进制存在天然的转换关系:一个16进制,4位2进制),直接字符串拼接即可
[解决办法]
用正则是必然的,但用Integer.parseInt(str,16); 函数,这道题立马就0分了;面试过程中(一定要理解出题者的意图,不能盲目的调用库函数,包括sort、binarySearch等等,不然就等着被pass),进制转换没有捷径,循环+栈是唯一的办法
[解决办法]
这种笔试题就看考官的意图了。
可能是以下几种:
1、就是考算法,让你自己实现;
2、考你javaAPI的熟练程度;
3、考你思维严谨度,比如边界值,收入输出,异常处理等,这时候用什么实现估计就不关心了。
[解决办法]
引用:
这边有个想法,纸上谈兵一下:
1. 初始化一个Map<String,String>,0~9、A(a)~F(f)为key,0000~1001、1010~1111为value(16进制对应的2进制)
2. 入参解析,可以将字符串拆分成一个个单个字符的字符串,用Map一个个取对应value,也可以考虑用正则表达式匹配
3. 按位转换为2进制(16进制与2进制存在天然的转换关系:一个16进制,4位2进制),直接字符串拼接即可

如果算法题目 类似于版主的这种做法估计好点。
[解决办法]
引用:
Quote: 引用:

这边有个想法,纸上谈兵一下:
1. 初始化一个Map<String,String>,0~9、A(a)~F(f)为key,0000~1001、1010~1111为value(16进制对应的2进制)
2. 入参解析,可以将字符串拆分成一个个单个字符的字符串,用Map一个个取对应value,也可以考虑用正则表达式匹配
3. 按位转换为2进制(16进制与2进制存在天然的转换关系:一个16进制,4位2进制),直接字符串拼接即可

如果算法题目 类似于版主的这种做法估计好点。

如果不考API的话,楼主的方法很快的,这个问题的主要点还在不能组成十六进制数的错误还是输入的数超过了范围的错误。输入的数操作用正则表达式就可以,超过的范围自己判断一下,16进制最多8位,就可以判断范围了吧?
[解决办法]
参照版主的思路写了一个,注意输出的时候要去掉多余的0.


import java.util.HashMap;

/**
* 从控制台输入一个字符串,要求返回其二进制数。输入的数当成十六进制数处理,如输入3A,返回111010,输入17返回10001。
* 如果输入的字符串不合法则提示错误,当然,要区分是因为输入的字符串是不能组成十六进制数的错误还是输入的数超过了范围的错误。
*
*
*/
public class Test019 {

final static HashMap<Character, String> BINARY_CODE_MAP = new HashMap<Character, String>();

static {
BINARY_CODE_MAP.put('0', "0000");
BINARY_CODE_MAP.put('1', "0001");
BINARY_CODE_MAP.put('2', "0010");
BINARY_CODE_MAP.put('3', "0011");
BINARY_CODE_MAP.put('4', "0100");
BINARY_CODE_MAP.put('5', "0101");
BINARY_CODE_MAP.put('6', "0110");
BINARY_CODE_MAP.put('7', "0111");
BINARY_CODE_MAP.put('8', "1000");
BINARY_CODE_MAP.put('9', "1001");
BINARY_CODE_MAP.put('A', "1010");
BINARY_CODE_MAP.put('B', "1011");
BINARY_CODE_MAP.put('C', "1100");
BINARY_CODE_MAP.put('D', "1101");
BINARY_CODE_MAP.put('E', "1110");
BINARY_CODE_MAP.put('F', "1111");
BINARY_CODE_MAP.put('a', "1010");
BINARY_CODE_MAP.put('b', "1011");
BINARY_CODE_MAP.put('c', "1100");


BINARY_CODE_MAP.put('d', "1101");
BINARY_CODE_MAP.put('e', "1110");
BINARY_CODE_MAP.put('f', "1111");
}


/**
* 把字符串转化成2进制数,有效长度31位。
* @param numStr 源字符串
* @return 与源字符串对应的2进制数,字符串不合法则提示是不能组成十六进制数的错误还是输入的数超过了范围的错误
*/
static String fromIntegerToBinary(String numStr) {
return toBinary(numStr, 31);
}

/**
* 把字符串转化成2进制数。
* @param numStr 源字符串
* @param range 2进制数有效长度
* @return 与源字符串对应的2进制数,字符串不合法则提示是不能组成十六进制数的错误还是输入的数超过了范围的错误
*/
private static String toBinary(String numStr,int range) {
if(numStr == null
[解决办法]
numStr.isEmpty()) {
return numStr;
}
char[] arr = numStr.toCharArray();
StringBuilder sb = new StringBuilder();
for (char c : arr) {
if(BINARY_CODE_MAP.containsKey(c)) {
sb.append(BINARY_CODE_MAP.get(c));
} else {
return "illegal char " + c;
}
}
//格式化输出字符串
String result = sb.toString();
if(!result.contains("1")) {
//全0
result = "0";
} else {
//去掉多余的0
result = result.substring(result.indexOf("1"));
}
//超过范围报错
if(result.length() > range) {
return "out of range size:" + result.length();
}
return result;
}

public static void main(String[] args) {
System.out.println(fromIntegerToBinary("0"));
System.out.println(fromIntegerToBinary("00000000"));
System.out.println(fromIntegerToBinary("3A"));
System.out.println(fromIntegerToBinary("017"));
System.out.println(fromIntegerToBinary("7FFFFFFF"));
System.out.println(fromIntegerToBinary("80000000"));
System.out.println(fromIntegerToBinary("dfg"));
System.out.println(fromIntegerToBinary("123呵呵12a"));
}
}


[解决办法]
。。。直接去看Integer的算法难道不好么?


/**
* Parses the string argument as a signed integer in the radix
* specified by the second argument. The characters in the string
* must all be digits of the specified radix (as determined by
* whether {@link java.lang.Character#digit(char, int)} returns a
* nonnegative value), except that the first character may be an
* ASCII minus sign <code>'-'</code> (<code>'\u002D'</code>) to
* indicate a negative value. The resulting integer value is returned.
* <p>
* An exception of type <code>NumberFormatException</code> is
* thrown if any of the following situations occurs:
* <ul>
* <li>The first argument is <code>null</code> or is a string of
* length zero.
* <li>The radix is either smaller than
* {@link java.lang.Character#MIN_RADIX} or
* larger than {@link java.lang.Character#MAX_RADIX}.
* <li>Any character of the string is not a digit of the specified
* radix, except that the first character may be a minus sign
* <code>'-'</code> (<code>'\u002D'</code>) provided that the
* string is longer than length 1.
* <li>The value represented by the string is not a value of type
* <code>int</code>.
* </ul><p>
* Examples:
* <blockquote><pre>
* parseInt("0", 10) returns 0
* parseInt("473", 10) returns 473
* parseInt("-0", 10) returns 0
* parseInt("-FF", 16) returns -255
* parseInt("1100110", 2) returns 102
* parseInt("2147483647", 10) returns 2147483647


* parseInt("-2147483648", 10) returns -2147483648
* parseInt("2147483648", 10) throws a NumberFormatException
* parseInt("99", 8) throws a NumberFormatException
* parseInt("Kona", 10) throws a NumberFormatException
* parseInt("Kona", 27) returns 411787
* </pre></blockquote>
*
* @param s the <code>String</code> containing the integer
* representation to be parsed
* @param radix the radix to be used while parsing <code>s</code>.
* @return the integer represented by the string argument in the
* specified radix.
* @exception NumberFormatException if the <code>String</code>
* does not contain a parsable <code>int</code>.
*/
public static int parseInt(String s, int radix)
throws NumberFormatException
{
if (s == null) {
throw new NumberFormatException("null");
}

if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}

if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX");
}

int result = 0;
boolean negative = false;
int i = 0, max = s.length();
int limit;
int multmin;
int digit;

if (max > 0) {
if (s.charAt(0) == '-') {
negative = true;
limit = Integer.MIN_VALUE;
i++;
} else {
limit = -Integer.MAX_VALUE;
}
multmin = limit / radix;
if (i < max) {
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
} else {
result = -digit;
}
}
while (i < max) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
if (negative) {
if (i > 1) {
return result;
} else {/* Only got "-" */
throw NumberFormatException.forInputString(s);
}
} else {
return -result;
}
}




  /**
* Convert the integer to an unsigned number.
*/
private static String toUnsignedString(int i, int shift) {
char[] buf = new char[32];
int charPos = 32;
int radix = 1 << shift;
int mask = radix - 1;
do {
buf[--charPos] = digits[i & mask];
i >>>= shift;
} while (i != 0);

return new String(buf, charPos, (32 - charPos));
}

------解决方案--------------------


直接转,有异常就说明参数非法,多快捷
一个算法题
[解决办法]
参考14L吧,他写的蛮好的,注释也蛮清晰。
[解决办法]

引用:
Quote: 引用:

用正则是必然的,但用Integer.parseInt(str,16); 函数,这道题立马就0分了;面试过程中(一定要理解出题者的意图,不能盲目的调用库函数,包括sort、binarySearch等等,不然就等着被pass),进制转换没有捷径,循环+栈是唯一的办法

恩,您说的很对。您可以写下代码我参考下不?


public class Parse {

/**
* output:10101011110101
*/
public static void main(String[] args) {
parse16To2("2AF5");
}
/**
把任意一位16进制数字转换为2进制
由于0转换为0000、F转换为1111,写死了4位,可以不用stack
*/
private static String parseOne(int k){
int[] array=new int[4];
int i=3;
while(k>0){
array[i]=k%2;
k/=2;
i--;
}
String str="";
for(i=0;i<=3;i++){
str+=array[i];
}
return str;

}
/**
* 遍历str
* 判断这一位是数字还是字母,并把这一位转换为2进制
* (请在面试时牢记A的AscII码为65,0的AscII码为48,a的AscII码为97)
* 最后,去掉前面的0
*/
public static void parse16To2(String str){
if(!str.matches("[\\dA-F]{1,8}")){
System.out.println("不符合!");
}else{
String total="";
char c=0;
int k=0;
int i=0;
for(;i<str.length();i++){
c=str.charAt(i);
if(c>='A'&&c<='F'){
k=c-55;
}else{
k=c-'0';
}
total+=parseOne(k);
}
for(i=0;i<total.length();i++){
if(total.charAt(i)=='1'){
break;
}
}
System.out.println(total.substring(i));
}
}
}

读书人网 >J2SE开发

热点推荐