Am trying to create a method to encrypt a word with Caesar cipher
here is the code:
public static void main (String [] args)
{
String s = "ahmed";
int k = 2;
char[] c = new char[5];
int[] a = new int[s.length()];
for (int i = 0; i<s.length();i++){
a[i] = Secret_Code_Library.getDigit(s.charAt(i));
a[i] = i + k ;
c[i] = Secret_Code_Library.getLetter(a[i]);
}
String ss = String.valueOf(c);
}
Secret_Code_Library is a class that contains the two methods
(getDigit(char): returns the number of the character a =0, b= 1...etc, and
getLetter(int): returns the letter corresponding to the number).
my problem is when ever i try to encrypt a word it encrypts only
the first letter correctly and save it in to the array a.
P.S: I have to use those two methods.
the output of the above code is: cdefg
while it should be: cjogf
this is the class :
public class Secret_Code_Library {
public static final char [] LETTERS={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };
public static char getLetter(int digit){
return LETTERS[digit]; }
public static int getDigit(char ch){
int digit=0;
switch (ch){
case 'A': digit=0; break; case 'B': digit=1; break; case 'C': digit=2; break;
case 'D': digit=3; break; case 'E': digit=4; break; case 'F': digit=5; break;
case 'G': digit=6; break; case 'H': digit=7; break; case 'I': digit=8; break;
case 'J': digit=9; break; case 'K': digit=10; break; case 'L': digit=11; break;
case 'M': digit=12; break; case 'N': digit=13; break; case 'O': digit=14; break;
case 'P': digit=15; break; case 'Q': digit=16; break; case 'R': digit=17; break;
case 'S': digit=18; break; case 'T': digit=19; break; case 'U': digit=20; break;
case 'V': digit=21; break; case 'W': digit=22; break; case 'X': digit=23; break;
case 'Y': digit=24; break; case 'Z': digit=25; break;
}// switch
return digit;
}}
a[i]= i + k ;
should be
a[i] = a[i] + k;
because you're not adding the key to the position of the current encrypted character, but the integer value of the character itself.
But that is not enough. What happens when you're encrypting 'z' with k = 2? You should wrap around in the alphabet, if the Secret_Code_Library.getLetter(a[i]); doesn't already do this for you.
If your alphabet is 26 characters long, then this should do it:
a[i] = (a[i] + k) % 26;
Related
I am trying to create a scrabble-like program that calculates the points of letters contained in a word. These word are contained in a .txt file. I can get it to read from the file, but unsure how to get it to calculate the value of each word. I have attached what I have done so far, and am wondering if a switch case is the best way to go, and if so, how do I assign a value to a letter with a switch case. Any help is appreciated.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package pointsproblem;
/**
*
*/
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class PointsProblem {
/**
* #param args the command line arguments
* #throws java.io.FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
// TODO code application logic here
//create new object//
PointsProblem task1 = new PointsProblem();
File file = new File("dictionary.txt");
// read the file//
Scanner input = new Scanner(file);
//check if file can be found//
if (!file.isFile()) {
System.err.println("Cannot open file: " + input);
System.exit(0);
}
else {
System.out.println("Successfully opened file: " + input + ".");
}
//read all the lines in the file//
{
while (input.hasNext()) {
String word = input.nextLine();
System.out.println(word);
System.out.println("'" + input + "' is worth " + point + " points");
int point = "";
switch(point) {
case 'a': = "1":
case 'e': = "1";
case 'i': = "1";
case 'l': = "1";
case 'n': = "1";
case 'o': = "1";
case 'r': = "1";
case 's': = "1";
case 't': = "1";
case 'u': = "1";
case 'g': = "2";
case 'g': = "2";
case 'b': = "3";
case 'm': = "3";
case 'c': = "3";
case 'p': = "3";
case 'f': = "4";
case 'h': = "4";
case 'v': = "4";
case 'w': = "4";
case 'y': = "4";
case 'k': = "5";
case 'j': = "8";
case 'x': = "8";
case 'q': = "10";
case 'z': = "10";
return score = point + "";
}//end switch
}//end point calculation loop
public int getScore() {
return score;
}
//public boolean containsLetter(Character letter) {
//return points.contains(letter);//
}
I have tried assigning an int of X to the value as well. I would like it to read the word contained in the file and give a total score.
Looks like a Map<Character, Integer> would fit:
public class PointsProblem {
final Map<Character, Integer> pointsMap = Map.of(
'a', 1,
'e', 1,
//.......
'z', 10
);
Then, in your function, simply use the map to find the corresponding point for each character:
int wordPoints = 0;
for(char c : word.toCharArray())
wordPoints += pointsMap.get(c);
Use a map to store the values:
Map<Character, Integer> charValues = new HashMap();
charValues.put('a', 2);
charValues.put('b', 1);
You can use the chars() and collect as sum
int total = word.chars()
.mapToObj(c -> charValues.get((char)c))
.mapToInt(i -> (int)i)
.sum();
But according to your use case you can count the chars first and then multiply
Map<Character, Integer> counter = new HashMap<>();
while (input.hasNext()) {
String word = input.next();
word.chars().forEach(c -> counter.compute(c, (k, v) -> v == null ? 1 : v + 1));
}
counter.entrySet()
.stream()
.mapToInt(e -> charValues.get(e.getKey())*e.getValue())
.sum();
if you are using switch your code will look like:
int total = 0;
switch (c){
case 'a' : total += 1; break;
case 'b' : total += 2; break;
}
I'm not sure that the code you've shown us will compile. There are a few things you need to change;
1) You're setting a String to an int. You'll want to change that to
int point = 0
2) You aren't setting anything in the switch statement
Change case 'a': = "1": to case 'a': point = 1;
3) You will never set a unique value in the switch statement because you aren't using 'break'
Checkout this page for a good tutorial: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
Basically without any break statements, your code will go through the of the statements and point will just be assigned to your last case
You want to have something along the lines of
switch(char) {
case 'a': point = 1;
break;
case 'e': point = 1;
break;
// etc.
default: point = 1; // maybe throw an error or add some logging for the default case
break;
}
return point;
I am presuming that you actually have this switch statement in it's own method and not in main as you've shown us above, otherwise the return statement won't help you.
You can also shorten this so that each case simply returns a value (again, if this is in it's own method), i.e.
switch(char) {
case 'a': return 1;
case 'b': return 1;
// etc.
}
edit:
The best way to get the point value of the whole word via a switch statement is:
char[] chars = word.toCharArray();
int point=0;
for (char c: chars) {
switch(c) {
case 'a':
point += 1;
break;
// etc.
}
}
System.out.println("Total point value of word '" + word + "' was " + point);
Instead of assigning individually for each 'case' statement, you can also use the fall through feature of the switch block.
int calcScore(String str)
{
int score = 0;
for(int i=0; i<str.length(); i++)
{
switch(str.charAt(i)) {
case 'a':
case 'e':
case 'i':
case 'l':
case 'n':
case 'o':
case 'r':
case 's':
case 't':
case 'u': score += 1; break;
case 'g': score += 2; break;
case 'b':
case 'm':
case 'c':
case 'p': score += 3; break;
case 'f':
case 'h':
case 'v':
case 'w':
case 'y': score += 4; break;
case 'k': score += 5; break;
case 'j':
case 'x': score += 8; break;
case 'q':
case 'z': score += 10; break;
}
}
return score;
}
This function can be called for each word.
Thanks everyone, I ended up with the following code which gives the output I am after;
System.out.println("Points problem");
File file = new File("dictionary.txt");
// read the file//
Scanner input = new Scanner(file);
//check if file can be found//
if (!file.isFile()) {
System.err.println("Cannot open file: " + file);
System.exit(0);
} else {
System.out.println("Successfully opened file: " + file + ".");
}
//read all the lines in the file//
while (input.hasNext()) {
String word = input.nextLine();
//System.out.println(word);
int l = word.length();
int point = 0;
for (int x = 0; x < l; x++) {
char c = word.charAt(x);
switch (c) {
case 'a':
case 'e':
case 'i':
case 'l':
case 'n':
case 'o':
case 'r':
case 's':
case 't':
case 'u':
point += 1;
break;
case 'd':
case 'g':
point += 2;
break;
case 'b':
case 'c':
case 'm':
case 'p':
point += 3;
break;
case 'f':
case 'h':
case 'v':
case 'w':
case 'y':
point += 4;
break;
case 'k':
point += 5;
break;
case 'j':
case 'x':
point += 8;
break;
case 'q':
case 'z':
point += 10;
break;
}//end switch*/
}//end point calculation loop
System.out.println(word + "is worth " + point + " points." );
}
I am writing a program that simulates the translation of an alphabetic phone number into just numbers. For example: 888-get-food == 555-438-3663.
Initially, the user should enter the phone number on the following format: 888-GET-FOOD (With the dashes). When I try to check if there are dashes on the user input, it prints the dashes, but with the number 1 in front of it. Very annoying.
This is what I have so far:
// Ask the user to enter the phone number
System.out.println("Please enter the phone number: ");
// Save the phone number into a string
String initialPhoneNumber = input.nextLine();
// Convert user input to UPPERCASE
initialPhoneNumber = initialPhoneNumber.toUpperCase();
// This will be the phone number converted
String finalPhoneNumber = fullPhoneNumber(initialPhoneNumber);
// Print number
System.out.println(initialPhoneNumber);
System.out.println(finalPhoneNumber);
for (int i = 0; i < strLength; i++) {
char letter = initialPhoneNumber.charAt(i);
if (Character.isLetter(letter)) {
switch (letter) {
case 'A': case 'B': case 'C': number = 2; break;
case 'D': case 'E': case 'F': number = 3; break;
case 'G': case 'H': case 'I': number = 4; break;
case 'J': case 'K': case 'L': number = 5; break;
case 'M': case 'N': case 'O': number = 6; break;
case 'P': case 'Q': case 'R': case 'S': number = 7; break;
case 'T': case 'U': case 'V': number = 8; break;
case 'W': case 'X': case 'Y': case 'Z': number = 9; break;
case '-':number='-';
}
}
else if (Character.isDigit(letter)) {
number = Character.getNumericValue(letter);
}
else if (initialPhoneNumber.charAt(i) == '-') {
number = Character.getNumericValue(letter);
}
and this is the output:
Please enter the phone number:
555-GET-FOOD
555-GET-FOOD
555-1438-13663
Why does the number 1 show up in front of the dashes? How can I make it so it doesn't show up? In other words, how can I print or separate the numbers separated by dashes?
Thanks
The problem is within the statement:
else if (initialPhoneNumber.charAt(i) == '-') {
number = Character.getNumericValue(letter);
}
The method Character.getNumericValue() returrns -1 if the character passed as parameter is not numeric.
Since you're passing -, the method returns -1.
That's why you get the 1 after the dash.
UPDATE
Supposing that the for-loop is part of your method fullPhoneNumber, you could resolve it as follows:
public String fullPhoneNumber(String initialPhoneNumber)
{
StringBuilder result;
result = new StringBuilder();
for (int i = 0; i < initialPhoneNumber.length(); i++)
{
char letter = Character.toUpperCase(initialPhoneNumber.charAt(i));
switch (letter)
{
case 'A':
case 'B':
case 'C':
letter = '2';
break;
case 'D':
case 'E':
case 'F':
letter = '3';
break;
case 'G':
case 'H':
case 'I':
letter = '4';
break;
case 'J':
case 'K':
case 'L':
letter = '5';
break;
case 'M':
case 'N':
case 'O':
letter = '6';
break;
case 'P':
case 'Q':
case 'R':
case 'S':
letter = '7';
break;
case 'T':
case 'U':
case 'V':
letter = '8';
break;
case 'W':
case 'X':
case 'Y':
case 'Z':
letter = '9';
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
break;
default:
throw new IllegalArgumentException("");
}
result.append(letter);
} // for
return (result.toString());
} // fullPhoneNumber
Modify the program to accept a telephone number with any number of letters. The output should display a hyphen after the first 3 digits and subsequently a hyphen (-) after every four digits. Also, modify the program to process as many telephone numbers as the user wants.
Below is what i have to edit.
Scanner keyboard = new Scanner(System.in);
String telephone_letter;
int index;
System.out.print("Enter Telephone letters : ");
telephone_letter = keyboard.nextLine();
char aChar[] = telephone_letter.toCharArray();
int[] number = new int[100];
for(index=0;index<telephone_letter.length();index++){
switch (aChar[index])
{
case 'A':
case 'a':
case 'B':
case 'b':
case 'C':
case 'c':
number[index] = 2;
break;
case 'D':
case 'd':
case 'E':
case 'e':
case 'F':
case 'f':
number[index] = 3;
break;
case 'G':
case 'g':
case 'H':
case 'h':
case 'I':
case 'i':
number[index] = 4;
break;
case 'J':
case 'j':
case 'K':
case 'k':
case 'L':
case 'l':
number[index] = 5;
break;
case 'M':
case 'm':
case 'N':
case 'n':
case 'O':
case 'o':
number[index] = 6;
break;
case 'P':
case 'p':
case 'Q':
case 'q':
case 'R':
case 'r':
case 'S':
case 's':
number[index] = 7;
break;
case 'T':
case 't':
case 'U':
case 'u':
case 'V':
case 'v':
number[index] = 8;
break;
case 'W':
case 'w':
case 'X':
case 'x':
case 'Y':
case 'y':
case 'Z':
case 'z':
number[index] = 9;
break;
default:
break;
}
}
System.out.println("=======================================");
System.out.println("The Telephone letter is : " + telephone_letter);
System.out.println("The Phone number is : " + number[0]+number[1]+number[2]+"-"+number[3]+number[4]+number[5]+number[6]);
System.out.println("=======================================");
}
This part is what i tried.
Scanner keyboard = new Scanner(System.in);
String telephone_letter;
int index;
System.out.print("Enter Telephone letters : ");
telephone_letter = keyboard.nextLine();
char aChar[] = telephone_letter.toCharArray();
int[] number = new int[100];
while(telephone_letter !="2")
{
for(index=0;index<telephone_letter.length();index++){
switch (aChar[index])
{
case 'A':
case 'a':
case 'B':
case 'b':
case 'C':
case 'c':
number[index] = 2;
break;
case 'D':
case 'd':
case 'E':
case 'e':
case 'F':
case 'f':
number[index] = 3;
break;
case 'G':
case 'g':
case 'H':
case 'h':
case 'I':
case 'i':
number[index] = 4;
break;
case 'J':
case 'j':
case 'K':
case 'k':
case 'L':
case 'l':
number[index] = 5;
break;
case 'M':
case 'm':
case 'N':
case 'n':
case 'O':
case 'o':
number[index] = 6;
break;
case 'P':
case 'p':
case 'Q':
case 'q':
case 'R':
case 'r':
case 'S':
case 's':
number[index] = 7;
break;
case 'T':
case 't':
case 'U':
case 'u':
case 'V':
case 'v':
number[index] = 8;
break;
case 'W':
case 'w':
case 'X':
case 'x':
case 'Y':
case 'y':
case 'Z':
case 'z':
number[index] = 9;
break;
default:
break;
}
}
System.out.println("=======================================");
System.out.println("The Telephone letter is : " + telephone_letter);
System.out.println("The Phone number is : " + number[0]+number[1]+number[2]+"-"+number[3]+number[4]+number[5]+number[6]);
System.out.println("=======================================");
System.out.print("Enter Telephone letters : ");
telephone_letter = keyboard.nextLine();
}
My output is wrong.
Enter Telephone letters : fewfwef
======================================
The Telephone letter is : fewfwef
The Phone number is : 339-3933
=======================================
Enter Telephone letters : wsqsq
=======================================
The Telephone letter is : wsqsq
The Phone number is : 339-3933
=======================================
And another Question is how do i do this The output should display a hyphen after the first 3 digits and subsequently a hyphen (-) after every four digits.
This seems like a homework problem so here are some hints to help you solve it yourself.
(1) Using a fixed number like 100 is rarely a good idea:
int[] number = new int[aChar.length];
(2) The scanner can tell you if there is more to be scanned(read):
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter Telephone letters : ");
while (keyboard.hasNextLine()) {
String telephone_letter = keyboard.nextLine();
...
System.out.println("");
System.out.print("Enter Telephone letters : ");
}
(3) A loop is good for counting. If the first count is different, then start different:
int todash = 3;
System.out.print("The Phone number is : ");
for (int i=0; i < number.length; ++i) {
if (todash == 0) {
System.out.print("-");
todash = 4;
}
System.out.print(number[i]);
--todash;
}
System.out.println("");
I've rewritten you're code. It may be easier to work with.
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Telephone {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter Telephone letters : ");
String input = keyboard.nextLine();
TelephoneProcessor telephoneProcessor = new TelephoneProcessor(input);
String result = telephoneProcessor.proccess();
System.out.println("=======================================");
System.out.println("The Telephone letter is : " + input);
System.out.println("The Phone number is : " + result);
System.out.println("=======================================");
}
}
class TelephoneProcessor {
Map<String, String> matches = new HashMap<>();
String toProcess;
public TelephoneProcessor(String toProcess) {
this.toProcess = toProcess;
matches.put("[a-c]", "2");
matches.put("[d-f]", "3");
matches.put("[g-i]", "4");
matches.put("[j-l]", "5");
matches.put("[m-o]", "6");
matches.put("[p-r]", "7");
matches.put("[s-w]", "8");
matches.put("[x-z]", "9");
}
public String proccess() {
if(toProcess != "2") {
matches.forEach((regex, replacement) -> {
toProcess = toProcess.replaceAll(regex, replacement);
});
}
return toProcess.substring(0,3) + "-" + toProcess.substring(3,7);
}
}
It only asks once but that's easy to solve by making a class that contains the main method in a method and loops it.
I hope this helps for further extensions of the program :)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
Question
Write a method that returns a number, given an uppercase letter, as follows.
int getNumber (char uppercaseLetter)
Write a test program that prompts the user to enter a phone number as a string. The input number may contain letters. The program translates a letter (uppercase or lowercase) to a digit and leaves all other characters intact.
Sample run from textbook
Enter a string: 1-800-Flowers
1-800-3569377
Enter a string: 1800flowers
18003569377
Here is what I have so far
import java.util.Scanner;
public class Assignment {
public static int correspondingNumber(char uppercaseLetter){
int correspondingNumber=0;
switch (uppercaseLetter)
{
case 'A':
case 'B':
case 'C': correspondingNumber=2; break;
case 'D':
case 'E':
case 'F': correspondingNumber=3; break;
case 'G':
case 'H':
case 'I': correspondingNumber=4; break;
case 'J':
case 'K':
case 'L': correspondingNumber=5; break;
case 'M':
case 'N':
case 'O': correspondingNumber=6; break;
case 'P':
case 'Q':
case 'R':
case 'S': correspondingNumber=7; break;
case 'T':
case 'U':
case 'V': correspondingNumber=8; break;
case 'W':
case 'X':
case 'Y':
case 'Z': correspondingNumber=9; break;
}
return correspondingNumber;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String num;
char num1 = 0;
System.out.print("Enter a string: ");
num = input.next();
num.toUpperCase();
int i=0;
while(i!=num.length()){
num1=num.charAt(i);
}
System.out.print(correspondingNumber(num1));
}
}
steps need tobe done
scan input let's say as String
Convert string to character array (srcArray)
change method return of correspondingNumber to Char
default return to input and apply switch case
call method correspondingNumber, store return char in stringbuilder or Array of Char array
repeat step-5 until character array(srcArray) is completely processed
print the output
import java.util.Scanner;
public class Assignment {
// changed return type
public static char correspondingNumber(char uppercaseLetter) {
char correspondingNumber = uppercaseLetter;// default the return value
// to input
switch (uppercaseLetter) {
case 'A':
case 'B':
case 'C':
correspondingNumber = '2';
break;
case 'D':
case 'E':
case 'F':
correspondingNumber = '3';
break;
case 'G':
case 'H':
case 'I':
correspondingNumber = '4';
break;
case 'J':
case 'K':
case 'L':
correspondingNumber = '5';
break;
case 'M':
case 'N':
case 'O':
correspondingNumber = '6';
break;
case 'P':
case 'Q':
case 'R':
case 'S':
correspondingNumber = '7';
break;
case 'T':
case 'U':
case 'V':
correspondingNumber = '8';
break;
case 'W':
case 'X':
case 'Y':
case 'Z':
correspondingNumber = '9';
break;
}
return correspondingNumber;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String num;
char num1 = 0;
System.out.print("Enter a string: ");
num = input.next();
num.toUpperCase();
int i = 0;
while (i != num.length()) {
num1 = num.charAt(i);
System.out.print(correspondingNumber(num1)); // moved print
// statement to
// appropriate place
i++; // iterate loop
}
input.close();
}
}
I just saw some of my work today, and i want to enter the user how many alphabet they want and continue converting. Can i have help? It would be fantastic. I tried anything. I'm just new in java programming that's why. Thanks :)
This is my whole programming
import java.util.Scanner;
public class Try2 {
public static void main(String[] args) {
int counter = 0;
int it = 0;
Scanner keyboard = new Scanner(System. in );
System.out.println("Enter words to digits: ");
String alpha = keyboard.nextLine();
alpha = alpha.toLowerCase();
String num = (" ");
while (counter < alpha.length()) {
switch (alpha.charAt(it)) {
case 'A':
case 'a':
case 'B':
case 'b':
case 'c':
case 'C':
num += "2";
counter++;
break;
case 'D':
case 'E':
case 'F':
case 'd':
case 'e':
case 'f':
num += "3";
counter++;
break;
case 'G':
case 'H':
case 'I':
case 'g':
case 'h':
case 'i':
num += "4";
counter++;
break;
case 'J':
case 'K':
case 'L':
case 'j':
case 'k':
case 'l':
num += "5";
counter++;
break;
case 'M':
case 'N':
case 'O':
case 'm':
case 'n':
case 'o':
num += "6";
counter++;
break;
case 'P':
case 'R':
case 'S':
case 'p':
case 'r':
case 's':
num += "7";
counter++;
break;
case 'T':
case 'U':
case 'V':
case 't':
case 'u':
case 'v':
num += "8";
counter++;
break;
case 'W':
case 'w':
case 'X':
case 'x':
case 'Y':
case 'y':
case 'Z':
case 'z':
case ' ':
num += "9";
counter++;
break;
}
if ((counter % 4) == 3) {
num += "-";
}
it++;
}
System.out.println(num);
}
}
You can wrap the read line code with another while loop:
Scanner keyboard = new Scanner(System.in);
while(true) {
System.out.println("Enter words to digits: ");
String alpha = keyboard.nextLine();
alpha = alpha.toLowerCase();
String num = " ";
int counter = 0;
int it = 0;
while (counter < alpha.length()) {
...
}
//new line (optional)
num += "\n";
}
You can check if the user entered a flag to end input:
//You can choose any flag you want
if(alpha.equals("finish")) {
break;
}
About your switch:
You can remove all the upper case letters because you wrote: alpha = alpha.toLowerCase();
You forgot 'q'
If alpha don't match: [a-zA-z ] (contains only letters and spaces) an IndexOutOfBoundsException will be thrown from alpha.charAt(it) because you don't increase counter and the loop don't exit in time.
To prevent the last problem you can remove counter and it and change the while loop to for loop:
for (int i = 0; i < alpha.length(); i++) {
if ((i % 4) == 3) {
num += "-";
}
switch (alpha.charAt(i)) {
...
}
}