I encountered a code which some parts I do not understand. It has something to do with keeping count of letters in a string. I have commented the part that I do not get. I would appreciate any help. Thank you!
I tried looking it up online but none seem to answer my question.
public class test2 {
static int[] inventory;
public static final int ALPHABET = 26;
public static void main(String[] args) {
inventory = new int [ALPHABET];
String dog = "There goes the dog!";
int size = count(dog);
System.out.println(size);
}
private static int count(String data) {
data = data.toLowerCase();
int size = 0;
for (int i = 0; i < data.length(); i++) {
char ch = data.charAt(i);
if (Character.isLetter(ch)) {
size++;
inventory[ch - 'a']++; // this I don't get
}
}
return size;
}
}
In this case, inventory is an array of size 26 which holds number of times each character appears in the string.
The statement you have put the comment on is trying to deduct the ASCII value of a which is 97 from the character in the string. For example, b's ASCII value is 98 and 'b' - 'a' is 1. So, inventory[1] is incremented i.e b appeared in your string once.
System.out.println(0 + 'c'); //ASCII value of 'c'; will print 99
System.out.println(0 + 'a'); //ASCII value of 'a'; will print 97
System.out.println('c' - 'a'); //Difference of ASCII values of characters; will print 99-97=2
In your case
inventory[ch - 'a']++;
ch will be some character.
ch - 'a' will be the distance of that character from 'a'. For example, as shown above, 'c' - 'a' = 2.
inventory[ch - 'a'] will point to the number at index ch - 'a' in the array.
inventory[ch - 'a']++ will increment that value by 1.
As per the above code, you're trying to count the number of each alphabets.
So, for each letter, let's assume you use a single bucket. Which is done by new int [ALPHABET];. So, you have 26 slots from 0 to 25.
Now, when you're counting the letters: Each letter has a value assigned to it (ASCII value). ASCII value of lower case a a is 97. But, in your slot, you want to add a to slot 0. So, what do you do: you subtract 97 i.e. you subtract value of a for each letter.
So now, a is stored in slot 0, b in slot 1 and so on.
Related
Can you guys, please, explain to me what does count[word.charAt(i)]++, exactly do in this code and overall--?
public static void main(String[] args) {
String S = "Some random text to test.";
int count[] = new int[124];
for (int i=0; i< S.length(); i++) {
count[S.charAt(i)]++;
System.out.print(count[S.charAt(i)] + " ");
}
int max = 1;
char result = ' ';
for (int i = 0; i < S.length(); i++) {
if (max < count[S.charAt(i)] && S.charAt(i) != ' ') {
max = count[S.charAt(i)];
result = S.charAt(i);
}
}
System.out.println(result);
}
The printing of count[S.charAt(i)] was just me trying to figure it out.
S.charAt(i) returns the character in the i-th position of that string S.
Then count[S.charAt(i)] will execute like this. Lets say you get 'S' as the character. Then the character value for 'S' will be 83. So, it will take the element of the 83 index in count array and increment it by one.
word.charAt(i) returns the character at the i-th index in the String word.
count is an int array with all zeros automatically : int count[] = new int[124];
count[i]++ increments the value that is in count at index i by 1.
Here, you're passing word.charAt(i) as an index i.e count[word.charAt(i)]++, and what it does is:
-Evaluate word.charAt(i) first, but
note that index i must be an integer!
so automatically gets the ASCII value of the character. For example ('a' = 97, 'b' = 98..)
-then, count[ASCII number returned]++, for example count[97]++, will be incremented and now count[97] = 1
But note that if your String has '}', there will be Index out of bound exception, since its ASCII value is 125; and 125 > 124 the size of count!
So I'm working on some Java exercises, and one that has caught my attention recently is trying to produce all permutations of a String using iteration. There are plenty of examples online - however, a lot of them seem very complex and I'm not able to follow.
I have tried using my own method, which when tested with a string of length 3 it works fine. The method is to (for each letter) keep moving a letter along the string, swapping it with whatever letter is in front of it. E.g.
index: 012
string: abc
(iteration 1) swap 'a' (index 0) with letter after it 'b' (index 0+1) : bac
(iteration 2) swap 'a' (index 1) with letter after it 'c' (index 1+1) : bca
(iteration 3) swap 'a' (index 2) with letter after it 'b' (index 0) : acb
current permutations: abc (original), bac, bca, acb
(iteration 3) swap 'b' (index 1) with letter after it 'c' (index 1+1) : acb
(iteration 4) swap 'b' (index 2) with letter after it 'a' (index 0) : bca
(iteration 5) swap 'b' (index 0) with letter after it 'c' (index 1) : cba
current permutations: abc (original), bac, bca, acb, acb, cba
...
This is how I implemented it in Java:
String str = "abc"; // string to permute
char[] letters = str.toCharArray(); // split string into char array
int setLength = factorial(letters.length); // amount of permutations = n!
HashSet<String> permutations = new HashSet<String>(); // store permutations in Set to avoid duplicates
permutations.add(str); // add original string to set
// algorithm as described above
for (int i = 0; i < setLength; i++) {
for (int j = 0; j < letters.length; j++) {
int k;
if (j == letters.length - 1) {
k = 0;
} else {
k = j + 1;
}
letters = swap(letters, j, k);
String perm = new String(letters);
permutations.add(perm);
}
}
The problem is if I input a string of length 4, I only end up with 12 permutations (4x3) - if I input a string of length 5, I only end up with 20 permutations (5x4).
Is there a simple modification I could make to this algorithm to get every possible permutation? Or does this particular method only work for strings of length 3?
Appreciate any feedback!
Suppose the input is "abcd". This is how your algorithm will work
bacd
bacd
bcad
bcda
If you observe carefully, "a" was getting positioned at all indexes and the following consecutive letter was getting replaced with "a". However, after your algorithm has produced "bacd" - it should be followed by "badc" also, which will be missing from your output.
For string of length 4, When you calculated the number of permutations as factorial, you understand that the first position can be occupied by 4 characters, followed by 3, 2 and 1. However, in your case when the first two positions are occupied by "ba" there are two possibilities for 3rd position, i.e. c and d. While your algorithm correctly finds "cd", it fails to find "dc" - because, the loop does not break the problem into further subproblems, i.e. "cd" has two permutations, respectively "cd" and "dc".
Thus, the difference in count of your permutations and actual answer will increase as the length of string increases.
To easily break problems into sub-problem and solve it, many algorithm uses recursion.
However, you could look into Generate list of all possible permutations of a string for good iterative answers.
Also, as the length of string grows, calculating number of permutation is not advisable.
While I do not know of a way to expand upon your current method of switching places (I've attempted this before to no luck), I do know of a fairly straightforward method of going about it
//simple method to set up permutate
private static void permutations(String s)
{
permutate(s, "");
}
//takes the string of chars to swap around (s) and the base of the string to add to
private static void permutate(String s, String base)
{
//nothing left to swap, just print out
if(s.length() <= 1)
System.out.println(base + s);
else
//loop through the string of chars to flip around
for(int i = 0; i < s.length(); i++)
//call with a smaller string of chars to flip (not including selected char), add selected char to base
permutate(s.substring(0, i) + s.substring(i + 1), base + s.charAt(i));
}
The goal with this recursion is to delegate as much processing as possible to something else, breaking the problem down bit by bit. It's easy to break down this problem by choosing a char to be first, then telling a function to figure out the rest. This can then be done for each char until they've all been chosen once
so I am trying to set each of the letter in the alphabet to a number like a = 1
b = 2 c =3 and so on.
int char = "a";
int[] num = new int{26};
for (int i = 0; i <num.length; i++){
System.out.print(i);
But after this i got Stuck so if you possible help me out. So when the users input a word like cat it would out put 3-1-20.
You can subtract 'a' from each char and add 1. E.g.
String input = "cat";
for (char c : input.toCharArray()) {
System.out.print(c - 'a' + 1);
}
The code you posted doesn't compile as you can't assign a String to an int and char is a reserved word (name of a primitive type)
int char = "a";
You also mention that you want the output formatted like this "3-1-20". This is one way to achieve that :
String input = "cat";
String[] out = new String[input.length()];
for (int i = 0; i < input.length(); ++i) {
out[i] = Integer.toString(input.charAt(i) - 'a' + 1);
}
System.out.println(String.join("-", out));
Both versions work only for lowercase English letters (a to z)
Assigning a number to a character is called an "encoding". As computers can only handle numbers internally, this happens all the time. Even this text here is encoded (probably into an encoding called "UTF-8") and then the resulting number is stored somewhere.
One very basic encoding is the so called ASCII (American Standard Code for Information Interchange). ASCII already does what you want, it assigns a number to each character, only that the number for "A" is 65 instead 1.
So, how does that help? We can assume that for the character A-z, the numeric value of a char is equal to the ASCII code (it's not true for every character, but for the most basic ones, it's good enough).
And this is why everyone here tells you to subtract 'A' or 'a': Your character is a char, which is a character, but also the numeric value of that character, so you can subtract 'A' (again, a char) and add 1:
'B' - 'A' + 1 = 2
because...
66 (numeric value of 'B') - 65 (numeric value of 'A') + 1 = 2
Actually, char is not ASCII, but UTF-8, but there it starts to get slightly bit more complex, so ASCII will suffice for the moment.
the best way of doing this is to convert the String to a byte[], like this:
char[] buffer = str.toCharArray();
Then each of the characters can be converted to their byte-value (which are constants for a certain encoding), like this:
byte[] b = new byte[buffer.length];
for (int i = 0; i < b.length; i++) {
b[i] = (byte) buffer[i];
}
Now look at the resulting values and subtract/add some value to get the desired results!
Here is what the teacher asked me to do:
Enter a phone number (set up a string-type object for the phone number)
example:
(703) 323-3000
Display the phone number, using a format like the following:
Example 1:
The phone number you entered is 703-323-3000.
Display the content of the array that holds the count for each digit in the string. Use a format similar to the following:
Example:
Digit 0 showed up 4 times.
Digit 1 showed up 0 times.
Digit 2 showed up 1 times.
Digit 3 showed up 4 times.
Digit 4 showed up 0 times.
Digit 5 showed up 0 times.
Digit 6 showed up 0 times.
Digit 7 showed up 1 times.
Digit 8 showed up 0 times.
Digit 9 showed up 0 times
The teacher also provided us with an algorithm as a hint:
set up an integer array of size 10
initialize each element to zero
input string of phone number
set SIZE = length of the string
set up a loop to iterate SIZE times
{
get next character
update array appropriately
(for example: if the character is '7' then increment array[7] by 1.
}
Display BOTH using appropriate messages:
the original phone number
contents of the array (using a loop).
Here is My code but it shows the error I mentioned when i use the equals() method, and displays a wrong answer if i use ==. Please Help.
public class Phones
{
public static void main(String[] args)
{
int Num[] = {0,0,0,0,0,0,0,0,0,0};
String Phone = "703-323-3000";
int SIZE = Phone.length() - 1;
for(int count=0; count<= SIZE; count++)
{
for(int counter = 0; counter <= SIZE; counter++)
{
if(Phone.charAt(counter).equals(count))
Num[count]++;
}
System.out.println("Digit " + count + " showed up " + Num[count] + " times");
}
}
}
This is my first time on this site, so sorry in advance if this is too long or incomprehensible. Thank you.
The reason you get the wrong answer with == is that you're comparing a char with an int incorrectly. In short, you're comparing counter with the unicode value of the characters, rather than with the number that the character represents. (For "normal" characters like letters, numbers and simple punctuation, the unicode values are the same as the ASCII values.)
The char '0' does not have an int value 0 -- it has the unicode value for the char 0, which is 0x0030 (aka 48 in base 10 -- the 0x format shows it in hex). By comparing the char the way you're doing, the first comparison will only be true if the char is the so-called "null char" 0x0000 (not to be confused with null, which is a null reference!), which won't happen for any sort of "normal" input.
Instead, you need a way to compare chars with ints. The easiest way to do this is to subtract the '0' char's value from the current char:
int charDistanceFromZero = Phone.charAt(counter) - '0';
If that distance is less than 0 or greater than 9, you have a char that's not a number. Otherwise, charDistanceFromZero is the offset you need into the array.
This works because the characters for the number digits start at 0 and are sequential from there. Try computing charDistanceFromZero for a few of them to get a feel for how it works out for getting the array index.
charAt will return a value of type char, which is the reason why you cannot do .equals(...).
Also, the characters representing the digits are in ['0' .. '9'], which isn't the same as the interval [0 .. 9]. You need to translate the range by subtracting '0'.
The reason for your error is that charAt returns a char, which is a primitive type. You need to have an object, not a primitive, in order to be able to call a method, such as .equals. Moreover, when you tried to use == in place of .equals, you were comparing a char to an int value. It's all right to do this, so long as you remember that the int value of a character is its encoded value, so 48 for '0', 49 for '1' and so on.
To solve this problem, it's best to use the methods that come for free in Java's Character class; notably isDigit, which determines whether a character is a digit, and getNumericValue, which converts a character to the number that it represents.
It's also possible to dispense with the outer loop entirely, since once you've converted each digit character to its numeric value, you already have the index in the array that you want to increment. So here is a much cleaner solution, that does not use nested loops at all.
public class Phones{
public static void main(String[] args){
int counters[] = new int[10];
String phone = "703-323-3000";
for (char eachCharacter : phone.toCharArray()) {
if (Character.isDigit(eachCharacter)) {
int digit = Character.getNumericValue(eachCharacter);
counters[digit]++;
}
}
for(int digit = 0; digit < 10; digit++) {
if (counters[digit] != 0) {
System.out.format("Digit %d showed up %d times.%n", digit, counters[digit]);
}
}
}
}
Here, the first loop traverses your input string, incrementing the array index corresponding to each digit in the string. The second loop just prints out the counts that it's found.
Other answers are fine... But to reduce ambiguity in code I generally just send the string into a char array before doing any control flows... And as noted, 'Zero' is at Unicode Code Point 48 so you need to subtract that value from the character index.
char[] number = "212-555-1212".toCharArray();
for(int i = 0; i < numbers.length; i++) {
// do something groovy with numbers[i] - 48
}
So for this solution you might do something like this....
String phone = "212-555-1212".replaceAll( "[^\\d]", "" );
int[] nums = new int[phone.length()];
int[] queue = new int[phone.length()];
for(int i = 0; i < nums.length; i++) {
nums[i] = phone.toCharArray()[i] - 48;
for(int num : nums) {
if( nums[i] == num ) {
queue[i] += 1;
}
}
System.out.println( "Number: " + nums[i] + " Appeared: " + queue[i] + " times." );
}
I typed in the following code in eclipse, and expected rows of ten characters per line. However, I cannot figure out why the first and last lines only have 3 characters. Can anyone help?
package chapter4;
import java.util.*;
public class DisplayChars {
public static void printChars(char c1, char c2, int num){
for(int i = (int)c1; i <= (int)c2; i++){
if(i % num == 0)
System.out.println("");
System.out.print((char)i);
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("please enter two characters and the number per line");
char c1 = (char)input.next().charAt(0);
char c2 = (char)input.next().charAt(0);
int numberPerLine = input.nextInt();
printChars(c1, c2, numberPerLine);
}
}
And the output is as follows:
please enter two characters and the number per line
a
z
10
abc
defghijklm
nopqrstuvw
xyz
The character code for a is 97. You see the characters a through c on one line because that's characters 97-99. Then d through m is 100-109, n through w is 110-119, and x through z is 120-122.
To get 10 on a line to start with, don't use i as indicator to determine when to print a newline. Use another variable for that purpose.
You start counting from 'a', not zero. And notably, 'a' % 10 is not zero.
In ASCII a=97 so after 3 iterations you encounter d=100. And in the last line your loop ends so last 3 characters.
The explanation is that when the first character is "a", the int value of a is not a multiple of 10, so (i % num) likely evaluates to 7 on the first iteration of the loop, leading to only 3 characters being printed on the first line. You could rewrite it like this:
public static void printChars(char c1, char c2, int num){
int count = 0;
while (c1 <= c2) {
System.out.print(c1);
count++;
if (count == num) {
count = 0;
System.out.println("");
}
c1++;
}
}