I want to convert those if-statements into a ternary operator expression, but I've been struggling since I haven't had the need to use them that much. The code essentially replaces the characters '1' with 'i', removes characters that are not letters, and also removes upper-case letters by enqueuing elements that don't meet those conditions.
private static Iterable<Character> transformationA(Queue<Character> q) {
Queue<Character> retq = new Queue<>();
for(Character c: q) {
if(c.equals('1')) {
retq.enqueue('i');
}
if(Character.isLowerCase(c)) {
retq.enqueue(c);
}
}
return retq;
}
Edit: thanks for your comments, code and suggestions.
Something like:
inQueue.stream()
.map(c -> '1'.equals(c)?'i':c)
.filter(Character::isLowerCase)
.collect(Collectors.toCollection(Queue::new)));
Ternary operation does not fit
As commented, a ternary operation is not appropriate to your code. A ternary operation in Java is an expression, returning a result.
In your case, you do not have a "if x is true, return y, otherwise return z" situation. In your case you may enqueue an I, or you may enqueue a lowercase letter, or you may do nothing (thereby ignoring that nth character).
Unicode code points
The char type (and its Character wrapper class) are legacy, essentially broken. As a 16-bit value, the char type is incapable of representing even half of the characters defined in Unicode.
Instead use Unicode code point integer numbers.
Pass in a collection of int or Integer (or IntStream) rather than Character objects. And actually, I would just pass in a CharSequence (the interface for String, etc.).
To see if the code point represents the character for the digit 1, check for a code point number of 49 (decimal), the ASCII/Unicode number for the digit 1: if( codePoint == 49 ) { … } where codePoint is an int/Integer.
For lowercase check, pass the code point integer: if( Character.isLowerCase( codePoint ) ) { … }.
Related
I'm trying to find a way to convert a char (Precondition is the char can only be '0' or '1') into an actual bit in Java. I'm not sure if Java has some built-in functionality for this, or if there is an algorithm that can be implemented to do so.
I need to implement the following class:
public void writeBit(char bit) {
//PRE:bit == '0' || bit == '1'
try {
} catch (IOException e) {
System.out.println(e);
}
}
I cannot change the method structure in any way. I am implementing Huffman Encoding and have an array of Strings that represent the encodings for every character within an input file. For example, 'A' or array[65] contains the String: "01011". So if I see the letter A in my file, I need to use writeBit to write out A's respective String to a binary file. Every time I reach 8 bits (one byte) I will call writeByte to send those 8 bits to the binary file, then reset some sort of counter variable to 0 and continue.
What I'm stuck on is how I am supposed to convert the char bit into an actual bit, so that it can be properly written out to a binary file.
Java does not have a primitive data type representing a single bit. On many hardware architectures, it is not even possible to access memory with that granularity.
When you say "an actual bit", then, I can only assume that you mean an integer value that is either 0 or 1, as opposed to char values '0' and '1'. There are numerous ways to perform such a conversion, among them:
byte the_bit = bit - '0';. This takes advantage of the fact that char is an integer type, and that the decimal digits zero and one are encoded in Java with consecutive character codes.
byte the_bit = (bit == '0') ? 0 : 1;. This just explicitly tests whether bit contains the value '0', evaluating to 0 if so or 1 if not.
It gets more complicated from there, for example:
byte the_bit = Byte.parseByte(String.valueOf(bit));. This converts the char to a string containing (only) that char, and then parses it as the string representation of a byte.
All of the above rely to one degree or another on the precondition given: that bit does not have any value other than '0' or '1'.
With that said, I think anything like this is probably the wrong approach for implementing a Huffman encoding, because Java Strings are an unlikely, very heavyweight, representation for the bit strings involved.
You can use Integer.parseInt(String s, int radix) or Integer.parseUnsignedInt(String s, int radix) with radix 2, to convert from a "binary digits string" to internal int java integer form.
public static void main(String[] args) {
int num = Integer.parseInt("101010", 2);
// print 42
System.out.println(num);
}
And reversely with method Integer.toBinaryString(int i) you can generate the binary string representation:
// print 101010
System.out.println(Integer.toBinaryString(42));
Similarly you can use Byte.parseByte(String s, int radix) to parse a byte:
public static void main(String[] args) {
byte num = Byte.parseByte("101010", 2);
// print 42
System.out.println(num);
}
As a Java beginner I'm playing around with a case statement at this point.
I have set: int d = '1'; And with: System.out.println("number is: " + d);, this returns 51.
Now I found out that if I set it as: int d = 1;, it does return 1.
Now my question is why does it return 49 when I set it as '3'? What difference do the ' ' make?
My code that returns 49:
int a = '1';
switch(a)
{
case '1' :
System.out.println("Good");
break;
case '2' :
case '3' :
System.out.println("great");
break;
default :
System.out.println("invalid");
}
System.out.println("value: " + a);
'1' is the character '1', whose integer value is 49. Each character has a numeric value in the range from 0 to 2^16-1. Therefore 1 and '1' are different integer values.
With ' (single quotes) around a character you tell the compiler that the value in between is a character (variable type char in Java). Generally, computers only understand numbers so characters get represented as numbers in memory as well. The value of the character '1' is 49. You want to actually save the value 1 in memory and use that to calculate things. So, you have to tell the compiler that you want this to be interpreted as an actual number and not as a character.
To summarize:
'1' is the character that prints the number 1
1 is the actual number 1
This means 1 and '1' have different integer values.
You can look at the integer value of the most commonly used characters in coding here: ASCII Table
In Java the character values are stored as int internally. That means when you assign a char value using 'A' to an int type, the compiler casts the char value into int and thus the UTF-16 Code unit value is stored into the int variable.
Try this one as well:
int yourInt = 33;
char ch = (char) yourInt;
System.out.println(yourInt);
System.out.println(ch);
1 is interpreted as a character whose value is 49.
Do:
int a = 1;
switch(a) {
case 1:
...
Or, if you go with your current code:
System.out.println("value: " + Integer.parseInt((char)a+'');
It is happens because for some weird reason java treat char type as short.
Your '1' expression is constant expression of type char. It is stored internally as some numeric value. Usually all goes fine with this approach for example System.out.println('1') will print exactly what you expect.
But when you write int a = '1'; you char value is converted to int value because char behave like short int there.
PS: if there was no implicit conversion between char and int (which anyway have no sense) you just got compilation error.
When you declare int d='1'; then 1 is not treated as integer it is a character. It is converted to 49 according its unicode value. similarly character '3' will coverted to 51. Jvm do implicit type casting from character to integer.
you should try this code
char c = '3';
int a ='1';
System.out.println(c);
System.out.println((int)c);
You will get output as
3
51
49
public static int get(String A) // it is a method
{
int count = 1;
for (int i = 0; i < A.length(); i++) // So A reads line (any word, for example "Car"), so I understand that length will be 3 and that java will check all the characters.
{
int num = (A.charAt(i) - 'A') + 1;
count *= num;
}
return count;
}
You write A.charAt(i) because charAt is a function, not an array.
You write A.charAt(i) - 'A' to compute the difference between A's i:th character and the character 'A'.
The class String is an immutable or value object. It doesn't give you direct access to the characters which make up the string, mainly for performance reasons but also since it helps to avoid a whole class of bugs.
That's why you can't use the array access via []. You could call A.getChars() but that would create a copy of the underlying character array.
char is the code for a character. 'A' == 65, for example. See this table. If A.charAt(1) returns 'F' (or 70), then 'F' - 'A' gives you 5. +1 gives 6.
So the code above turns letters into a number. A pattern which you'll see pretty often is charAt(i) - '0' to turn a string into a number.
But the code above is odd in this respect since count *= num produces a pretty random result for the input. To turn the letters into numbers, base 26, it should read count = count * 26 + num.
A.charAt(i) is a method for strings, you could also do A[i] to access the same position directly.
When you do an operation (+ or -) with chars, you get an int.
Java API for charAt() function
charAt() is a java method, not an Array
returns the char value at the specified index.
Syntax:
Here is the syntax of this method:
public char charAt(int index);
Because charAt() is a method that returns a character from a given String, and not an array. Characters are written 'A'. Strings are written "A".
Because charAt is a method within string and it accepts index. String internally maintains char array and it's all hidden from us and hence you have a method not the array itself.
Reason for -'A' is user wants to convert that character to integer. So for e.g. You character is 'B', User wants to convert it into int using ascii value of 'B' which is 66 - ascii value of 'A' which 65
num = 66 - 65 + 1
And do further processing.
because charAt() is a method in java for string it and it returns a character. and 'A' refers to a char type while we write "A" for string type
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#charAt%28int%29
How can I "translate" this XSLT code to Java ?
<xsl:value-of select="number(string-to-codepoints(upper-case($char)) - string-to-codepoints('A'))+10"/>
I only know that: "The fn:string-to-codepoints function returns a sequence of xs:integer values representing the Unicode code points."
From the example that is given in (http://www.xsltfunctions.com/xsl/fn_string-to-codepoints.html) :
string-to-codepoints('a') = 97
I found this:
char ch = 'a';
System.out.println(String.format("\\u%04x", (int) ch));
But I get : \u0061
For a single char you can just cast it to int to get the decimal value:
System.out.println((int)ch);
For a String there's .toCharArray() to convert it to a char[] but that isn't quite the same as a "sequence of codepoints" if the String involves Unicode characters outside the BMP (i.e. above U+FFFF), which are represented in Java as a surrogate pair of two char values. To handle surrogates properly you would need to use a technique like the one described in this answer.
To answer the specific question you ask, you can do
number(string-to-codepoints(upper-case($char)) - string-to-codepoints('A'))+10
in Java as
char ch = // wherever you get $char from
int num = Character.toUpperCase(ch) - 'A' + 10;
since char is an integer type in Java and you can add or subtract char values like any other number.
But this will probably only give you a sensible answer when the initial ch is an ASCII letter.
You print the value as unicode escape sequence; XSLT prints a decimal value.
This should work much better:
System.out.println("a".codePointAt(0));
I have a small problem. I have numbers like 5421, -1 and 1. I need to print them in four bytes, like:
5421 -> 0x0000152D
-1 -> 0xFFFFFFFF
1 -> 0x00000001
Also, I have floating point numbers like 1.2, 58.654:
8.25f -> 0x41040000
8.26 -> 0x410428f6
0.7 -> 0x3f333333
I need convert both types of numbers into their hexadecimal version, but they must be exactly four bytes long (four pairs of hexadecimal digits).
Does anybody know how is this possible in Java? Please help.
Here are two functions, one for integer, one for float.
public static String hex(int n) {
// call toUpperCase() if that's required
return String.format("0x%8s", Integer.toHexString(n)).replace(' ', '0');
}
public static String hex(float f) {
// change the float to raw integer bits(according to the OP's requirement)
return hex(Float.floatToRawIntBits(f));
}
For Integers, there's an even easier way. Use capital 'X' if you want the alpha part of the hex number to be upper case, otherwise use 'x' for lowercase. The '0' in the formatter means keep leading zeroes.
public static String hex(int n)
{
return String.format("0x%04X", n);
}
Here it is for floats:
System.out.printf("0x%08X", Float.floatToRawIntBits(8.26f));
Use
String hex = Integer.toHexString(5421).toUpperCase(); // 152D
To get with leading zeroes
String hex = Integer.toHexString(0x10000 | 5421).substring(1).toUpperCase();