This is part of my Pig Latin. It is a method, I need to return the first vowel of the word. If there are no vowels I want to return the word length. But I have an error when I return the length of the word. The error is in "else" when returning isVowel.
private static int indexOfVowel(String word) {
int index = 0;
for (int i = 0; i < word.length(); i++)
if (isVowel(word.toLowerCase().charAt(i))) {
return index;
} else {
return isVowel(word.length());
}
}
private static boolean isVowel(char ch) {
switch (ch) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'y':
return true;
default: return false;
}
}
}
You cannot pass an integer to a method that expects a character. I think what you wanted is if you didn't find a vowel anywhere in the word, you want to return the length of the word.
Therefore you need to return word.length() after the for loop is done i.e. you looked at all characters in the word and didn't find a vowel. The method needs to be written as :
private static int indexOfVowel(String word) {
int index = 0;
for (int i = 0; i < word.length(); i++)
if (isVowel(word.toLowerCase().charAt(i)))
return index;
return word.length();
}
Related
I'm a beginner programmer who is currently learning Java and I ran into a problem.
So recently I've been working on methods for converting Strings to or from their hexadecimal values, for instance "Hello" to 48656C6C6F, and vice versa. My method for converting the input String to its hexadecimal value works well, and I've tested it several times, but after having finished it I moved on to its reverse method, using which I could convert hexadecimal values to Strings, but after several errors, tests and re-tries, I'm still stuck with the same problem.
Whenever I input a full hexadecimal code into the console, it does nothing, but when I only input the hexadecimal value of a single character (for example 7A for z), it works well, except for symbols such as ', ., ;, etc. Also, since all of the characters in my switch statement in the hexDeValue() method have hexadecimal values with minimum 2 digits, I tried to take substrings of the input String with two characters to be converted into regular characters. As I mentioned, the purpose of the method is to convert hexadecimal values into Strings, so could anyone make a suggestion of what I should fix?
Kind regards,
Here is my code:
public class HexDecode {
public static void main(String[] args) throws InterruptedException {
while(true) {
System.out.println("Enter a hexadecimal value");
String input = TextIO.getlnString();
System.out.println(hexDe(input));
}
}
public static String hexDe(String textout) {
String output = "";
String invertedcomma = "'";
while (true) {
for(int i = 0; i < textout.length(); i++) {
int j = i+1;
String hext = textout.substring(i, j);
char smolhext = textout.charAt(i);
if (smolhext == ' ' ) {
output = output + ' ';
}
if(i%2 == 0) {
if (hext == "27") {
output = output + invertedcomma;
}
else {
output = output + hexDeValue(textout);
}
if (hexDeValue(hext) == ' ') {
output = output + " ";
}
if (j > textout.length()) {
return output;
}
}
}
return output;
}
}
public static char hexDeValue(String parameter) {
switch(parameter) {
case "21":
return '!';
case "22":
return '"';
case "23":
return '#';
case "24":
return '$';
case "25":
return '%';
case "26":
return '&';
case "28":
return '(';
case "29":
return ')';
case "2A":
return '*';
case "2B":
return '+';
case "2C":
return ',';
case "2D":
return '-';
case "2E":
return '.';
case "2F":
return '/';
case "30":
return '0';
case "31":
return '1';
case "32":
return '2';
case "33":
return '3';
case "34":
return '4';
case "35":
return '5';
case "36":
return '6';
case "37":
return '7';
case "38":
return '8';
case "39":
return '9';
case "3A":
return ':';
case "3B":
return ';';
case "3C":
return '<';
case "3D":
return '=';
case "3E":
return '>';
case "3F":
return '?';
case "40":
return '#';
case "41":
return 'A';
case "42":
return 'B';
case "43":
return 'C';
case "44":
return 'D';
case "45":
return 'E';
case "46":
return 'F';
case "47":
return 'G';
case "48":
return 'H';
case "49":
return 'I';
case "4A":
return 'J';
case "4B":
return 'K';
case "4C":
return 'L';
case "4D":
return 'M';
case "4E":
return 'N';
case "4F":
return 'O';
case "50":
return 'P';
case "51":
return 'Q';
case "52":
return 'R';
case "53":
return 'S';
case "54":
return 'T';
case "55":
return 'U';
case "56":
return 'V';
case "57":
return 'W';
case "58":
return 'X';
case "59":
return 'Y';
case "5A":
return 'Z';
case "5B":
return '[';
case "5D":
return ']';
case "5E":
return '^';
case "5F":
return '_';
case "60":
return '`';
case "61":
return 'a';
case "62":
return 'b';
case "63":
return 'c';
case "64":
return 'd';
case "65":
return 'e';
case "66":
return 'f';
case "67":
return 'g';
case "68":
return 'h';
case "69":
return 'i';
case "6A":
return 'j';
case "6B":
return 'k';
case "6C":
return 'l';
case "6D":
return 'm';
case "6E":
return 'n';
case "6F":
return 'o';
case "70":
return 'p';
case "71":
return 'q';
case "72":
return 'r';
case "73":
return 's';
case "74":
return 't';
case "75":
return 'u';
case "76":
return 'v';
case "77":
return 'w';
case "78":
return 'x';
case "79":
return 'y';
case "7A":
return 'z';
case "7B":
return '{';
case "7C":
return '|';
case "7D":
return '}';
case "7E":
return '~';
default:
return ' ';
}
}
}
enter code here
Your hexDe() contains the line output = output + hexDeValue(textout); - but hexDeValue(textout) only works if textout contains the hex value for a single character (for example "41").
If textout contains for example "4142" then only the default case in hexDeValue() matches and hexDeValue(textout) returns ' '.
There are more problems:
if (hext == "27") {
output = output + invertedcomma;
}
The expression hext == "27" will only be true if hext is assigned the string constant "27", but not (as in your case) if hext is extracted from some longer string. See How do I compare strings in Java? for more information.
int j = i+1;
String hext = textout.substring(i, j);
This extracts a substring of length 1 from textout. But the following code only works if hext has a length of 2.
A minor problem with your code is that you repeatedly concatenate strings in a loop. This is very inefficient (although it probably doesn't matter for such a small scale problem), it would be better to use a StringBuilder:
StringBuilder output = new StringBuilder();
// instead of output = output + something; use
output.append(something);
// at the end of your method, instead of return output; use
return output.toString();
How to fix the code
Instead of
output = output + hexDeValue(textout);
you probably meant
output = output + hexDeValue(hext);
For this to properly decode character it is required that hext has a length of 2. That means that a few lines before that you need to write
int j = i+2;
String hext = textout.substring(i, j);
but this will lead to an IndexOutOfBoundsException if i is equal to textout.length()-1.
I don't know how important it is for your code to handle space characters in the input. If the input only consists of pairs of hexadecimal characters then you could rewrite your loop as:
public static String hexDe(String textout) {
StringBuilder output = new StringBuilder();
for (int i = 0; i < textout.length(); i += 2) {
String hext = textout.substring(i, i+2);
if (hext.equals("27")) {
output.append(invertedcomma);
}
else {
output.append(hexDeValue(hext));
}
}
return output.toString();
}
and if you add the lines
case "27":
return '\'';
to the switch statement in hexDeValue() you don't even need the special case for "27" in the hexDe() method.
How do I make the method indexOfVowel to return 1 for strings such as translate? I need it to find all the consonant that is before a vowel to be moved to the end. If I changed "notVowel" to 2 the word "translate" should be "anslatetray" but it returns ranslatetay. It only checks the first letter but not the rest of the word.
private String translateWord(String word) {
String translated = "";
int vowel = 0;
int notVowel = 1;
if (vowel == indexOfVowel(word)) {
return (word + "way ");
}
if (notVowel == indexOfVowel(word)) {
return (word.substring(1) + word.substring(vowel, 1) + "ay ");
}
return translated;
}
private static int indexOfVowel(String word) {
int index = 0;
for (int i = 0; i < word.length(); i++) {
if (isVowel(word.charAt(i))) {
return i;
}
}
return word.length();
}
private static boolean isVowel(char ch) {
switch (ch) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return true;
default:
return false;
}
}
}
I don't think you want indexOfVowel to return 1 specifically under any case. You want it to do what it sounds like it will do...return the index of the first vowel in the word passed to it. If the first vowel happens to be at the beginning of the word, it will return 0, otherwise it will return a non-0 value indicating the location of the first vowel. You need that location to do the right thing elsewhere. So indexOfVowel is correct as you have it.
Your problem is your use of the substring method...understanding how to use it to pick out the right portions of the target word.
Here's a modified version of your code that does the right thing, with comments to explain the two uses of substring:
public class Test {
private static String translateWord(String word) {
int i = indexOfVowel(word);
if (i == 0) { // if word starts with vowel
return (word + "way ");
}
else { // word doesn't start with a vowel
// 'i' is the position of the first vowel
// word.substring(i) = from position of first vowel to end of word
// word.substring(0, i) = from start of word to char before first vowel
return (word.substring(i) + word.substring(0, i) + "ay ");
}
}
private static int indexOfVowel(String word) {
for (int i = 0; i < word.length(); i++) {
if (isVowel(word.charAt(i))) {
return i;
}
}
return word.length();
}
private static boolean isVowel(char ch) {
switch (ch) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return true;
default:
return false;
}
}
public static void main(String[] args) {
System.out.println(translateWord("action"));
System.out.println(translateWord("translate"));
System.out.println(translateWord("parachute"));
System.out.println(translateWord("scrap"));
}
}
Result:
actionway
anslatetray
arachutepay
apscray
I have two classes that do two different things. I am trying to get my FileAccess class to use my encryption class to to encode a set number of phrases in a text file. The first 10 numbers in the file give the program the key value and that should be stored as a int and what comes after the file should be stored as a array of char and those need to be called by the encryption class to code the phrase. I do not know why I can't call my encryption class and I am stumped.
Sorry for being unclear I am trying to design an code that will accept a number of phrases as input and allow the user to encrypt it through the use of an encryption key. This key should be made up of an integer number between-2000000 and +2000000.The encryption algorithm uses the key to shift the letters of the alphabet to the right or left.For example A encoded with a key of 3 would produce D three letters to its right in the alphabet. If the key is so large that the new letter goes past the end of the alphabet, the program should wrap around to a letter near the beginning of the alphabet.
The FileAccess class – This class should read several phrases from a file. The first line of the file should contain an integer indicating the number of phrases in the file. The first 10 characters of each phrase in the file should contain the encryption key to be used in the encryption and decryption process for that phrase. This class should provide a way to access this information by other classes. Finally, this class should have a second method to allow phrases to be saved into a new file. I tried to be as clear as i can now. My problem is I cant call my encode method in my encryption class
Here is the code for the File Access.
public class FileAccess {
public static String[] load(String fileName) throws IOException {
FileReader file = new FileReader(fileName); //open file for reading
BufferedReader input = new BufferedReader(file);
int sizeF = Integer.parseInt(input.readLine()); // variable for the size of the array
String infoInFile[] = new String[sizeF]; // declare and create a string array
for (int i = 0; i < sizeF; i++) { // loop to read the file into the array
infoInFile[i] = input.readLine();
}
input.close();//close the file
return infoInFile;
}
public static int[] key(String finalKey[]) {
int finaloutput[] = new int[5];
String temp;
for (int i = 0; i < finalKey.length; i++) {
temp = finalKey[i].substring(0, 11);
finaloutput[i] = Integer.parseInt(temp);
System.out.println(finaloutput[i]);
}
return finaloutput;
}
public static char[] phrase(String EndOfPhrase[]) {
char letter[] = new char[5];
for (int j = 0; j < EndOfPhrase.length; j++) {
String phrase;
phrase = EndOfPhrase[j].substring(11);
char temp = phrase.charAt(1);
letter = phrase.toCharArray();
System.out.println(letter);
}
return letter;
}
public static void main(String[] args) throws IOException {
String output[]; // call the loader
int[] keyTest;
char[] phraseTest;
String display;
output = FileAccess.load("phrase.txt");
keyTest = key(output);
phraseTest = phrase(output);
for (int i = 0; i < output.length; i++) {
}
}
}
I am not sure if I should have that for loop, but scice the encryption encode method only takes in 1 char at a time and codes I think I need a for loop to keep calling it
HERE IS THE CODE FOR THE encryption code
public class Encryption {
public static boolean isNotALetter(char character) { // returns false if the character is a letter
boolean yorn = false;
return yorn;
}
public static char encode(char letter, int key) { // returns an encrypted character
char encryptedcharacter = 0;
int truevalueofkey = 0;
int valueofletter;
int newvalueofletter;
valueofletter = Encryption.lettertovalue(letter);
truevalueofkey = key % 26;
newvalueofletter = (valueofletter + truevalueofkey)%26;
encryptedcharacter = Encryption.valueToLetter(newvalueofletter);
// add truevalueofkey to key to get
return encryptedcharacter;
}
public static char decode(char letter, int key) { // returns a decrypted character
char decodedcharacter = 0;
int dtruevalueofkey = 0;
int dvalueofletter;
int dnewvalueofletter;
dvalueofletter = Encryption.lettertovalue(letter);
dtruevalueofkey = key % 26;
dnewvalueofletter = (dvalueofletter - dtruevalueofkey)%26;
decodedcharacter = Encryption.valueToLetter(dnewvalueofletter);
return decodedcharacter;
}
public static int lettertovalue(char letter) { // get value of each letter ex A = 1
int value = 0;
// convert to string based on char
switch (letter) {
case 'a': {
value = 1;
break;
}
case 'b': {
value = 2;
break;
}
case 'c': {
value = 3;
break;
}
case 'd': {
value = 4;
break;
}
case 'e': {
value = 5;
break;
}
case 'f': {
value = 6;
break;
}
case 'g': {
value = 7;
break;
}
case 'h': {
value = 8;
break;
}
case 'i': {
value = 9;
break;
}
case 'j': {
value = 10;
break;
}
case 'k': {
value = 11;
break;
}
case 'l': {
value = 12;
break;
}
case 'm': {
value = 13;
break;
}
case 'n': {
value = 14;
break;
}
case 'o': {
value = 15;
break;
}
case 'p': {
value = 16;
break;
}
case 'q': {
value = 17;
break;
}
case 'r': {
value = 18;
break;
}
case 's': {
value = 19;
break;
}
case 't': {
value = 20;
break;
}
case 'u': {
value = 21;
break;
}
case 'v': {
value = 22;
break;
}
case 'w': {
value = 23;
break;
}
case 'x': {
value = 24;
break;
}
case 'y': {
value = 25;
break;
}
case 'z': {
value = 26;
break;
}
}
return value;
}
public static char valueToLetter(int value) {
char letter = 0;
if (value == 1) {
letter = 'a';
}
if (value == 2) {
letter = 'b';
}
if (value == 3) {
letter = 'c';
}
if (value == 4) {
letter = 'd';
}
if (value == 5) {
letter = 'e';
}
if (value == 6) {
letter = 'f';
}
if (value == 7) {
letter = 'g';
}
if (value == 8) {
letter = 'h';
}
if (value == 9) {
letter = 'i';
}
if (value == 10) {
letter = 'j';
}
if (value == 11) {
letter = 'k';
}
if (value == 12) {
letter = 'l';
}
if (value == 13) {
letter = 'm';
}
if (value == 14) {
letter = 'n';
}
if (value == 15) {
letter = 'o';
}
if (value == 16) {
letter = 'p';
}
if (value == 17) {
letter = 'q';
}
if (value == 18) {
letter = 'r';
}
if (value == 19) {
letter = 's';
}
if (value == 20) {
letter = 't';
}
if (value == 21) {
letter = 'u';
}
if (value == 22) {
letter = 'v';
}
if (value == 23) {
letter = 'w';
}
if (value == 24) {
letter = 'x';
}
if (value == 25) {
letter = 'w';
}
if (value == 26) {
letter = 'z';
}
return letter;
}
public static void main(String[] args) {
String yrn = "y";
while (yrn == "y") {
String alsdjkf = JOptionPane.showInputDialog(null, "Enter the letter");
char enchar = alsdjkf.charAt(0);
int keyr = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter the key"));
char newchar = Encryption.decode(enchar, keyr);
JOptionPane.showMessageDialog(null, newchar);
yrn = JOptionPane.showInputDialog(null, "yes or no");
}
}
}
This is what is in the text file:
2
00000000003 The cook worked 12 hours in the darkened kitchen!
00000000025 Did Fred look well? That’s it!
Unfortunately it's quite hard to tell from your question what you are trying to do. I think you want each line to be interpreted as 10 digits and then a phrase to be encoded by the key represented by the digits. Assuming that's correct, I have several suggestions for changes to your code. I recommend you try these and then come back if they don't solve your problem.
FileAccess.load is unnecessary. You can use Files.lines to get all lines in a file in a single statement (use Stream.toArray if you really need it to be in an array).
The massive switch statements to just turn char to int are not needed. You can do math on char values such as letter - 'a' to simplify these.
Use a regular expression rather than decoding each line yourself. "(\\d{10}) (.*)" will read the key and phrase in a single statement.
Once you have the key and phrase you can call your "encryption" code for each line.
And just a warning: if you come back and say "I'm not allowed to use X or Y in my answer" then my comment will be "that would have been useful to know before I put time into trying to help you"!
So, we were given to code this ScantronGrader for homework, and the specs say that we have to create this class isValid to check to validity of the options that fall into either A, B, C, or D (all uppercase), I first tried switch (error), if-else-if (error); do-while (Oh, I know so wrong and error). I tried for loop first, and the value didn't get incremented.
In its recent rendition, this is my issue. TBH, I don't even know what I am doing anymore.
public static boolean isValid(String inputstr)
{
int x = 0;
do
{
switch (inputstr.charAt(x))
{
case 'A':
case 'B':
case 'C':
case 'D':
return true;
default: return false;
x++;
}
} while (x < inputstr.length());
}
}
The problem with this is that it is not letting me increment the counter. Now, I need to do that, else, how would I shift right? Either way, please HALP.
Not sure if i understood what that method have to do, but if it has to return true only if the string have those letter you can do this:
public static boolean isValid(String inputstr)
{
int x = 0;
boolean bool = true;
do
{
if(!(inputstr.charAt(x) == 'A' || inputstr.charAt(x) == 'B' || inputstr.charAt(x) == 'C' || inputstr.charAt(x) == 'D'))
{
bool = false;
}
x++;
}while (x < inputstr.length());
return bool;
}
Okay, so after some ideas from here (Thank you for reaching out to help), I am toying with this one which seems to work. Just let me know if I am doing anything unnecessary/ useless, or there is a more efficient way to do this, please?
public static boolean isValid(String inputstr) {
int count = 0;
for (int x = 0; x < inputstr.length(); x++) {
switch (inputstr.charAt(x)) {
case 'A':
case 'B':
case 'C':
case 'D':
break;
default: count++;
}
}
if (count == 0) {
return true;
}
else {
return false;
}
}
I am trying to check if a string is a palindrome, but it seems it does not work, because when I send a string that I know is not a palindrome, it returns that it is a palindrome, can anyone help? It also won't add to the variable counter.
package UnaryStack.RubCol1183;
public class CheckPalindrome {
static int counter = 0;
/** Decides whether the parentheses, brackets, and braces
in a string occur in left/right pairs.
#param expression a string to be checked
#return true if the delimiters are paired correctly */
public static boolean checkBalance(String expression)
{
StackInterface<Character> temporaryStack = new LinkedStack<Character>();
StackInterface<Character> reverseStack = new LinkedStack<Character>();
StackInterface<Character> originalStack = new LinkedStack<Character>();
int characterCount = expression.length();
boolean isBalanced = true;
int index = 0;
char nextCharacter = ' ';
for (;(index < characterCount); index++)
{
nextCharacter = expression.charAt(index);
switch (nextCharacter)
{
case '.': case '?': case '!': case '\'': case ' ': case ',':
break;
default:
{
{
reverseStack.push(nextCharacter);
temporaryStack.push(nextCharacter);
originalStack.push(temporaryStack.pop());
}
{
char letter1 = Character.toLowerCase(originalStack.pop());
char letter2 = Character.toLowerCase(reverseStack.pop());
isBalanced = isPaired(letter1, letter2);
if(isBalanced == false){
counter++;
}
}
break;
}
} // end switch
} // end for
return isBalanced;
} // end checkBalance
// Returns true if the given characters, open and close, form a pair
// of parentheses, brackets, or braces.
private static boolean isPaired(char open, char close)
{
return (open == close);
} // end isPaired
public static int counter(){
return counter;
}
}//end class
Your implementation seems way more complex than it needs to be.
//Check for invalid characters first if needed.
StackInterface<Character> stack = new LinkedStack<Character>();
for (char ch: expression.toCharArray()) {
Character curr = new Character(ch);
Character peek = (Character)(stack.peek());
if(!stack.isEmpty() && peek.equals(curr)) {
stack.pop();
} else {
stack.push(curr)
}
}
return stack.isEmpty();
Honestly using a stack is over kill here. I would use the following method.
int i = 0;
int j = expression.length() - 1;
while(j > i) {
if(expression.charAt(i++) != expression.charAt(j--)) return false;
}
return true;
You put exaclty the same elemets in reverseStack and originalStack, because everything you push into the temporaryStack will be immediately pushed into originalStack. This does not make sense.
reverseStack.push(nextCharacter);
temporaryStack.push(nextCharacter);
originalStack.push(temporaryStack.pop());
Therefore the expression
isBalanced = isPaired(letter1, letter2);
will always return true.
I found the errors in logic that were found inside the method checkBalace() and finished the code into a full working one. Here is what my finished code looks like:
public class CheckPalindrome {
static int counter;
/** Decides whether the parentheses, brackets, and braces
in a string occur in left/right pairs.
#param expression a string to be checked
#return true if the delimiters are paired correctly */
public static boolean checkBalance(String expression)
{
counter = 0;
StackInterface<Character> temporaryStack = new LinkedStack<Character>();
StackInterface<Character> reverseStack = new LinkedStack<Character>();
StackInterface<Character> originalStack = new LinkedStack<Character>();
boolean isBalanced = true;
int characterCount = expression.length();
int index = 0;
char nextCharacter = ' ';
for (;(index < characterCount); index++)
{
nextCharacter = expression.charAt(index);
switch (nextCharacter)
{
case '.': case '?': case '!': case '\'': case ' ': case ',':
break;
default:
{
{
reverseStack.push(nextCharacter);
temporaryStack.push(nextCharacter);
}
break;
}
} // end switch
} // end for
while(!temporaryStack.isEmpty()){
originalStack.push(temporaryStack.pop());
}
while(!originalStack.isEmpty()){
char letter1 = Character.toLowerCase(originalStack.pop());
char letter2 = Character.toLowerCase(reverseStack.pop());
isBalanced = isPaired(letter1, letter2);
if(isBalanced == false){
counter++;
}
}
return isBalanced;
} // end checkBalance
// Returns true if the given characters, open and close, form a pair
// of parentheses, brackets, or braces.
private static boolean isPaired(char open, char close)
{
return (open == close);
} // end isPaired
public static int counter(){
return counter;
}
}
I used 2 while methods outside of the for thus fixing the logic errors pointed out. I also assigned the value 0 to counter inside the method to fix a small problem I encountered. Feel free to revise the code if I still have errors, but I think I made no errors, then again, I'm a beginner.