I want to write a program that takes a string text, counts the appearances of every letter in English and stores them inside an array.and print the result like this:
java test abaacc
a:***
b:*
c:**
* - As many time the letter appears.
public static void main (String[] args) {
String input = args[0];
char [] letters = input.toCharArray();
System.out.println((char)97);
String a = "a:";
for (int i=0; i<letters.length; i++) {
int temp = letters[i];
i = i+97;
if (temp == (char)i) {
temp = temp + "*";
}
i = i - 97;
}
System.out.println(temp);
}
Writing (char)97 makes the code less readable. Use 'a'.
As 3kings said in a comment, you need an array of 26 counters, one for each letter of the English alphabet.
Your code should also handle both uppercase and lowercase letters.
private static void printLetterCounts(String text) {
int[] letterCount = new int[26];
for (char c : text.toCharArray())
if (c >= 'a' && c <= 'z')
letterCount[c - 'a']++;
else if (c >= 'A' && c <= 'Z')
letterCount[c - 'A']++;
for (int i = 0; i < 26; i++)
if (letterCount[i] > 0) {
char[] stars = new char[letterCount[i]];
Arrays.fill(stars, '*');
System.out.println((char)('a' + i) + ":" + new String(stars));
}
}
Test
printLetterCounts("abaacc");
System.out.println();
printLetterCounts("This is a test of the letter counting logic");
Output
a:***
b:*
c:**
a:*
c:**
e:****
f:*
g:**
h:**
i:****
l:**
n:**
o:***
r:*
s:***
t:*******
u:*
Related
I have a problem with this exercise.
In this exercise I enter a word and a number. I have to use the ASCII table to encrypt the word.
If I enter the letter "a" and the number 3, the letter becomes "d".
If I enter the letter "z" and the number 2, the letter should become "b", but a symbol comes out.
Another problem is if I use an uppercase letter. If I enter the uppercase letter "Z" I'll still get a symbol.
Another problem is if I use the letters "aB" and the number -2 should come out "yZ", but symbols come out.
This is the exercise:
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
String s, n="";
int N;
System.out.println("Insert a word");
s=in.next();
System.out.println("Insert a number");
N=in.nextInt();
n=uno(s, N);
System.out.println("That's the encrypted word: " + n);
}
public static String uno (String s, int N) {
String f, n="";
int c;
int length = s.length();
for (int i=0; i<length; i++) {
c = s.charAt(i);
c=c+N;
f = Character.toString((char)c);
n=n+f;
}
return n;
}
ASCII for z is 122. You add 2 to that. The ASCII for 124 is | symbol.
You need to check if your addition is going out of range (i.e. above 122).
Note: this won't work is N is greater than 26. Check the solution just below that implements modulo to handle that.
public static String uno (String s, int N) {
String f, n = "";
int c;
int length = s.length();
for (int i = 0; i < length; i++) {
c = s.charAt(i);
c = c + N;
if (c >= 122) {
c -= 26;
}
f = Character.toString((char) c);
n = n + f;
}
return n;
}
Side note: Never concatenate a string in a loop using +. It is very inefficient. Using StringBuilder.
Handle case sensitive letters concisely:
public static String uno (String s, int N) {
StringBuilder n = new StringBuilder();
int bound = s.length();
IntStream.range(0, bound).forEach(i -> {
char c = s.charAt(i);
n.append(Character.isUpperCase(c) ?
(char) ((c + N - 'A') % 26 + 'A') :
(char) ((c + N - 'a') % 26 + 'a'));
});
return n.toString();
}
Handling negative numbers:
public static String uno (String s, int N) {
StringBuilder n = new StringBuilder();
int bound = s.length();
IntStream.range(0, bound).forEach(i -> {
char c = s.charAt(i);
if (N > 0) {
n.append(Character.isUpperCase(c) ?
(char) ((c + N - 'A') % 26 + 'A') :
(char) ((c + N - 'a') % 26 + 'a'));
} else {
n.append((char) (c + N % 26 + 26));
}
});
return n.toString();
}
Check this comment for a good point on your naming conventions.
I'm trying to count the number of occurrences of letters that are in string. The code that I have written technically does what I want, but not the way I want to do it. For example, if I input "Hello World", I want my code to return "a=0 b=0 c=0 d=0 e=1 etc...." with the code I have written it returns "H=1, e=1, l=2 etc...."
Also how would I make sure that it is not case sensitive and it doesn't count spaces.
Code:
import java.util.Scanner;
public class Sequence {
private static Scanner scan = null;
public static void main(String[] args) {
scan = new Scanner(System.in);
String str = null;
System.out.print("Type text: ");
str = scan.nextLine();
int[] count = new int[255];
int length = str.length();
for (int i = 0; i < length; i++)
{
count[str.charAt(i)]++;
}
char[] ch = new char[str.length()];
for (int i = 0; i < length; i++)
{
ch[i] = str.charAt(i);
int find = 0;
for (int j = 0; j <= i; j++)
{
if (str.charAt(i) == ch[j])
find++;
}
if (find == 1)
{
System.out.print(str.charAt(i) + "=" + count[str.charAt(i)] + " ");
}
}
}
}
As I hinted in my original comment you only need an array of 26 int(s) because there are only 26 letters in the alphabet. Before I share the code, it is important to note that Java char is an integral type (and, for example, 'a' + 1 == 'b'). That property is important, because it allows you to determine the correct offset in an array (especially if you force the input to lower case). Something like,
Scanner scan = new Scanner(System.in);
System.out.print("Type text: ");
String str = scan.nextLine();
int[] count = new int[26];
for (int i = 0; i < str.length(); i++) {
char ch = Character.toLowerCase(str.charAt(i)); // not case sensitive
if (ch >= 'a' && ch <= 'z') { // don't count "spaces" (or anything non-letter)
count[ch - 'a']++; // as 'a' + 1 == 'b', so 'b' - 'a' == 1
}
}
for (int i = 0; i < count.length; i++) {
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
}
System.out.println();
If you really want to see all of the letters that have counts of zero (seems pointless to me), change
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
to remove the if and just
System.out.printf("%c=%d ", 'a' + i, count[i]);
Change str = scan.nextLine(); to str = scan.nextLine().toLowerCase().replaceAll("\\s+","");
.toLowerCase() is a method which makes every char in the string lowercase.
.replaceAll() is a method which replaces one char with another. In this case, it replaces whitespaces with nothing.
I have this problem,
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100
at Exercise_12_2.main(Exercise_12_2.java:28)
When i am trying to just simply count the occurrences of the letters in a char array. I just cant seem to wrap my head around how to work it out. I have been at it for several hours. Please help get me on the right track.
input: a a a b b c !
Expected output:
Counts:
a 3
b 2
c 1
This is my code so far. Please help me.
import java.util.Scanner;
public class Exercise_12_2
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in); // Setup scanner
char[] charArray = new char[100];
int[] counts = new int[26];
char tempinput = '?';
System.out.print("Enter letters (or ! to quit): ");
while (tempinput != '!')
{
tempinput = (input.next()).charAt(0);
charArray[tempinput]++;
for (int c = 'a'; c <= 'z'; c++)
{
for (int k = 0; k <= charArray.length; k++)
{
if (c == charArray[k])
{
counts[c] += 1;
}
}
}
}
}
public static void displayCounts(int[] counts)
{
for (int i = 0; i < counts.length; i++)
{
if ((i + 1) % 10 == 0)
{
System.out.println(counts[i] + " " + (char)(i + 'a'));
}
else
{
System.out.print(counts[i] + " " + (char)(i + 'a') + " ");
}
}
}
}
java.lang.ArrayIndexOutOfBoundsException: 100 means you are asking for the 101st element of an array with only 100 elements. Remember, java arrays are indexed starting with 0.
From that you might be able to tell why this line is broken:
for (int k = 0; k <= charArray.length; k++)
charArray.length is 100, so you run up until k is 101, meaning that you try charArray[100] which is asking for the 101st element of charArray, but charArray only has 100 elements.
If you switch k <= charArray.length to k < charArray.length you should get farther.
On an unrelated note, counts[c] += 1; won't work. The int val of a char is its ascii value. The letter a for example is 97, so you'll go way off the end of your counts array. This also doesn't account for upper/lower case (which have different numeric values).
This problem becomes much easier if you use an appropriate data structure. For example, I would use a Map<Character, Integer> to keep the count and then iterate that to display. Like,
Scanner input = new Scanner(System.in); // Setup scanner
System.out.print("Enter letters (or ! to quit): ");
Map<Character, Integer> map = new HashMap<>();
char ch;
while ((ch = Character.toLowerCase(input.next().charAt(0))) != '!') {
map.put(ch, map.getOrDefault(ch, 0) + 1);
}
System.out.println("Counts:");
for (int c = 'a'; c <= 'z'; c++) {
if (map.containsKey((char) c)) {
System.out.printf("%c\t%d%n", c, map.get((char) c));
}
}
Which I tested with your example input, and I get as requested:
Enter letters (or ! to quit): a a a b b c !
Counts:
a 3
b 2
c 1
I think after creating the character array of [a, a, b c, d, !, ..], following code will be enough to calculate count for each alphabet [a-z].
for (int k = 0; k < charArray.length; k++)
{
char c = charArray[k];
if (c >= 'a' && c <= 'z' )
{
counts[c - 'a'] += 1;
}
}
Take as input S, a string. Write a function that replaces every odd character with the character having just higher ASCII code and every even character with the character having just lower ASCII code. Print the value returned.
package assignments;
import java.util.Scanner;
public class strings_odd_even_char {
static Scanner scn = new Scanner(System.in);
public static void main(String[] args) {
String str = scn.nextLine();
for (int i = 0; i < str.length(); i = i + 2) {
char ch = str.charAt(i);
ch = (char)((ch + 1));
System.out.println(ch);
}
for (int j = 1; j < str.length(); j = j + 2) {
char ch = str.charAt(j);
ch = (char)((ch - 1));
System.out.print(ch);
}
}
}
The problem with my code is that it is first printing the values for all the odd characters and then for even characters but what I want is that they get printed in proper sequence like for input --> abcg , the output should be --> badf .
I'd hold the "incremenet" value in a variable and alternate it between +1 and -1 as I go voer the characters:
private static String change(String s) {
StringBuilder sb = new StringBuilder(s.length());
int increment = 1;
for (int i = 0; i < s.length(); ++i) {
sb.append((char)(s.charAt(i) + increment));
increment *= -1;
}
return sb.toString();
}
Just use one loop that handles both characters:
for (int i = 0; i < str.length(); i = i + 2) {
char ch = str.charAt(i);
ch = (char) (ch + 1);
System.out.print(ch);
if (i + 1 < str.length()) {
ch = str.charAt(i + 1);
ch = (char) (ch - 1);
System.out.print(ch);
}
}
You only need to iterate one time but do different operation (char+1) or (char-1) depending on the i:
public static void main(String[] args) {
String str = scn.nextLine();
for(int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(i % 2 == 0) { // even
ch += 1;
} else { // odd
ch -= 1;
}
System.out.print(ch);
}
}
You are using two loops, but you only need one. You can use the % operator to tell if i is even or odd, and then either subtract or add accordingly:
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(i % 2 == 0) {
ch = (char)((ch + 1));
System.out.println(ch);
} else {
ch = (char)((ch - 1));
System.out.print(ch);
}
}
You can do it in one for loop, to do that you will need to check whether the current index is even or odd. if current index is even you will increment char and print, if it is odd you will decrement char and print. to check if even or odd using % operator
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(i%2 == 0) {
ch = ch + 1;
System.out.println(ch);
continue;
}
ch = ch - 1;
System.out.println(ch);
}
I'm trying to create a loop which only returns letters. In my code, I get symbols that I don't want. How do I fix my loop so that when my integer is +3, it only gives me letters?
public static String caesarDecrypt(String encoded, int shift){
String decrypted = "";
for (int i = 0; i < encoded.length(); i++) {
char t = encoded.charAt(i);
if ((t <= 'a') && (t >= 'z')) {
t -= shift;
}
if (t > 'z') {
t += 26;
} else if ((t >= 'A') && (t <= 'Z')) {
t -= shift;
if (t > 'Z')
t += 26;
} else {
}
decrypted = decrypted + t;
}
}
You are subtracting the shift value from the letters. Therefore, the new letter can never be > 'z'. You should check if the it is < 'a' (or 'A', respectively).
StringBuilder decrypted = new StringBuilder(encoded.length());
for (int i = 0; i < encoded.length(); i++)
{
char t = encoded.charAt(i);
if ((t >= 'a') && (t <= 'z'))
{
t -= shift;
while (t < 'a')
{
t += 26;
}
}
else if ((t >= 'A') && (t <= 'Z'))
{
t -= shift;
while (t < 'A')
{
t += 26;
}
}
decrypted.append(t);
}
return decrypted.toString();
Also, you shouldn't be using String concatenation to generate the result. Learn about StringBuilder instead.
EDIT: To make sure the new letter is in the range 'a' .. 'z' for an arbitrary (positive) shift, you should use while instead of if.
I am not giving you exact code. But I can help you in logic:
Check whether you are reaching end points (a, A, z, Z) due to the shift.
If you exceed the end points either way, then compute the distance between end points and shifted t. Add/subtract/modulus (based on the end point) this distance to the other endpoint to get the exact letter.
Something like this? (Warning, untested)
public static String caesarDecrypt(String encoded, int shift) {
String decrypted = "";
for (int i = 0; i < encoded.length(); i++) {
char t = encoded.charAt(i).ToUpper();
decrypted = decrypted + decode(t, shift);
}
}
// call with uppercase ASCII letters, and a positive shift
function decode(char n, int shift)
{
if ((n < 'A') || (n > 'Z')) return ('-');
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var s = str.charAt(((n - 'A') + shift)%26);
return(s);
}
As you are naming your method caesarDecrypt (I assume you mean encrypt), I think you want a shift in the alphabet including wrapping around.
This code will do that for you:
public class Snippet {
public static void main(String[] args) {
System.out.println(caesarShift("This is a Fizzy test.", 5));
System.out.println(caesarShift("Ymnx nx f Kneed yjxy.", -5));
}
public static String caesarShift(String input, int shift) {
// making sure that shift is positive so that modulo works correctly
while (shift < 0)
shift += 26;
int l = input.length();
StringBuffer output = new StringBuffer();
for (int i = 0; i < l; i++) {
char c = input.charAt(i);
char newLetter = c;
if (c >= 'a' && c <= 'z') { // lowercase
newLetter = (char) ((c - 'a' + shift) % 26 + 'a'); // shift, wrap it and convert it back to char
} else if (c >= 'A' && c <= 'Z') { // uppercase
newLetter = (char) ((c - 'A' + shift) % 26 + 'A'); // shift, wrap it and convert it back to char
}
output.append(newLetter);
}
return output.toString();
}
}
This will handle lowercase and uppercase letters. Everything else will be left as it is (like spaces, punctuations, etc).
Please take some time to look at this code to understand how it works. I have put some comments to make it clearer. From your code I think you were a bit confused, so it is important that you understand this code very well. If you have questions, feel free to ask them.
This code
String start = "abcdefghijklmnopqrstuvwxyz";
String encrypted = caesarShift(start, 3);
String decrypted = caesarShift(encrypted, -3);
System.out.println("Start : " + start);
System.out.println("Encrypted : " + encrypted);
System.out.println("Decrypted : " + decrypted);
will give this result
Start : abcdefghijklmnopqrstuvwxyz
Encrypted : defghijklmnopqrstuvwxyzabc
Decrypted : abcdefghijklmnopqrstuvwxyz