Why when comparing a char against another it must be taken also from a string? For example;
This does not work
while(i < t.length() && zeroCount < 5) {
if(t.charAt(i) == 0){
zeroCount++;
}
i++;
}
Nor does this
char zero = 0;
while(i < t.length() && zeroCount < 5) {
if(t.charAt(i) == zero){
zeroCount++;
}
i++;
}
The only way I managed to get it working is like this...
String zeros = "0000000000";
while(i < t.length() && zeroCount < 5) {
if(t.charAt(i) == zeros.charAt(i)){
zeroCount++;
}
i++;
}
Can anyone explain if am doing something wrong, or if it is just not acceptable to do it like the top 2 examples. If so, why?
You're confusing
char zero = 0;
with
char zero = '0';
The former is the null-character (ASCII value of zero), whereas the latter is the character representing the digit zero.
This confusion is a rather unfortunate hang-over from C, with char variables being treated as numbers as well as characters.
You are looking for the character '0'? Then compare to '0', not 0.
You're comparing against Unicode value 0 (aka U+0000, the "null" character) - which is not the same as the Unicode character representing the digit 0.
Use '0' instead of 0:
while(i < t.length() && zeroCount < 5) {
if(t.charAt(i) == '0'){
zeroCount++;
}
i++;
}
Use '0' instead of 0.
The simple answer is that the value 0 is not the same as the character '0' which has an ASCII code of 48 (IIRC).
You should compare it with the char value charAt(i) == '0' or subtract the char before comparison charAt(i) - '0' == 0
These other answers have it right, but there’s one very important thing you should know. You should never use chatAt! You should only use codePointAt.
Similarly, you mustn’t blindly use i++ to bump through a string. You need to see whether s.codePointAt(i) > Character.MAX_VALUE to know whether to give an extra i++ kicker.
For example, to print out all the codepoints in a String s in standard "U+" notation:
private static void say_U_contents(String s) {
System.out.print("U+");
for (int i = 0; i < s.length(); i++) {
System.out.printf("%X", s.codePointAt(i));
if (s.codePointAt(i) > Character.MAX_VALUE) { i++; } // UG!
if (i+1 < s.length()) { System.out.printf("."); }
}
}
That way you can output like U+61.DF, U+3C3, and U+1F4A9.1F4A9 for the corresponding strings. That last one looks like "\uD83D\uDCA9\uD83D\uDCA9", which is simply insane.
Related
I want to create a loop where when you add a number, it gives you the equivalent character in that position in the alphabet. For example, a = 0, b = 1 etc..
I've already created that and it works, but the problem I have is that when it reaches 26, I would like it go back and continue the loop. For example, 25 is z, so 27 should be b.
Code:
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase().toCharArray();
if (i < 0)
{
return null;
}
if(i > 25)
{
i = 0;
}
return Character.toString(alphabet[i]); //converts character to String and returns the character
}
You can use the modulo operation on i.
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase().toCharArray();
int i =30;
System.out.println(alphabet[i % alphabet.length]);
You don't need any arrays or loops at all. Just do this:
return (char)('a' + (i % 26));
Try using a modulo operator for your indices. For example,
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase().toCharArray();
if (i < 0) return;
i = i % 26;
return Character.toString(alphabet[i]);
Or
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase().toCharArray();
if (i > 0)
return Character.toString(alphabet[i % 26]);
else
return;
basically, Ive been asked to write a program that checks how many times a number is apparent in a string and print it out. This is what i have
BufferedReader input = new BufferedReader (new InputStreamReader (System.in));
System.out.println("Please enter your string");
String s = input.readLine();
/*System.out.println("Please enter the chracter you are looking for");
char c = (char)input.read();*/
char one = '1';
char two = '2';
char three = '3';
char four = '4';
char five = '5';
char six = '6';
char seven = '7';
char eight = '8';
char nine = '9';
char zero= '0';
int counter = 0;
for( int i=0; i<s.length(); i++ ) {
if( s.charAt(i) == one || s.charAt(i) == two || s.charAt(i) == three || s.charAt(i) == four ||
s.charAt(i) == five || s.charAt(i) == six || s.charAt(i) == seven
|| s.charAt(i) == eight || s.charAt(i) == nine || s.charAt(i) == zero ) {
counter++;
}
}
is there a faster, better way to do this? I tried another way but for this error
Error: The operator || is undefined for the argument type(s) boolean, char
Instead of declaring digits by yourself in the code, you can take a look at Character.isDigit() method in Java. This will make the code much cleaner. There's no other faster way of doing this.
If you want to count occurrence of each digit, one simple way to do that would be to use Java Maps. You can read basic tutorial about Maps from here.
this works in c#
foreach (char c in str)
{
if (c >= '0' && c <= '9')
counter++;
}
You can use the decimal value of the character (as defined in the ASCII table)
String s = "abc123def456";
int cpt = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
cpt++;
}
}
System.out.println(cpt); // 6
You can also use the Character::isDigit method
if (Character.isDigit(s.charAt(i))) {
cpt++;
}
EDIT :
If you are using Java 8+ you can turn the String in an stream of characters, apply a filter to keep the digits, and then count the number of elements in it.
long nbDigits = s.chars()
.filter(Character::isDigit) // If the character is a digit (= the isDigit() method returns true) it's kept in the stream
.count();
System.out.println(nbDigits); // 6
is there a faster, better way to do this
Your approach is absolute correct and almost maximum fast!. You could make it mo readable.
I think that general algorithm is the same for all languages with O(n):
Loop the array and increment counter when find a number character.
Your approach is absolute correct and almost maximum fast!. (note: I really think that speed between two comparisons and nine is very-very small and we should not care about it) All you can do is just write it with as less lines of code as possible. You can do following corrections:
char is integer in JVM and ASCII code for 0-9 is 0x30-0x39, so you can move from == to ch >= '0' && ch <= '9'.
Character class contains special method to check it: Character.isDigit(ch).
For java 8 you can use Streams instead of manual for...each.
Not using streams (plain old java) I think this approach provides maximum speed and lees memory objects
public int countDigits(String str) {
int count = 0;
for(int i = 0; i < str.length(); i++)
if(Character.isDigit(str.charAt(i)))
count++;
return count;
}
Using streams (from java 8). Looks good, works a little bit slower that previous example, and creates some additional objects in memory.
public int countDigits(String str) {
// could be a little bit slower, because additional objects are created inside
return (int)str.chars().filter(Character::isDigit).count();
}
P.S. If you want to show your skill, plain old java variant is more preferable. In working code, both variant are equal.
P.P.S. actually String.toCharArray() or str.chars() are look more elegant and even a little bit less performed that str.charAr(int), because they create additional objects in memory, but str.charAr(int) works directly with internal arrays. But I did not faced with problem with any approaches in real application.
This is probably a simple fix but I can't seem to solve it.
I am trying to add an integer to the ascii value of characters during a for loop.
It is giving me the error that the program expects a variable rather than a value. How can I do what I am trying to do here?
Here is the code:
public boolean toggleEncryption(){
if(encrypted == false){
for(int i = 0; i < sentence.length(); i++){
if(sentence.charAt(i) >= 65 && sentence.charAt(i) <= 90){
int x = (int)sentence.charAt(i);
x += key;
while(x > 90){
x = x - 26;
}
sentence.charAt(i) += (char)x;
}
}
}
return encrypted;
}
the line sentence.charAt(i) += (char)x; is not working for me
Simple:
sentence.charAt(i) += (char)x;
You wrongly assume that charAt() gives you a "left hand side" thingy. In other words: something that you can assign a value to; like a variable.
But this is not possible: charAt() returns an char value; that represents the char within the string at that index.
It does not give you something that allows you to manipulate the string itself! Strings are immutable; you can't use charAt() to modify its content!
In other words; you can do this:
char c = 'a';
c += 'b';
but you can't use charAt() to achieve the same!
Thus, in order to make your code work, you have to build a new string, like:
StringBuilder builder = new StringBuilder(sentence.length());
for(int i = 0; i < sentence.length(); i++) {
if(sentence.charAt(i) >= 65 && sentence.charAt(i) <= 90){
int x = (int)sentence.charAt(i);
x += key;
while(x > 90){
x = x - 26;
}
builder.append(sentence.charAt(i) + (char)x));
} else {
builder.append(sentence.charAt(i));
}
}
(disclaimer: I just wrote down the above code; there might be typos or little bugs in there; it is meant to be "pseudo code" to get you going!)
Beyond that: I find the name of that method; and how it deals with that boolean field ... a bit confusing. You see, if encryption is true ... the method does nothing?! Then it doesn't "toggle" anything. Thus that name is really misleading resp. not matching what your code is doing!
Here charAt(i) returns a char:
sentence.charAt(i) += (char)x;
1) You cannot assign a character to a value but you can do it to a variable.
2) Even if you used a variable such as
char tempChar = sentence.charAt(i);
You cannot do then :
tempChar += (char)x;
As you cannot increment (+=) a character with another character.
I have a car Object which is supposed to have a characteristic. The characteristic is supposed to have the requirements: starts with two capital letter followed by a number from 1-9 followed by 4 numbers from 0-9.
public void writeCharacteristic(){
System.out.println("write down the characteristic for the car.");
String characteristic = kb.nextLine();
progress = false;
if (characteristic.length() != 7){
System.out.println("The string is not 7 letter/numbers long");
progress = false;
}
for(int i = 0; i < 2; ++i){
if (characteristic.charAt(i) < "A" || characteristic.charAt(i) > "Z"){
System.out.println(" character number " + i + " is invalid");
progress = false;
}
}
if (characteristic.charAt(3) < "1" || characteristic.charAt(3) > "9")
progress = false;
for (int j = 3; j < 7; ++j){
if (characteristic.charAt(j) < 0 || characteristic.charAt(j) > 9)
progress =false;
}
if (progress == false){
System.out.println("characteristic will have the value null.");
characteristic = null;
}
if (progress == true)
car.setCharacteristic(characteristic);
}
I'm having a problem at the lines "if (characteristic.charAt(i) < "A" || characteristic.charAt(i) > "Z"){"
The compiler is saying "The operator < is undefined for the argument type(s) char, String"
Any help is highly appreciated, thanks.
In Java, you can compare a character (char) to a character, but you can't compare a character to a String. charAt returns a character, so you must compare its result to a character.
These are String
"A" "Z" "1" "9"
And these are characters
'A' 'Z' '1' '9'
You can compare a character to an integer (int), but the result may not be what you want. So in the code below:
for (int j = 3; j < 7; ++j){
if (characteristic.charAt(j) < 0 || characteristic.charAt(j) > 9)
0 and 9 should be change to '0' and '9'.
Note: There is another unrelated logic error in your code:
String characteristic = kb.nextLine();
progress = false;
Shouldn't progress be set to true here?
I would certainly check out the other answers on this page re. character comparisons. However, I would perhaps suggest a different approach given:
starts with two capital letter followed by a number from 1-9 followed
by 4 numbers from 0-9
and investigate regular expressions. Something like:
[A-Z]{2}[1-9][0-9]{4}
would satisfy the above requirement.
Use single quotes for chars, double quotes for Strings.
characteristic.charAt(3) < '1'
there is meaning for single and double quotes in java
And for your situation best suits is a regex
Replace the double quotes with single quotes.
You'll also have to put single quotes around the numbers when comparing them with chars, even though the compiler doesn't complain.
Compare like this
characteristic.charAt(3) < '1'
First, you can achieve this goal with regexp:
[A-Z]{2}[1-9][0-9]{4}
(Read Pattern article to know how to use it).
If you want to do it as you started - use singleqoutes instead of doublequotes with characters. e.g. "a" -> 'a'.
If you want to assign value to char use single quote. If it is a String use double quote
char myChar='a';
String myString="a";
so
characteristic.charAt(3) < "1" should change as characteristic.charAt(3) < '1'
I've got a simple java assignment. I need to determine if a string starts with the letter A through I. I know i have to use string.startsWith(); but I don't want to write, if(string.startsWith("a")); all the way to I, it seems in efficient. Should I be using a loop of some sort?
You don't need regular expressions for this.
Try this, assuming you want uppercase only:
char c = string.charAt(0);
if (c >= 'A' && c <= 'I') { ... }
If you do want a regex solution however, you can use this (ideone):
if (string.matches("^[A-I].*$")) { ... }
if ( string.charAt(0) >= 'A' && string.charAt(0) <= 'I' )
{
}
should do it
How about this for brevity?
if (0 <= "ABCDEFGHI".indexOf(string.charAt(0))) {
// string starts with a character between 'A' and 'I' inclusive
}
Try
string.charAt(0) >= 'a' && string.charAt(0) <= 'j'
char c=string.toLowerCase().charAt(0);
if( c >= 'a' && c <= 'i' )
...
This makes it easy to extract it as a method:
public static boolean startsBetween(String s, char lowest, char highest) {
char c=s.charAt(0);
c=Character.toLowerCase(c); //thx refp
return c >= lowest && c <= highest;
}
which is HIGHLY preferred to any inline solution. For the win, tag it as final so java inlines it for you and gives you better performance than a coded-inline solution as well.
if ( string.toUpperCase().charAt(0) >= 'A' && string.toUpperCase().charAt(0) <= 'I' )
should be the easiest version...