How to get hexadecimal value from combined booleans? - java

I want to get a hexadecimal value from four boolean variables something like this example:
boolean[] m = {true, false, true, true};
I want to get a String or char that hold B which means 1011 in binary.
PS: I am working on an Android app.

You can use below code to get your binary string, integer value and hexDecimal value.
boolean[] m = {true,false,true,true};
String binaryStr = "";
for (boolean bit : m) {
binaryStr = binaryStr + ((bit) ? "1" : "0" );
}
int decimal = Integer.parseInt(binaryStr , 2);
String hexStr = Integer.toString(decimal , 16);
In above code, binaryStr is your Binary String i.e. 1011 and its equivalent decimal and hexa decimal value are decimal and hexStr

boolean[] booleanArray = new boolean[] { true, false, false, true };
String binaryString = Arrays.toString(booleanArray).replace("true", "1").replace("false", "0");
and just convert that binaryString to hexadecimalvalue

While the above answers do work, they have their limitations. The first limit being a cap at 32 booleans because of the 32 bit integer limit. But the above code also uses built-in methods, they don't allow a beginner to grasp what is really going on.
If you just want to get the job done, use something from above. It'll probably be more efficient. I'm just posting this solution because I feel it will allow someone who wants to grasp the actual concept do so better.
(Hopefully the comments make a little sense)
public static String booleanArrayToHex1(boolean[] arr){
if(!(arr.length%4==0)){arr=makeMultOf4(arr);} //If you are using arrays not in multiples of four, you can put a method here to add the correct number of zeros to he front.
//Remove the above line if your array will always have a length that is a multiple of 4
byte[] hexValues=new byte[arr.length/4];
//The array above is where the decimal hex values are stored, it is byte because the range we need is 0-16, bytes are the closest to that with the range of 0-255
int hexCounter=arr.length/4-1; //counts what hex number you are calculating
/* The below loop calculates chunks of 4 bianary numbers to it's hex value
* this works because 16 is a power of 2
* so if we simpily squish those numbers together it will be the same as finding the accual integer value of the whole thing
* This can go to higher numbers because we do not have the 32 bit integer limit
* it runs in reverse because the lowest value is on the right of the array (the ones place is on the right)
*/
for(int i=arr.length-1;i>=0;i--){
if(arr[i]){
int place=1; //will count the value of a bianary number in terms of its place
for(int j=3;j>i%4;j--)
//loop multiplies the bianary number by 2 j times, j being what place it's in (two's, four's, eight's). This gives the correct value for the number within the chunk.
//This is why the array needs to be a multiple of 4
place*=2;
hexValues[hexCounter]+=place; //this will add that place value to the current chunk, only if this place in the boolean array is true (because of the above if - statement)
}
if(i%4==0)//moves the chunk over one every 4 binary values
hexCounter--;
}
//Everything below simpily takes the array of decimal hex values, and converts to a alpha-numeric string (array to normal hex numbers)
String ret="";
for(byte b:hexValues)
switch(b){
case 10:
ret=ret+"A";
break;
case 11:
ret=ret+"B";
break;
case 12:
ret=ret+"C";
break;
case 13:
ret=ret+"D";
break;
case 14:
ret=ret+"E";
break;
case 15:
ret=ret+"F";
break;
default:
ret=ret+b;
break;
}
return ret;
}
If your array length is not a multiple of 4, to make this work you will need to make the array a multiple of 4. I have some code below that will do that. It's not commented, and probably not that efficient, but it works.
public static boolean[] makeMultOf4(boolean[] arr){
if(arr.length%4==0){return arr;}
boolean[] array=new boolean[arr.length+(arr.length%4==1?3:arr.length%4==2?2:1)];
for(int i=0;i<array.length;i++){
try{
array[i]=arr[i-(arr.length%4==1?3:arr.length%4==2?2:1)];
}catch(Exception e){
array[i]=false;
}
}
return array;
}

You can use this logic :
String x = "";
for(int i = 0 ; i < m.length ; i++){
if(m[i])
x += "1";
else
x += "0";
}
Log.i("values = ",x);

For each boolean value append to binary string 1 if true 0 otherwise, then using Integer.parseInt() convert binary string to Integer instance, finally convet integer to hex string using Integer.toHexString() method
#org.junit.Test
public void test() throws Exception{
boolean[] m = {true, false, true, true};
String binary = "";
for(boolean b : m) binary += b ? 1 : 0;
String hex = Integer.toHexString(Integer.parseInt(binary, 2));
System.out.println(hex);
}

Related

Encode a 4 Length string using different 4 bit binary numbers

