Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This program's purpose is to translate Morse code into English. I've divided the program's execution logic into three cases: the translation of one Morse code character, two characters and three+ characters. This program tries to translate characters that fall under case three. If you can help, and decide to test the program, please input at least four morse code characters (between a and d)! Otherwise, expect some outofbounds exceptions!
What's wrong with the switch I used? I've read that, up until a few years ago, Java did not support switch statements that used Strings. Java now supports String switch statements and, if I'm not mistaken, my syntax agrees with the not-very-complex conventions of these statements. To determine whether the compiler first recognizes the switch's subject (i.e. switch (aReferenceThatPointsToaString), I printed the reference in the line preceding the switch. No problem there. I also looked at whether cases could be executed if the switch's subject were explicitly stated. Instead of saying switch (array3[i]), I wrote in switch ("._") This test did result in a working switch, leaving me with the impression that switch(array3[i]) isn't quite the same as switch(aStringexpression)
import java.util.Scanner;
public class MorseToEnglish1 {
public static void main (String[]args){
System.out.println("enter morse here");
Scanner input = new Scanner (System.in);
String container = input.nextLine();
char [] array = container.toCharArray();
int count = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == ' ')
count++ ;
}
// count counts the number of times a space appears
System.out.println(count);
int [] array2 = new int [count];
int counter = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == ' '){
array2[counter] = i;
counter ++ ;
}
}
// array2 assigns the indexes of spaces to its members
System.out.println(counter);
String [] array3 = new String [array2.length - 1];
for (int i = 0; i < array3.length ; i ++)
array3[i] = container.substring(array2[i], array2[i+1]);
// array3 creates substrings based on these spaces
System.out.print (array3[1]);
System.out.print(array3[0]);
// tests above
for (int i = 0; i < array3.length; i ++){
switch (array3[i]){
case ("._"):
{ System.out.println("a");
break; }
case "_...":
{ System.out.println("b");
break; }
case "_._.":
{ System.out.println("c");
break;}
case "_..":
{ System.out.println("d ");
break;}
}
}
input.close();
}
}
There's nothing wrong with your switch statement, there is a lot wrong with the rest of the program...
The problem is, your custom "split" process is leaving spaces within the text, so, if were to enter ._ _... _._. _.., the array would be split into...
" _...", " _._."
Which is wrong on two accounts, one, it's missing stuff I entered and two, it's leaving the leading space character in the String, so when you try and compare the Strings in the switch statement, you are actually trying to do something like...
"_...".equals(" _...")
Which will fail...
To start with, this "manual" splitting code...
char[] array = container.toCharArray();
int count = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == ' ') {
count++;
}
}
// count counts the number of times a space appears
System.out.println(count);
int[] array2 = new int[count];
int counter = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == ' ') {
array2[counter] = i;
counter++;
}
}
// array2 assigns the indexes of spaces to its members
System.out.println(counter);
String[] array3 = new String[array2.length - 1];
for (int i = 0; i < array3.length; i++) {
array3[i] = container.substring(array2[i], array2[i + 1]);
}
// array3 creates substrings based on these spaces
System.out.println(array3[1]);
System.out.println(array3[0]);
Should be replaced with...
String[] array3 = container.split(" ");
As I, frankly, have no idea what it's trying to achieve and it breaks if there is less than 4 "codes" on the input String and doesn't correctly parse the input anyway (throwing away values)
Your splitting code is leaving leading space characters which cause them to not correctly match. You should instead be using a version of String.split in order to produce your array3. This will create the correct substrings with a lot less work.
Edit:
Your splitting code also appears to leave off the first and last morse codes which is why you get ArrayIndexOutOfBoundsExceptions when you input less than 4.
From looking at the code you've got too many } curly braces. You only need one of those at the end of the switch statement.
case ("._"):
{System.out.println("a");
break;
case "_...":
{System.out.println("b");
break;
case "_._.":
{System.out.println("c");
break;
case "_..":
{System.out.println("d ");
break;
}
It should work. My assumption is of course that your problem is that your code doesn't compile. Which I'm pretty sure that the code you posted won't do.
Related
I created a simple program using the acm library that takes a user inputted string and prints it out in morse. This is the program:
import acm.program.*;
public class morse extends Program{
public void run(){
String[] alphabet = {"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"};
String[] morse = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
String word = readLine("Give the word(s) to transcribe: ").toUpperCase();
println("Morse: ");
int j = 0;
for(int i = 0; i < word.length(); i++){
int k = 0;
boolean flag = true;
if(Character.toString(word.charAt(j)).equals(" ")){
println();
}else {
while(!Character.toString(word.charAt(j)).equals(alphabet[k])){
if(k < 25){
k += 1;
}else{
println("Letter was not found.");
flag = false;
break;
}
}
if(flag){
println(morse[k] + " ");
}
j += 1;
}
}
}
}
However, every time the string contains a space, everything after the space is not printed. I seriously cant find the reason behind this. Can anyone help me or even point me somewhere ? Thanks
(The letters after the space are all printed as spaces)
I do not know why you define i in the for loop but never use it. Your main problem is that when you encounter an space you do not increment j. I think you have two options:
increment j after you call println(); inside the if
drop j completely and simply use i wherever j previously was used (probably the better idea)
General recommendation for your code: You are performing too much weird Character and String logic. You could do
drop the alphabet
get the char from the String the same way you currently do
subtract 'A' from it
use the resulting char as index to access the morse array
drop k and the entire while loop.
Given a non-empty string str like "Code" print a string like "CCoCodCode". Where at each index in the string you have to reprint the string up to that index.
I know there is DEFINITELY something wrong with this code that I wrote because the answer should be CCoCodCode, but instead it's giving me the alphabet! I don't know how I should change it.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String str = scan.next();
int x = str.length();
for(char i = str.charAt(0); i <= str.charAt(x-1); i++)
{
System.out.print(i);
}
}
The char datatype can be treated as a number; you can increment it and manipulate it as a number.
What you really want is successive substrings of str to be printed. Loop over an int that will represent the ending position of the substring to be printed.
for (int i = 0; i < str.length(); i++)
{
System.out.print(str.substring(0, i + 1));
}
The end index argument to substring is exclusive, which is why I added 1.
Let's say that str is "Code". We can perform some mental substitutions to see what happens to your loop.
str is "Code"
x is 4
str.charAt(0) is 'C'
str.charAt(x-1) is 'e'
Making these substitutions, your loop is:
for(char i = 'C'; i <= 'e'; i++)
{
System.out.print(i);
}
Does this help you see the problem? I would think you'd have a loop from 0 to 3, not from 'C' to 'e'...
Many ways to get it done, suppose we have the input from user stored in a string named "c"... then...
String c = "Code";
for (int i = 0; i < c.length(); i++) {
System.out.print(c.substring(0, i));
}
System.out.print(c);
And this will print the sequence you are looking for.
It is outputting the alphabet because you are printing the counter instead of the characters in the string!
As it is, the first iteration of the for loop will set i to the first character, print that, then the operation i++ will increment i by one. Wait, so if the first character is "C", so i = 'C', what is i++?
Well it turns out characters can be represented by numbers. For example, 'C' has a value of 67. So incrementing it makes it 68, which represents 'D'. So if you run the loop on "Code", it will increment your counter 4 times, giving "CDEF". If you run on "Codecodecode", that will make the loop run 12 times, giving "CDEFGHIJKLMN".
What you really want is to loop through the string by its index instead:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str = scan.next();
int length = str.length();
for (int i = 0; i < length; i++) {
System.out.print(str.substring(0, i + 1));
}
}
When I run the method below keep in mind ADFGVX will be printed to the left and over the top of the array when its displayed, just like a classic ADFGVX cypher.
static char [][] poly = new char[][]{
{'p','h','0','q','g','6'},
{'4','m','e','a','1','y'},
{'l','2','n','o','f','d'},
{'x','k','r','3','c','v'},
{'s','5','z','w','7','b'},
{'j','9','u','t','i','8'}};
I have written a method that displays a polybius square using a 2d array(array can be seen above) and what I want to do is pair what ever the user enters with the square, so if the user types OBJECT I want it to return FG VX XA DF GV XG.
Scanner console = new Scanner (System.in);
String phrase;
displayGrid();
System.out.println("");
System.out.print("Please enter a phrase you want to use\n");
phrase = console.nextLine();
console.close();
Does anyone here know how I would go about this? I was going to make a switch statement or something but I don't think that would work and even if it did it would be very long and inefficient.
You could just iterate over your array to get the position of the character you are looking for and than decode this position to the letter.
public static String[] cypherADFGVX(String phrase){
String[] output=new String[phrase.length()];
for (int i = 0; i < phrase.length(); i++) {
//optional for breaking
//squareIteration:
for (int j = 0; j < 6; j++) {
for (int k = 0; k < 6; k++) {
if(poly[j][k]==phrase.charAt(i)){
output[i]=new String(new char[]{switchChar(j),switchChar(k)});
//To stop the iteration over poly and take care of the next char
//break squareIteration;
}
}
}
}
return output;
}
public static char switchChar(int integer){
switch (integer) {
case 0:
return 'A';
case 1:
return 'D';
//and so on
}
}
If I left any questions just ask.
To answer your questions
Oh. I see. I made it a bit too complicated for java beginners.
An easier solution with just one String would be:
public static String cypherADFGVX(String phrase){
String output=new String[phrase.length()];
for (int i = 0; i < phrase.length(); i++) {
//optional for breaking
//squareIteration:
for (int j = 0; j < 6; j++) {
for (int k = 0; k < 6; k++) {
if(poly[j][k]==phrase.charAt(i)){
output=output+switchChar(j)+switchChar(k)+" ";
//To stop the iteration over poly and take care of the next char
//break squareIteration;
}
}
}
}
return output;
}
Now let me explain what my lines do.
String[] output=new String[phrase.length()];
creates a new array of string where each string are the two capital letters.
It would look like ["FG","VX",...]. It is easier for futher processing in my opinion.
if(poly[j][k]==phrase.charAt(i))
Compares the character at position jk in your square with the i-th character of the input String.
output[i]=new String(new char[]{switchChar(j),switchChar(k)});
I use the String constructor that takes a char-array as argument.
new char[]{'a','b'}
creates the array and fills it with the elements listed in the brackets.
Sure you can use the switch to set the value of a variable and than return that variable.
So our teacher gave us this homework, we had to write a program that went something along the lines of
Write an application that reads a line of text from the keyboard and prints a table indicating the number of occurrences of each letter
of the alphabet in the text, For example, the phrase
To be, or not to be: that is the question:
Contains one “a,” two “b’s,” no “c’s,” and so on.
Well I've written the code, but I've ran into one small problem when I enter the to be or not to be part the code continually loops forever. I've looked at this program forever, I even tried asking some folks at Yahoo (but I think I confused them). So I am hoping someone here will spot something I missed or have some advice to give me.
public class occurances {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
String str;
char ch;
int count = 0;
System.out.println("Enter the string:");
str = inp.nextLine();
while (str.length() > 0) {
ch = str.charAt(0);
int i = 0;
while (i < str.length() && str.charAt(i) == ch) {
count = count++;
i++;
}
str = str.substring(count);
System.out.println(ch);
System.out.println(count);
}
}
}
There are many problems with your code, but start with count = count++. It will always have its initial values (0 in your case). That causes the infinite loop. If you manage this one you'll be good to go with debugging your code further. Learn how to use debugger and/or print for checking your code. Good luck.
It seems your approach is not necessarily the one the teacher wants. Your approach (if it worked at all) would display the character counts in the order the characters appear in the string. So, for example, for "To be, or not to be: that is the question" you would show the character count for "T" first, whereas the teacher probably wants you to show the character count for "a" first. Your approach also doesn't show the character counts for the characters that are missing in the answer.
It has been suggested in the other two answers to use a Map. I recommend that approach, although you could use a simple int[] array where the index is (ch - 'a') assuming that it is between 0 and 25. See Character.toLowerCase() for how to convert a character into a lowercase one, because the correct answer would probably treat "T" and "t" as the same.
You need only one loop through the array, incrementing the counts for the characters that appear. Obviously all of the counts should be initialized to 0 prior to the loop.
I've not done JAVA in a while i came here to help someone with Javascript... but i'll give it go
while(str.length()>0)
This will obviously enter an endless loop because you have no breakout terms... i'd probably use a for loop instead... also you need something to store your counts inside of for each unique letter you find.
-- EDIT based on the comment below i find myself agreeing that answering your homework is not a good thing but here is what i'd suggest you look at...
Look at Hashtables or Maps and thing about "storing the dictionary counts as you find them"
Bare in mind upper and lower case letter, i'd just cast to lowercase and count
use a for loop instead of the while loop, use the strings length as the limit e.g. count from 0 to string.length()
This should get you on the right path :http://www.java2s.com/Tutorial/Java/0140__Collections/GettingelementskeyvaluepairsfromaHashtabletheentrySetmethod.htm
Some things to resolve in your code:
while(str.length()>0) : Infinite loop here. You could go through the string, with a for (int index = 0; index < str.length(); index++).
ch = str.charAt(0); : Here you are always taking the first letter of the String, you should take each letters with ch = str.charAt(index);.
count = count++; : count++; would be enough or count = count + 1;.
count = count++; : count should be re-initialized for each letter count = 0; before your while inner loop.
str = str.substring(count); : No need to substring here. You would loose letters for next computation.
Your code should work with one disavantages. The letters and their count will be written as many times as their is their occurence. If a is 3 times in the String, a : 3 will be written 3 times.
So you should whether you had already print the letter (maybe an array), but performance would be bad. For a String of n letters, you would have n * n computations (Complexity O(n^2)). If you take an HashMap between letter and their count, you will just of to go through the String one time, incrementing your counter while iterating on the loop. Then you would have only n computations. (Complexity O(n)).
HashMap<Char, Integer> letters = new HashMap<Char, Integer>();
for (int i = 0; i < str.length(); i++) {
char letter = str.charAt(i);
if (!letters.contains(letter)) {
letters.put(letter, 1);
} else {
letters.put(letter, letters.get(letter) + 1);
}
}
Then you go through the map to display the count.
Here is your corrected code for the problem you asked..Try this..
import java.util.*;
public class Occurence {
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
String str;
char ch;
int count = 0;
System.out.println("Enter the string:");
str = inp.nextLine();
int length = str.length();
int i = 0, j = 0;
for (i = 0; i < length; i++) {
j = 0;
count=0;
for (j = 0; j < length; j++) {
if (str.charAt(j) == str.charAt(i)) {
count++;
}
System.out.println(str.charAt(i)+" "+count);
}
}
}
}
I have a four letter string of letters, such as ASDF and I want to find all 3 (three) letter combinations using these letters and the three letter combination does not need to form a real word.Ex.
AAA AAS AAD AAF
ADA ADS ADD ADF
...............
SSA SSD SSF SSS
I am relatively new to Java, having just learned how to use the String class and using loops and conditional statements. The only way that I know how to do this is by a massive and very tedious set of for loops and if statements that account for every possibility that could arise. This would look like:
public static void main(String[] args)
{
String combo = "";
for(int counter = 1; counter <= 16; counter++){
combo = "A";
if(counter == 1){
combo = combo + "AA";
}
// This would continue on for all the possibilities starting with "A" and
// then move on to "S" as the lead character
}
}
I know that this is one of the worst ways to go about this problem, but I am really stuck as to how to do it another way. It would be easier if I had 3 letters and made the 3 letter combos, as then I could just get each letter from the array and just rearrange them, but as I'm only using 3 of the 4 letters it is more difficult. Any advice on how to get this done in an more efficient manner?
Use a recursive function.
Like this (not tested, don't have a Java compiler on my laptop).
Performance could probably be boosted by using StringBuilder.
static void printAllPossibilities(String charSet, int length) {
printAllPossibilities_(charSet, length, "");
}
static void printAllPossibilities_(String charSet, int length, String temp) {
if (length == 0) {
System.out.println(temp);
return;
}
for (int i = 0; i < charSet.length(); i++)
printAllPossibilities_(charSet, length - 1, temp + charSet.charAt(i));
}
Usage:
printAllPossibilities("ASDF", 4); // Print all 4-letter combinations out of "ASDF"
printAllPossibilities("bar", 2); // Print all 2-letter combinations out of "bar"
For the general case (all combinations of N chars out of M), the solution by #Qntm is exactly what you need... but, use a StringBuilder as he said, and just change the last character instead of constructing strings like 'temp + charSet.charAt(i)'.
If you need exactly 3 chars out of N, it's easier to just do 3 nested loops:
for (int char1 = 0; char1 < charSet.length(); char1++) {
for (int char2 = 0; char2 < charSet.length(); char2++) {
for (int char3 = 0; char3 < charSet.length(); char3++) {
System.out.println(""+charSet.charAt(char1)+charSet.charAt(char2)+charSet.charAt(char3));
}
}
}