Java - Integers and Binaries - java

Trying to create a program where you input binary numbers, and you get the sum of these two again in binary form. Why doesn't the code work;
import java.util.Scanner;
class ABC{
public static void main(String[] args){
Scanner toy = new Scanner(System.in);
int x = toy.nextInt();
int y = toy.nextInt();
x = 0bx; y=0by; ------------> ERROR SHOWS UP
int z = x + y;
System.out.println(Integer.toBinaryString(z));
}
}
The error message reads:
binary numbers must contain at least one binary digit
';' expected
Ideal example:
x = 101 (integer) --> x = 5 (binary meaning of 101)
y = 10 (integer) --> y = 2 (binary meaning of 10)
z = x + y = 5 + 2 = 7
return binary form of 7 (111)

If you want your input numbers to be parsed a binary, you should read them as Strings and parse to int in radix 2:
int x = Integer.parseInt(toy.next(),2);
int y = Integer.parseInt(toy.next(),2);
int z = x + y;
System.out.println(Integer.toBinaryString(z));
As for your error:
x = 0bx; y=0by;
is not a valid syntax. The 0b prefix allows you to enter numeric literals that would be treated as binary literals (for example x = 0b1001;), but you can't combine it with a variable.

You wrote 0bx, which were a nice programming trick if it worked. It doesn't, as you experienced yourself.
To see why, you need to know that the code you wrote is first interpreted as a whole, and is translated by the compiler into a program in machine code. In principle the compiler could figure out what you were trying to say with the 0bx expression. It's just that the Java programming language doesn't allow this expression.
It says something similar to:
A binary literal is written by 0b, followed by only 0 and 1, at least one and as many as possible.
The word literal means something related to letters, "as written". Therefore you cannot use this part of the programming language.
But there's another part. The method Integer.parseInt has 2 variants: Integer.parseInt("12345") converts a decimal representation of the number into that number. The variant Integer.parseInt("101110101101", 2) parses a binary representation of a number into that number.
If there is a method toy.nextInt(2), you can use that. Otherwise you have to use Integer.parseInt(toy.next(), 2).

Related

Is there an approach to finding the ASCII distance between two strings of 5 characters

I am trying to find a way to calculate and print the Ascii distance between a string from user input
Scanner scan = new Scanner(System.in);
System.out.print("Please enter a string of 5 uppercase characters:");
String userString = scan.nextLine();
and a randomly generated string
int leftLimit = 65; // Upper-case 'A'
int rightLimit = 90; // Upper-case 'Z'
int stringLength = 5;
Random random = new Random();
String randString = random.ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
.limit(stringLength)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
Is there a way to calculate the distance without having to separate each individual character from the two strings, comparing them and adding them back together?
Use Edit distance (Levenshtein distance)
You can
Implement your own edit distance based on the algorithm on wikipedia,
you can use an existing source code, for that look at rosetta code.
use an existing library like apache LevenshteinDistance
you can also check
Levenshtein Distance on stackoverflow
Streams are, well, as the name says, streams. They don't work very well unless you can define an operation strictly on the basis of one input: One element from a stream, without knowing its index or referring to the entire collection.
Here, that is a problem; after all, to operate on, say, the 'H' in your input, you need the matching character from your random code.
I'm not sure why you find 'separate each individual character, compare them, and add them back together' is so distasteful to you. Isn't that a pretty clean mapping from the problem description to instructions for your computer to run?
The alternative is more convoluted: You could attempt to create a mixed object that contains both the letter as well as its index, stream over this, and use the index to look up the character in the second string. Alternatively, you could attempt to create a mix object containing both characters (so, for inputs ABCDE and HELLO, an object containing both A and H), but you'd be writing far more code to get that set up, then the simple, no-streams way.
So, let's start with the simple way:
int difference = 0;
for (int i = 0; i < stringLength; i++) {
char a = inString.charAt(i);
char b = randomString.charAt(i);
difference += difference(a, b);
}
You'd have to write the difference method yourself - but it'd be a very very simple one-liner.
Trying to take two collections of some sort, and from them create a single stream where each element in the stream is matching elements from each collection (so, a stream of ["HA", "EB", "LC", "LD", "OE"]) is generally called 'zipping' (no relation to the popular file compression algorithm and product), and java doesn't really support it (yet?). There are some third party libraries that can do it, but given that the above is so simple I don't think zipping is what you're looking for here.
If you absolutely must, I guess i'd look something like:
// a stream of 0,1,2,3,4
IntStream.range(0, stringLength)
// map 0 to "HA", 1 to "EB", etcetera
.mapToObj(idx -> "" + inString.charAt(idx) + randomString.charAt(idx))
// map "HA" to the difference score
.mapToInt(x -> difference(x))
// and sum it.
.sum();
public int difference(String a) {
// exercise for the reader
}
Create an 2D array fill the array with distances - you can index directly into the 2D array to pull out the distance between the characters.
So one expression that sums up a set of array accesses.
Here is my code for this (ASCII distance) in MATLAB
function z = asciidistance(input0)
if nargin ~= 1
error('please enter a string');
end
size0 = size(input0);
if size0(1) ~= 1
error ('please enter a string');
end
length0 = size0(2);
rng('shuffle');
a = 32;
b = 127;
string0 = (b-a).*rand(length0,1) + a;
x = char(floor(string0));
z = (input0 - x);
ascii0 = sum(abs(z),'all');
ascii1 = abs(sum(z,'all'));
disp(ascii0);
disp(ascii1);
disp(ascii0/ascii1/length0);
end
This script also differentiates between the absolute ASCII distance on a per-character basis vs that on a per-string basis, thus resulting in two integers returned for the ASCII distance.
I have also included the limit of these two values, the value of which approaches the inverse of the length of strings being compared. This actually approximates the entropy, E, of every random string generation event when run.
After standard error checking, the script first finds the length of the input string. The rnd function seeds the random number generator. the a and b variables define the ASCII table minus non-printable characters, which ends at 126, inclusively. 127 is actually used as an upper bound so that the next line of code can generate a random string of variables of input length. The following line of code turns the string into the alphanumeric characters provided by the ASCII table. The following line of code subtracts the two strings element-wise and stores the result. The next two lines of code sum up the ASCII distances in the two ways mentioned in the first paragraph. Finally, the values are printed out, as well as providing the entropy, E, of the random string generation event.