I am trying to make a function that turns a binary number into letters according to the positions of the one's inside of it.
For example if i had the binary number : 0101
I want to take the String "LUDR" and effectively multiply them together to get
: "UR".
I have the 4 bit binary numbers in an array and the string that i want to 'multiply' them with is always going to be "LUDR".
I will give more examples..
binary number of : 1011 gives "LDR"
binary number of : 0001 gives "R"
EDIT:
the code i have already written :
String[][] binVals = new String[10][10];
//my function to fill up with 4 bit binary values so i can get 100 in total
//just read from file so that's why it's a string array
String mazeWallRemove = "LURD";
//I need to write some function to turn the binary values in to some string
String[][] unCodedWalls = new String[10][10]//into this array
my question is what functions can i use to 'multiply' the binVals and the "LURD" string to get the string output(in the form as shown above)
I can just write 15 if statments converting each binary value from the array into an integer and then just saying:
for(int a = 0; a < 10; a++){
for(int b = 0; b < 10; b++){
if(binVals[a][b] == 1){
uncodedWalls[a][b] = "R"
} // lots more else if statements
}
}
this method is horribly inefficient and so i'm looking for a more efficient way to do it instead of making tons of if statements.
You can use the charAt method available in String class to construct the string you need. Pass the binary number and string you want to multiply to this method. This will check the character in the binary String is 1 and get the corresponding value from the original String and append it.
public String multiply(String value, String binary) {
String finalString = "";
for (int i = 0; i < binary.length(); i++) {
if (binary.charAt(i) == '1') {
finalString+=value.charAt(i);
}
}
return finalString;
}

Generate all Palindromic numbers in a given number system?

I need to generate all palindromic numbers for a given number base (which should be able to be of size up to 10,000), in a given range. I need a efficient way to do it.
I stumbled upon this answer, which is related to base 10 directly. I'm trying to adapt it to work for "all" bases:
public static Set<String> allPalindromic(long limit, int base, char[] list) {
Set<String> result = new HashSet<String>();
for (long i = 0; i <= base-1 && i <= limit; i++) {
result.add(convert(i, base, list));
}
boolean cont = true;
for (long i = 1; cont; i++) {
StringBuffer rev = new StringBuffer("" + convert(i, base, list)).reverse();
cont = false;
for (char d : list) {
String n = "" + convert(i, base, list) + d + rev;
if (convertBack(n, base, list) <= limit) {
cont = true;
result.add(n);
}
}
}
return result;
}
convert() method converts a number to a string representation of that number in a given base using a list of chars for digits.
convertBack() converts back the string representation of a number to base 10.
When testing my method for base 10, it leaves out two-digit palindromes and then the next ones it leaves out are 1001,1111,1221... and so on.
I'm not sure why.
Here are the conversion methods if needed.
Turns out, this gets slower with my other code because of constant conversions since I need the all numbers in order and in decimal. I'll just stick to iterating over every integer and converting it to every base and then checking if its a palindrome.
I don't have enough reputation to comment, but if you are only missing even length palindromes, then most probably there is something wrong with your list. Most probably you have forgot to add an empty entry in list as to generate 1001, it should be like num(10) + empty("") + rev(01).
There is no so many appropriate chars for digits in all possible bases (like 0xDEADBEEF for hex, and I suppose that convert has some limit like 36), so forget about exotic digits, and use simple lists or arrays like [8888, 123, 5583] for digits in 10000-base.
Then convert limit into need base, store it.
Now generate symmetric arrays of odd and even length like
[175, 2, 175] or [13, 221, 221, 13]. If length is the same as limit length, compare array values and reject too high numbers.
You can also use limit array as starting and generate only palindromes with lesser values.

How can I keep track of an int and hold the 0's

