直接去看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)); }
/** * Returns the numeric value of the specified character (Unicode * code point) in the specified radix. * * <p>If the radix is not in the range <code>MIN_RADIX</code> <= * <code>radix</code> <= <code>MAX_RADIX</code> or if the * character is not a valid digit in the specified * radix, <code>-1</code> is returned. A character is a valid digit * if at least one of the following is true: * <ul> * <li>The method {@link #isDigit(int) isDigit(codePoint)} is <code>true</code> of the character * and the Unicode decimal digit value of the character (or its * single-character decomposition) is less than the specified radix. * In this case the decimal digit value is returned. * <li>The character is one of the uppercase Latin letters * <code>'A'</code> through <code>'Z'</code> and its code is less than * <code>radix + 'A' - 10</code>. * In this case, <code>ch - 'A' + 10</code> * is returned. * <li>The character is one of the lowercase Latin letters * <code>'a'</code> through <code>'z'</code> and its code is less than * <code>radix + 'a' - 10</code>. * In this case, <code>ch - 'a' + 10</code> * is returned. * </ul> * * @param codePoint the character (Unicode code point) to be converted. * @param radix the radix. * @return the numeric value represented by the character in the * specified radix. * @see java.lang.Character#forDigit(int, int) * @see java.lang.Character#isDigit(int) * @since 1.5 */ public static int digit(int codePoint, int radix) { int digit = -1; if (codePoint >= MIN_CODE_POINT && codePoint <= FAST_PATH_MAX) { digit = CharacterDataLatin1.digit(codePoint, radix); } else { int plane = getPlane(codePoint); switch(plane) { case(0): digit = CharacterData00.digit(codePoint, radix); break; case(1): digit = CharacterData01.digit(codePoint, radix); break; case(2): digit = CharacterData02.digit(codePoint, radix); break; case(3): // Undefined case(4): // Undefined case(5): // Undefined case(6): // Undefined case(7): // Undefined case(8): // Undefined case(9): // Undefined case(10): // Undefined case(11): // Undefined case(12): // Undefined case(13): // Undefined digit = CharacterDataUndefined.digit(codePoint, radix); break; case(14): digit = CharacterData0E.digit(codePoint, radix); break; case(15): // Private Use case(16): // Private Use digit = CharacterDataPrivateUse.digit(codePoint, radix); break; default: // the argument's plane is invalid, and thus is an invalid codepoint // digit remains -1; break; } } return digit; }
public String getBinaryStr() {
Scanner sc = new Scanner(System.in);
System.out.println("Please input the hex number");
String input = sc.next();
while (input == null || input == "") {
input = sc.next();
}
sc.close();
String regex = "[1-9A-F][0-9A-F]*";
// 不是很理解“要区分是因为输入的字符串是不能组成十六进制数的错误还是输入的数超过了范围的错误”
// 输入不合格统一按非法处理
if (!input.toUpperCase().matches(regex)) {
return "Your input is illegal";
}
int tenRadix = Integer.parseInt(input, 16);
String twoRadix = Integer.toBinaryString(tenRadix);
return twoRadix;
}欢迎探讨学习
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进制),直接字符串拼接即可
可能是以下几种:
1、就是考算法,让你自己实现;
2、考你javaAPI的熟练程度;
3、考你思维严谨度,比如边界值,收入输出,异常处理等,这时候用什么实现估计就不关心了。
如果不考API的话,楼主的方法很快的,这个问题的主要点还在不能组成十六进制数的错误还是输入的数超过了范围的错误。输入的数操作用正则表达式就可以,超过的范围自己判断一下,16进制最多8位,就可以判断范围了吧?
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"));
}
}
/**
* 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));
}
* Returns the numeric value of the specified character (Unicode
* code point) in the specified radix.
*
* <p>If the radix is not in the range <code>MIN_RADIX</code> <=
* <code>radix</code> <= <code>MAX_RADIX</code> or if the
* character is not a valid digit in the specified
* radix, <code>-1</code> is returned. A character is a valid digit
* if at least one of the following is true:
* <ul>
* <li>The method {@link #isDigit(int) isDigit(codePoint)} is <code>true</code> of the character
* and the Unicode decimal digit value of the character (or its
* single-character decomposition) is less than the specified radix.
* In this case the decimal digit value is returned.
* <li>The character is one of the uppercase Latin letters
* <code>'A'</code> through <code>'Z'</code> and its code is less than
* <code>radix + 'A' - 10</code>.
* In this case, <code>ch - 'A' + 10</code>
* is returned.
* <li>The character is one of the lowercase Latin letters
* <code>'a'</code> through <code>'z'</code> and its code is less than
* <code>radix + 'a' - 10</code>.
* In this case, <code>ch - 'a' + 10</code>
* is returned.
* </ul>
*
* @param codePoint the character (Unicode code point) to be converted.
* @param radix the radix.
* @return the numeric value represented by the character in the
* specified radix.
* @see java.lang.Character#forDigit(int, int)
* @see java.lang.Character#isDigit(int)
* @since 1.5
*/
public static int digit(int codePoint, int radix) {
int digit = -1; if (codePoint >= MIN_CODE_POINT && codePoint <= FAST_PATH_MAX) {
digit = CharacterDataLatin1.digit(codePoint, radix);
} else {
int plane = getPlane(codePoint);
switch(plane) {
case(0):
digit = CharacterData00.digit(codePoint, radix);
break;
case(1):
digit = CharacterData01.digit(codePoint, radix);
break;
case(2):
digit = CharacterData02.digit(codePoint, radix);
break;
case(3): // Undefined
case(4): // Undefined
case(5): // Undefined
case(6): // Undefined
case(7): // Undefined
case(8): // Undefined
case(9): // Undefined
case(10): // Undefined
case(11): // Undefined
case(12): // Undefined
case(13): // Undefined
digit = CharacterDataUndefined.digit(codePoint, radix);
break;
case(14):
digit = CharacterData0E.digit(codePoint, radix);
break;
case(15): // Private Use
case(16): // Private Use
digit = CharacterDataPrivateUse.digit(codePoint, radix);
break;
default:
// the argument's plane is invalid, and thus is an invalid codepoint
// digit remains -1;
break;
}
}
return digit;
}
/**
* 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));
}
}
}
/**
* 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));
}
}
}
不好意思,许久未登录CSDN了,今天才来回复。顺便结贴了。
仔细看了两位的代码,受益良多,想请问一下算法这个东西该如何才能提高呢?