Java Hexadecimal to Decimal conversion: Custom Logic

I am trying to figure out how to convert hex into a string and integer so I can manipulate an RGB light on my arduino micro-controller through it's serialport. I found a good example on the java website, but I'm having a difficult time understanding some of the methods and I am getting hung up. I could easily just copy-paste this code and have it work but I want to fully understand it. I will add comments to my understandings and hopefully someone can provide some feedback.
public class HexToDecimalExample3{
public static int getDecimal(String hex){ //this is the function which we will call later and they are declaring string hex here. Can we declare string hex inside the scope..?
String digits = "0123456789ABCDEF"; //declaring string "digits" with all possible inputs in linear order for later indexing
hex = hex.toUpperCase(); //converting string to uppercase, just "in case"
int val = 0; //declaring int val. I don't get this part.
for (int i = 0; i < hex.length(); i++) //hex.length is how long the string is I think, so we don't finish the loop until all letters in string is done. pls validate this
{
char c = hex.charAt(i); //char is completely new to me. Are we taking the characters from the string 'hex' and making an indexed array of a sort? It seems similar to indexOf but non-linear? help me understand this..
int d = digits.indexOf(c); //indexing linearly where 0=1 and A=11 and storing to an integer variable
val = 16*val + d; //How do we multiply 16(bits) by val=0 to get a converted value? I do not get this..
}
return val;
}
public static void main(String args[]){
System.out.println("Decimal of a is: "+getDecimal("a")); //printing the conversions out.
System.out.println("Decimal of f is: "+getDecimal("f"));
System.out.println("Decimal of 121 is: "+getDecimal("121"));
}}
To summerize the comments, it's primarily the char c = hex.charAt(i); AND the val = 16*val + d; parts I don't understand.
Ok, let's go line for line
public static int getDecimal(String hex)
hex is the parameter, it needs to be declared there, so you can pass a String when you call the function.
String digits = "0123456789ABCDEF";
Yes, this declares a string with all characters which can occur in a hexadecimal number.
hex = hex.toUpperCase();
It converts the letters in the hex-String to upper case, so that it is consistent, i.e. you always have F and never f, no matter which is being input.
int val = 0;
This is the variable where the corresponding decimal value will later be in. We will do our calculations with this variable.
for (int i = 0; i < hex.length(); i++)
hex.length() is the number of characters in the hex-String provided. We execute the code inside this for loop once per character.
char c = hex.charAt(i);
Yes, char represents a single character. We retrieve the character from the hex-String at index i, so in the first iteration it is the first character, in the second iteration the second character and so on.
int d = digits.indexOf(c);
We look which index the character has in the digit-String. In that way we determine the decimal representation of this specific digit. Like 0-9 stay 0-9 and F becomes a 15.
val = 16*val + d;
Let's think about what we have to do. We have the decimal value of the digit. But in hexadecimal we have this digit at a specific position with which it gets multiplied. Like the '1' in '100' is actually not a 1, but 100 * 1 because it is at this position.
10 in hexadecimal is 16 in decimal, because we have 1 * 16. Now the approach here is a little bit complicated. val is not uninitialized. val is 0 at the beginning and then contains the cumulated values from the previous iterations. Since the first character in the String is the highest position we don't know directly with what we have to multiply, because we don't know how many digits the number has (actually we do, but this approach doesn't use this). So we just add the digit value to it. In the consecutive iterations it will get multiplied by 16 to scale it up to the corresponding digit base value. Let me show you an example:
Take 25F as hex number. Now the first iteration takes the 2 and converts it to a 2 and adds it to val. The 16 * val resolves to 0 so is not effective in the first time.
The next iteration multiplies the 2 with 16 and takes the 5 (converted to 5) and adds it to val. So now we have (I split it mathematically so you understand it):
2 * 16 + 5
Next we get the F which is decimal 15. We multiply val by 16 and add the 15.
We get 2 * 256 + 5 * 16 + 16 (* 1), which is actually how you calculate the decimal value of this hex value mathematically.
Another possibility to compute val is:
val += Math.pow(16, hex.length() - i - 1) * d;

How do I get the quotient of two ints to round up? (5/2)

I am having some trouble with some extra credit stuff my AP Computer Science teacher assigned. Here are the instructions:
Write a WordScrambler method recombine. This method returns a String created from its two String parameters as follows:
take the first half of word1
take the second half of word2
concatenate the two halves and return the new string
For example, the following lines show some results of calling recombine. Note that if a word has an odd number of letters, the second half of the word contains the extra letter.
here are the examples it gives:
"apple" + "pear" = "apar"
"pear" + "apple" = "peple"
it then says to create method recombine below, only giving one line of code:
private String recombine(String word1, String word2)
then I have to create the rest. I made a test program just to see if my ideas were correct, that I could use length() and substring() to do it (I know I will have to use them some time in it), then I would change the code to work with the private String recombine(word1,word2) bit. So here is my test code:
public class test
{
private static String word1,word2;
public static void main(String[]args){
word1 = "apple";
word2 = "pear";
int length1 = word1.length();
int length2 = word2.length();
System.out.println(length1);
System.out.println(length2);
int half1 = (int)Math.ceil(length1 / 2);
int half2 = length2 / 2;
System.out.println(half1);
System.out.println(half2);
}
}
the output is:
5
4
2
2
As you can see, the variable half1 should be 2.5, but since you cant use half of a letter, it should round up, but even with (int)Math.ceil it still rounds down. When I take out the int, just to see if it works as a double, it gives me an error, 'Possible loss of precision, required:int; found:double;`
The general answer to your question, for the quotient of two positive numbers a and b, is to compute(*) (a + b - 1) / b with the truncating division that most programming languages have. This produces the integer immediately above the real a / b.
In your example, b is 2. The value of length1 / 2 rounded up can be computed as (length1 + 1) / 2.
(*) This is assuming that a + b - 1 can be computed without overflow, which should not be a problem in your example.
The reason your code does not round down is that the division length1 / 2 happens before Math.ceil call, and it happens in integers.
You can round up division without using Math.ceil. For that you add a number that is less than the divisor by one to the number being divided. For example, if you want to round up the result of division by ten, add nine to the dividend:
int res = (d + 9) / 10; // Rounds up
In your case, all you need is to add one to length1:
int half1 = (length1+1) / 2;
The immediate solution is just to do the division in floating point:
int half1 = (int)Math.ceil(length1 / 2.0);
2 is an int literal and 2.0 is a double literal. Java will automatically promote length1 to double in the presence of 2.0 so this is effectively the following:
int half1 = (int)Math.ceil((double)length1 / 2.0);
But as noted by the other two answers, you don't need to use floating point. Furthermore, double only has 53 bits of integral precision so while doing the division in floating point works for an int it may result in error for a long.

String trim coming out with incorrect length

I am using Java to determine the length of a double as part of a larger program. At this time the double is 666 but the length is returning as 5, which is a big problem. I read another question posted here with a solution but that didn't work for me. I will show my code and my attempt at emulating the previous solution with results.
My original code:
double Real = 666;
int lengthTest = String.valueOf(Real).trim().length();
System.out.println("Test: " + lengthTest);
This prints 5
Modifications that didn't work, and were essentially just breaking up the code into multiple lines.
double Real = 666;
String part = Real + "";
part = part.trim();
int newLength = part.length();
System.out.println("new length : " + newLength);
This prints 5 as well.
Obviously, I want this to print how many digits I have, in this case it should show 3.
For a bigger picture if it helps I am breaking down number input into constituent parts, and making sure none of them exceed limits. ie: xx.yyezz where xx can be 5 digits, yy can be 5 digits and zz can be 2 digits. Thank you.
That's because you are using a double.
String.valueOf(Real); // returns 666.0, i.e. length 5
Try casting it to an integer first:
Integer simple = (int) Real;
String.valueOf(simple); // returns 666, i.e. length 3.
A double always puts a decimal place after the number. So the number looks like 666.0. You could see this by printing String.valueOf(Real). You should use an int instead or cast the double to an int:
double Real = 666;
int realInt = (int) Real;
System.out.println(String.valueOf(realInt).length());

Java code to convert from Base-10 to Base-9

How to convert a long number in base 10 to base 9 without converting to string ?
FWIW, all values are actually in base 2 inside your machine (I bet you already knew that). It only shows up as base 10 because string conversion creates string representations in base 10 (e.g. when you print), because methods like parseLong assumes the input string is in base 10 and because the compiler expects all literals to be in base 10 when you actually write code. In other words, everything is in binary, the computer only converts stuff into and from base 10 for the convenience of us humans.
It follows that we should be easily able to change the output base to be something other than 10, and hence get string representations for the same value in base 9. In Java this is done by passing an optional extra base parameter into the Long.toString method.
long x=10;
System.out.println(Long.toString(x,9));
Long base10 = 10;
Long.valueOf(base10.toString(), 9);
What does "convert to base 9 without converting to string" actually mean?
Base-9, base-10, base-2 (binary), base-16 (hexadecimal), are just ways to represent numbers. The value itself does not depend on how you represent it. int x = 256 is exactly the same as int x = 0xff as far as the compiler is concerned.
If you don't want to "convert to string" (I read this as meaning you are not concerned with the representation of the value), then what do you want to do exactly?
You can't convert to base 9 without converting to string.
When you write
Long a = 123;
you're making the implicit assumption that it's in base 10. If you want to interpret that as a base 9 number that's fine, but there's no way Java (or any other language I know of) is suddenly going to see it that way and so 8+1 will return 9 and not 10. There's native support for base 2, 8, 16 and 10 but for any other base you'll have to treat it as a string. (And then, if you're sure you want this, convert it back to a long)
You have to apply the algorithm that converts number from one base to another by applying repeated modulo operations. Look here for a Java implementation. I report here the code found on that site. The variable M must contain the number to be converted, and N is the new base.
Caveat: for the snippet to work properly, N>=1 && N<=10 must be true. The extension with N>10 is left to the interested reader (you have to use letters instead of digits).
String Conversion(int M, int N) // return string, accept two integers
{
Stack stack = new Stack(); // create a stack
while (M >= N) // now the repetitive loop is clearly seen
{
stack.push(M mod N); // store a digit
M = M/N; // find new M
}
// now it's time to collect the digits together
String str = new String(""+M); // create a string with a single digit M
while (stack.NotEmpty())
str = str+stack.pop() // get from the stack next digit
return str;
}
If you LITERALLY can do anything but convert to string do the following:
public static long toBase(long num, int base) {
long result;
StringBuilder buffer = new StringBuilder();
buffer.append(Long.toString(num, base));
return Long.parseLong(buffer.toString());
}

Categories

Resources