Java question,
Say I have a number such as 0000102 and the 0s are important, as in they need to be there.
How can I save this information in an int(or some other way that would allow me to increment it)
For example, after checking the number 0000102 it would then add one to it and check for 0000103
When I try saving it as in int it just reverts to 102 and gets rid of the 0's, and therefore doesn't match as I search through a database since it is no longer the same. Does anyone know of a way I can do this without it removing the 0's. Thanks
EDIT:
My final solution for addition with leading zeros was this function, it takes a string with leading 0's adds one to it, then returns the string
String nextNum(String s){
int number =0;
String newNum ="";
int len = s.length();
int newLength =0;
for(int i =0; i < s.length()-1; i++){
if (s.charAt(i) == '0')
newNum+="0";
else
break;
}
number = Integer.parseInt(s);
number++;
newNum += String.valueOf(number);
newLength = newNum.length();
if(newLength == len)
return newNum;
else
return newNum.substring(1); //incase number was 000099 it doesnt go to 0000100 it goes to 000100 instead
}
You can use string formatting by combining printf with "%0d" as follows:
String num = "000123";
Integer n = Integer.parseInt(num);
n++;
int len = num.length();
System.out.printf("%0" + len + "d", n); // 000124
// and if you want to store the result
// back into a string:
String res = String.format("%0" + len + "d", n);
System.out.println(res); // 000124
You would store the value as an int (without zeroes) but could convert it into a String with leading zeroes when you want to print or display it. Here is an example conversion method.
public String addZeroes(int value, int desiredLength) {
String valueString = value + "";
int valueLength = valueString.length();
for (int i = 0; i < desiredLength - valueLength; i++) {
valueString = "0" + valueString;
}
return valueString;
}
The number itself is separate from the representation of the number. The number associated with what we usually call "ten" is always the quantity that counts these: ||||||||||, but it has many possible string representations: "10", "0000010", "0x0a", "1010(2)"... (not all of these are valid Java representations, just various representations that humans are using)
Your number will always be stored in the computer in such a way that the quantity can be (mostly) accurately handled. The string representation is normally not stored; it is calculated each time. For example, when you do System.out.println(102), it is actually handled as System.out.println(Integer.toString(102, 10)).
Between 102 and "0000102", figure which one you want to store and which one you want to display, and convert appropriately when you need the other one.
You'll need to use a String.
The decimal numbers 000102 and 0102 and 102 (and for that matter, the hex number 0x66) are all the same integer value, there is no way to distinguish between them once you store them as an int.
If you want to preserve a specific character representation of your integer, then you need a string.
To increment the String you'll need to parse it to an Integer, and then reformat it.
String increment(String s) {
int n = Integer.parseInt(s, 10)
return ("%0" + s.length() + "d").format(n+1);
}
You say you need to keep track of the leading zeroes, but that's separate from the number itself. I would keep the number itself as an int, and keep a different variable with the required number of zeroes. This will let the number keep its semantic meaning of the number as a number (and allow incrementing, as you said), and when displaying it, pad or fill with zeroes when needed, based on the second value.

Why will this java string routine not print the answer?

I have been working on the Project Euler problem 4. I am new to java, and believe I have found the answer (906609 = 993 * 913, by using Excel!).
When I print the line commented out, I can that my string manipulations have worked. I've researched a few ways to compare strings in case I had not understoof something, but this routine doesn't give me a result.
Please help me identify why it is not printing the answer?
James
public class pall{
public static void main(String[] args){
int i;
int j;
long k;
String stringProd;
for(i=994;i>992; i--){
for (j=914;j>912; j--){
k=(i*j);
stringProd=String.valueOf(k);
int len=stringProd.length();
char[] forwards=new char[len];
char[] back = new char[len];
for(int l=0; l<len; l++){
forwards[l]=stringProd.charAt(l);
}
for(int m=0; m<len;m++){
back[m]=forwards[len-1-m];
}
//System.out.println(forwards);
//System.out.println(back);
if(forwards.toString().equals(back.toString())){
System.out.println(k);}
}
}
}
}
You are comparing the string representation of your array. toString() doesn't give you what you think. For example, the below code makes it clear:
char[] arr1 = {'a', 'b'};
char[] arr2 = {'a', 'b'};
System.out.println(arr1.toString() + " : " + arr2.toString());
this code prints:
[C#16f0472 : [C#18d107f
So, the string representation of both the arrays are different, even though the contents are equal. This is because arrays don't override toString() method. It inherits the Object#toString() method.
The toString method for class Object returns a string consisting of
the name of the class of which the object is an instance, the at-sign
character #, and the unsigned hexadecimal representation of the hash
code of the object. In other words, this method returns a string equal
to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
So, in the above output, [C is the output of char[].class.getName(), and 18d107f is the hashcode.
You can't also compare the arrays using forward.equals(back), as arrays in Java don't override equals() or hashCode() either. Any options? Yes, for comparing arrays you can use Arrays#equals(char[], char[]) method:
if (Arrays.equals(forward, back)) {
System.out.println(k);
}
Also, to get your char arrays, you don't need those loops. You can use String#toCharArray() method. And also to get the reverse of the String, you can wrap the string in a StringBuilder instance, and use it's reverse() method:
char[] forwards = stringProd.toCharArray();
char[] back = new StringBuilder(stringPod).reverse().toString().toCharArray();
And now that you have found out an easy way to reverse a string, then how about using String#equals() method directly, and resist creating those character arrays?
String stringPod = String.valueOf(k);
String reverseStringPod = new StringBuilder(stringPod).reverse().toString()
if (stringPod.equals(reverseStringPod)) {
System.out.println(k);
}
Finally, since it is about project euler, which is about speed and mostly mathematics. You should consider avoiding String utilities, and do it with general division and modulus arithmetic, to get each individual digits, from beginning and end, and compare them.
To convert a string to char[] use
char[] forward = stringProd.toCharArray();
To convert a char[] to String, use String(char[]) constructor:
String backStr = new String(back); // Not the same as back.toString()
However, this is not the most performant solution, for several reasons:
You do not need to construct a back array to check if a string is a palindrome - you can walk the string from both ends, comparing the characters as you go, until you either find a difference or your indexes meet in the middle.
Rather than constructing a new array in a loop, you could reuse the same array - in case you do want to continue with an array, you could allocate it once for the maximum length of the product k, and use it in all iterations of your loop.
You do not need to convert a number to string in order to check if it is a palindrome - you can get its digits by repeatedly taking the remainder of division by ten, and then dividing by ten to go to the next digit.
Here is an illustration of the last point:
boolean isPalindrome(int n) {
int[] digits = new int[10];
if (n < 0) n = -n;
int len = 0;
while (n != 0) {
digits[len++] = n % 10;
n /= 10;
}
// Start two indexes from the opposite sides
int left = 0, right = len-1;
// Loop until they meet in the middle
while (left < right) {
if (digits[left++] != digits[right--]) {
return false;
}
}
return true;
}

From string to ASCII to binary back to ASCII to string in Java

I have sort of a funky question (that I hope hasn't been asked and answered yet). To start, I'll tell you the order of what I'm trying to do and how I'm doing it and then tell you where I'm having a problem:
Convert a string of characters into ASCII numbers
Convert those ASCII numbers into binary and store them in a string
Convert those binary numbers back into ASCII numbers
Convert the ASCII numbers back into normal characters
Here are the methods I've written so far:
public static String strToBinary(String inputString){
int[] ASCIIHolder = new int[inputString.length()];
//Storing ASCII representation of characters in array of ints
for(int index = 0; index < inputString.length(); index++){
ASCIIHolder[index] = (int)inputString.charAt(index);
}
StringBuffer binaryStringBuffer = new StringBuffer();
/* Now appending values of ASCIIHolder to binaryStringBuffer using
* Integer.toBinaryString in a for loop. Should not get an out of bounds
* exception because more than 1 element will be added to StringBuffer
* each iteration.
*/
for(int index =0;index <inputString.length();index ++){
binaryStringBuffer.append(Integer.toBinaryString
(ASCIIHolder[index]));
}
String binaryToBeReturned = binaryStringBuffer.toString();
binaryToBeReturned.replace(" ", "");
return binaryToBeReturned;
}
public static String binaryToString(String binaryString){
int charCode = Integer.parseInt(binaryString, 2);
String returnString = new Character((char)charCode).toString();
return returnString;
}
I'm getting a NumberFormatException when I run the code and I think it's because the program is trying to convert the binary digits as one entire binary number rather than as separate letters. Based on what you see here, is there a better way to do this overall and/or how can I tell the computer to recognize the ASCII characters when it's iterating through the binary code? Hope that's clear and if not I'll be checking for comments.
So I used OP's code with some modifications and it works really well for me.
I'll post it here for future people. I don't think OP needs it anymore because he probably figured it out in the past 2 years.
public class Convert
{
public String strToBinary(String inputString){
int[] ASCIIHolder = new int[inputString.length()];
//Storing ASCII representation of characters in array of ints
for(int index = 0; index < inputString.length(); index++){
ASCIIHolder[index] = (int)inputString.charAt(index);
}
StringBuffer binaryStringBuffer = new StringBuffer();
/* Now appending values of ASCIIHolder to binaryStringBuffer using
* Integer.toBinaryString in a for loop. Should not get an out of bounds
* exception because more than 1 element will be added to StringBuffer
* each iteration.
*/
for(int index =0;index <inputString.length();index ++){
binaryStringBuffer.append(Integer.toBinaryString
(ASCIIHolder[index]));
}
String binaryToBeReturned = binaryStringBuffer.toString();
binaryToBeReturned.replace(" ", "");
return binaryToBeReturned;
}
public String binaryToString(String binaryString){
String returnString = "";
int charCode;
for(int i = 0; i < binaryString.length(); i+=7)
{
charCode = Integer.parseInt(binaryString.substring(i, i+7), 2);
String returnChar = new Character((char)charCode).toString();
returnString += returnChar;
}
return returnString;
}
}
I'd like to thank OP for writing most of it out for me. Fixing errors is much easier than writing new code.
You've got at least two problems here:
You're just concatenating the binary strings, with no separators. So if you had "1100" and then "0011" you'd get "11000011" which is the same result as if you had "1" followed by "1000011".
You're calling String.replace and ignoring the return result. This sort of doesn't matter as you're replacing spaces, and there won't be any spaces anyway... but there should be!
Of course you don't have to use separators - but if you don't, you need to make sure that you include all 16 bits of each UTF-16 code point. (Or validate that your string only uses a limited range of characters and go down to an appropriate number of bits, e.g. 8 bits for ISO-8859-1 or 7 bits for ASCII.)
(I have to wonder what the point of all of this is. Homework? I can't see this being useful in real life.)

Categories