I need help converting Morse Code to English. I have already written and tested the code for translating English to Morse. My main problem is having all the characters in the Morse code together before translating it to an English character if that makes sense.
Example: "." translates to E and ... translates to S, but I don't want the translation to start until it reaches ...
Few Rules
-Spaces are used to separate Morse Letters
-| is used as an delimiter to separate words
-Cant use an hashmap :(
Here is my code
import java.util.Arrays;
import javax.swing.JOptionPane;
public class test3
{
public static void main ( String [] args )
{
String s1 = "Morse";
// Decide whether Morse code or English
String decide = JOptionPane.showInputDialog("Enter 'English' for Morse to English code translation and 'Morse' for English to Morse code translation. Pay attention to Caps.");
// Enter String & decide whether to convert to Morse or English
String phrase = JOptionPane.showInputDialog("Enter the words you wish to translate.");
if ( decide.equals( s1 ))
toMorse( phrase );
else
toEnglish( phrase );
}
// Translate to Morse
public static void toMorse( String preTranslation )
{
String[] english = {"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","1","2","3","4","5","6","7","8","9","0"};
String[] morse = {".-","-...","-.-.","-..",".","..-.","--.","....","..", ".---",
"-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-",
"...-",".--","-..-","-.--","--..",".----","..---","...--","....-",".....","-....","--...","---..","----.","-----"};
// Remove uppercase
String preTrans = preTranslation.toLowerCase();
// Deletes spaces
String phraseWithDelimiter = preTrans.replace( " ", "|");
String[] translation = new String[phraseWithDelimiter.length()];
String[] delimiter = {"|"};
// Translate
for ( int arrayVar = 0, transArrayVar = 0, subStringVarB = 0, subStringVarE = 1; transArrayVar < phraseWithDelimiter.length();)
{
if( phraseWithDelimiter.substring(subStringVarB, subStringVarE).equals( delimiter[0] ) )
{
translation[transArrayVar] = delimiter[0];
transArrayVar++;
subStringVarB++;
subStringVarE++;
}
else if ( phraseWithDelimiter.substring(subStringVarB, subStringVarE).equals( english[arrayVar] ) )
{
translation[transArrayVar] = morse[arrayVar];
transArrayVar++;
subStringVarB++;
subStringVarE++;
arrayVar = 0;
}
else
{
arrayVar++;
if ( arrayVar == 35 )
{
arrayVar = 0;
subStringVarB++;
subStringVarE++;
transArrayVar++;
}
}
}
String morseSeparator = new String( " " );
arrayToString ( translation, morseSeparator );
}
//Convert array to string and print translation
public static void arrayToString(String[] trans, String separator)
{
String result = "";
if (trans.length > 0)
{
result = trans[0]; // start with the first element
for (int i = 1; i < trans.length; i++)
result = result + separator + trans[i];
}
System.out.println( result );
}
// unfinished
public static void toEnglish( String preTranslation)
{
}
I was thinking about making a for statement and assigning every character of the Morse code to a new string until I reach a white space and then using that to test but I'm unsure about how to do that.
Any help is appreciated thanks!
Create a regular expression containing all the Morse code sequences in order from longest to shortest.
Pattern.compile("----\\.|-----|---\\.\\.|...")
and then just match that repeatedly against a string to get the longest valid Morse code sequence.
Alternatively, you can use a parser compiler like JavaCC.
SKIP : { " " }
TOKEN : { < A : "-." > }
TOKEN : { < B : "-..." > }
TOKEN : { < C : "-.-." > }
...
String translate() :
{ StringBuilder sb; }
{
{ sb = new StringBuilder(); }
(
letter(sb)
)*
<EOF>
{ return sb.toString(); }
}
void letter(StringBuilder sb) :
{}
{
( <A>
{ sb.append('a'); }
| <B>
{ sb.append('b'); }
| <C>
{ sb.append('c'); }
...
)
}
For translating the text you might try and split it on word delimiters first, then on character limiters. Then process the words one by one. Similar to this:
String morseInput = //whatever, only delimiters or morse characters
String[] words = morseInput.split("-|");
for( String word : words ) {
String[] characters = word.split("\\s");
for( String c : characters ) {
//look up the english character for c - I'd use a map here
}
}
A few notes:
I omitted checks for empty strings and null for brevity
I also left out any code to build the final translation string, that's an excercise for you
I'd use a Map<String, String> for the lookup, if that's not allowed, look up the index of the character in the source array and then get the translation at that index from the translation array
Related
I'm trying to have the letter after every space turn uppercase. Can someone tell me what's wrong with the following method? Given phrase "this is a test" it returns "ThIs Is A TesT" instead of "this Is A Test"
public String toTitleCase(String phrase) {
for (int i=0; i<phrase.length(); i++) {
if(phrase.substring(i,i+1).equals(" ")) {
phrase = phrase.replace(phrase.substring(i+1,i+2),phrase.substring(i+1,i+2).toUpperCase());
}
}
return phrase;
}
The problem in your code is that String.replace replaces each target character present in the String, and not only the one you want.
You could work directly on an array of chars instead of on the String:
public static String toTitleCase(String phrase) {
// convert the string to an array
char[] phraseChars = phrase.toCharArray();
for (int i = 0; i < phraseChars.length - 1; i++) {
if(phraseChars[i] == ' ') {
phraseChars[i+1] = Character.toUpperCase(phraseChars[i+1]);
}
}
// convert the array to string
return String.valueOf(phraseChars);
}
It's replacing all t, try below code.
It will help you.
String phrase="this is a test";
for (int i=0; i<phrase.length(); i++) {
if(phrase.substring(i,i+1).equals(" ")) {
System.out.println(phrase.substring(i+1,i+2));
phrase = phrase.replace(phrase.substring(i,i+2),phrase.substring(i,i+2).toUpperCase());
}
}
System.out.println(phrase);
Use streams (or split) to split your string into parts, don't do it manually using substring.
Try below code
String test = "this is a test";
UnaryOperator<String> capitalize = str ->
str.substring(0,1).toUpperCase() + str.substring(1).toLowerCase();
String result =
Stream.of(
test.split(" ")
).map(capitalize)
.collect(
Collectors.joining(" ")
);
System.out.println(result);
Output: This Is A Test
When you replace a substring it will replace the each occurrence of that substring - which is not necessarily the one you are trying to replace. This is why it is replacing letters inside words.
Switching to a StringBuilder here to poke individual characters. Note that we don't traverse the entire String because there is no next-character to capitalize at the last character.
public String toTitleCase(String phrase) {
StringBuilder sb = new StringBuilder(phrase);
for (int index = 0 ; index < phrase.length - 1 ; ++index) {
if (sb.charAt(index) == ' ') {
sb.setCharAt(index + 1, Character.toUppercase(sb.charAt(index + 1)));
}
}
return sb.toString();
}
If a letter is first in any word, it will be replaced everywhere. In your case, all t,i and a will be uppercase.
Taking example for is. It is find a space before. Than in if body, what actually happen:
phrase = phrase.replace("i","I");
And all i are replaced with I.
String class cannot replace at a specific position.
You have to options:
using StringBuilder which can replace at a specific position.
String toTitleCase(String phrase) {
StringBuilder sb= new StringBuilder(phrase);
for (int i=0; i<phrase.length(); i++) {
if(i==0 || phrase.charAt(i-1)==' ') {
sb.replace(i,i+1,phrase.substring(i,i+1).toUpperCase());
}
}
return sb.toString();
}
or with stream, which is the method I prefer because is one-line. This way you don't preserve white-spaces( multiple consecutive white-spaces will be replaced with only one space), but usually you want this.
Arrays.asList(phrase.split("\\s+")).stream().map(x->x.substring(0,1).toUpperCase()+x.substring(1)).collect(Collectors.joining(" "));
I'm trying to make a converter from english alphabet letters to morse code, but I'm having difficulties when it comes to more than one inputed letter. I can tell what my problem is, but not the solution.
I'm very new to java and I know the way I'm doing it is very sloppy and repetitive, but this is all I could figure out with what I know so far.
I made some scenarios such as, figure out how many letters are in the input, and convert each letter; but again, I'm not sure if this would work or if it's even possible.
import java.util.Scanner;
public class JavaPractice {
public static void main(String[] args) {
String morseA;
morseA = "•-";
String morseB;
morseB = "-•••";
String morseC;
morseC = "-•-•";
String morseD;
morseD = "-••";
String morseE;
morseE = "•";
String morseF;
morseF = "••-•";
String morseG;
morseG = "--•";
String morseH;
morseH = "••••";
String morseI;
morseI = "••";
String morseJ;
morseJ = "•---";
String morseK;
morseK = "-•-";
String morseL;
morseL = "•-••";
String morseM;
morseM = "--";
String morseN;
morseN = "-•";
String morseO;
morseO = "---";
String morseP;
morseP = "•--•";
String morseQ;
morseQ = "--•-";
String morseR;
morseR = "•-•";
String morseS;
morseS = "•••";
String morseT;
morseT = "-";
String morseU;
morseU = "••-";
String morseV;
morseV = "•••-";
String morseW;
morseW = "•--";
String morseX;
morseX = "-••-";
String morseY;
morseY = "-•--";
String morseZ;
morseZ = "--••";
Scanner morseInput = new Scanner(System.in);
System.out.println("type a letter and it will be converted into morse code!");
String morseTranslation = morseInput.nextLine();
if (morseTranslation.length() > 0) {
if (morseTranslation.equals("a")) {
System.out.println(morseA);
}
if (morseTranslation.equals("b")) {
System.out.println(morseB);
}
if (morseTranslation.equals("c")) {
System.out.println(morseC);
}
if (morseTranslation.equals("d")) {
System.out.println(morseD);
}
if (morseTranslation.equals("e")) {
System.out.println(morseE);
}
if (morseTranslation.equals("f")) {
System.out.println(morseF);
}
if (morseTranslation.equals("g")) {
System.out.println(morseG);
}
if (morseTranslation.equals("h")) {
System.out.println(morseH);
}
if (morseTranslation.equals("i")) {
System.out.println(morseI);
}
if (morseTranslation.equals("j")) {
System.out.println(morseJ);
}
if (morseTranslation.equals("k")) {
System.out.println(morseK);
}
if (morseTranslation.equals("l")) {
System.out.println(morseL);
}
if (morseTranslation.equals("m")) {
System.out.println(morseM);
}
if (morseTranslation.equals("n")) {
System.out.println(morseN);
}
if (morseTranslation.equals("o")) {
System.out.println(morseO);
}
if (morseTranslation.equals("p")) {
System.out.println(morseP);
}
if (morseTranslation.equals("q")) {
System.out.println(morseQ);
}
if (morseTranslation.equals("r")) {
System.out.println(morseR);
}
if (morseTranslation.equals("s")) {
System.out.println(morseS);
}
if (morseTranslation.equals("t")) {
System.out.println(morseT);
}
if (morseTranslation.equals("u")) {
System.out.println(morseU);
}
if (morseTranslation.equals("v")) {
System.out.println(morseV);
}
if (morseTranslation.equals("w")) {
System.out.println(morseW);
}
if (morseTranslation.equals("x")) {
System.out.println(morseX);
}
if (morseTranslation.equals("y")) {
System.out.println(morseY);
}
if (morseTranslation.equals("z")) {
System.out.println(morseZ);
}
System.out.println(morseTranslation.charAt(0) + " " + morseTranslation.charAt(1));
}
}
}
// if statements
// long but might work
// charAt find out how many letters they typed in/inputed
// make something that uses chatAt for each character depending on how many there are,
// and individually translate each letter
I would recommend you to store each letter and their morse translations in two separate arrays or as key value pairs in a map. For example :
String [] morsetrans = {"•-","-•••", and so on};
String [] letters = {"a","b", and so on};
I think this would be a much easier way to do things. You just need to write the logic accordingly to match the letters in the array and take their corresponding morse translation from the array that corresponds to the morse translation using the index of the letter.
For "a" index is 0 and its corresponding more translation is located in the same index in morsetrans array.
Please try this edited code,It will print input word in Morse code
import java.util.Scanner;
public class JavaPractice {
public static void main(String[] args) {
String morseA;
morseA = "•-";
String morseB;
morseB = "-•••";
String morseC;
morseC = "-•-•";
String morseD;
morseD = "-••";
String morseE;
morseE = "•";
String morseF;
morseF = "••-•";
String morseG;
morseG = "--•";
String morseH;
morseH = "••••";
String morseI;
morseI = "••";
String morseJ;
morseJ = "•---";
String morseK;
morseK = "-•-";
String morseL;
morseL = "•-••";
String morseM;
morseM = "--";
String morseN;
morseN = "-•";
String morseO;
morseO = "---";
String morseP;
morseP = "•--•";
String morseQ;
morseQ = "--•-";
String morseR;
morseR = "•-•";
String morseS;
morseS = "•••";
String morseT;
morseT = "-";
String morseU;
morseU = "••-";
String morseV;
morseV = "•••-";
String morseW;
morseW = "•--";
String morseX;
morseX = "-••-";
String morseY;
morseY = "-•--";
String morseZ;
morseZ = "--••";
Scanner morseInput = new Scanner(System.in);
System.out.println("type a letter and it will be converted into morse code!");
String morseTranslation = morseInput.nextLine();
if (morseTranslation.length() > 0) {
for (int i = 0; i < morseTranslation.length(); i++) {
String character = ""+morseTranslation.charAt(i);
if (character.contains("a")) {
System.out.println(morseA);
}
if (character.contains("b")) {
System.out.println(morseB);
}
if (character.contains("c")) {
System.out.println(morseC);
}
if (character.contains("d")) {
System.out.println(morseD);
}
if (character.contains("e")) {
System.out.println(morseE);
}
if (character.contains("f")) {
System.out.println(morseF);
}
if (character.contains("g")) {
System.out.println(morseG);
}
if (character.contains("h")) {
System.out.println(morseH);
}
if (character.contains("i")) {
System.out.println(morseI);
}
if (character.contains("j")) {
System.out.println(morseJ);
}
if (character.contains("k")) {
System.out.println(morseK);
}
if (character.contains("l")) {
System.out.println(morseL);
}
if (character.contains("m")) {
System.out.println(morseM);
}
if (character.contains("n")) {
System.out.println(morseN);
}
if (character.contains("o")) {
System.out.println(morseO);
}
if (character.contains("p")) {
System.out.println(morseP);
}
if (character.contains("q")) {
System.out.println(morseQ);
}
if (character.contains("r")) {
System.out.println(morseR);
}
if (character.contains("s")) {
System.out.println(morseS);
}
if (character.contains("t")) {
System.out.println(morseT);
}
if (character.contains("u")) {
System.out.println(morseU);
}
if (character.contains("v")) {
System.out.println(morseV);
}
if (character.contains("w")) {
System.out.println(morseW);
}
if (character.contains("x")) {
System.out.println(morseX);
}
if (character.contains("y")) {
System.out.println(morseY);
}
if (character.contains("z")) {
System.out.println(morseZ);
}
}
System.out.println(morseTranslation.charAt(0) + " " + morseTranslation.charAt(1));
}
}
}
As you are a beginner in JAVA learn while and for loop to fix your problem. You have to loop through the String input line to print morse code. Learn switch case also. I am not providing any code as you are beginner and may not have any knowledge about loops.
Because you are using letters, you could use charAt() to convert a letter into a char, which can then be easily turned into an index of an array by using the ASCII value of the char. You can store the morse letters as a separate array and easily convert from alphabetic characters to their morse representations like so:
import java.util.Scanner;
public class JavaPractice {
//You can store the morse alphabet as a constant array to
//group all the letters together into one data structure
public static final String[] MORSE_ALPHABET = new String[] {
"•-", "-•••", "-•-•", "-••", "•",
"••-•", "--•", "••••", "••", "•---",
"-•-", "•-••", "--", "-•", "---",
"•--•", "--•-", "•-•", "•••", "-",
"••-", "•••-", "•--", "-••-", "-•--", "--••"};
public static void main(String[] args) {
Scanner morseInput = new Scanner(System.in);
System.out.println("type a letter and it will be converted into morse code!");
String morseTranslation = morseInput.nextLine();
for (int i = 0; i < morseTranslation.length(); i++) {
System.out.print(alphaToMorse(morseTranslation.charAt(i)) + " ");
}
System.out.println();
}
public static String alphaToMorse(char c) {
if (c > 91) { //this would convert lowercase letters to their uppercase counterparts
c -= 32;
}
if (c < 91 && c > 64) { //65-90 are the ASCII representations for A-Z
return MORSE_ALPHABET[c - 65]; //A = 65 which maps to index 0, B = 66 maps to index 1, etc.
}
return "";
}
}
For input "Happy":
output: "•••• •- •--• •--• -•-- "
Here is a quick solution to your problem, note that there could be simpler/easier to read ways to store the morse code, but for now this will do:
String[] morseCode = {"•-","-•••","-•-•", "-••","•","••-•","--•", "••••", "••","•---","-•-","•-••", "--","-•","---", "•--•","--•-", "•-•", "•••", "-", "••-", "•••-", "•--","-••-", "-•--", "--••"};
String alphabet = "abcdefghijklmnopqrstuvwxyz";
Scanner morseInput = new Scanner(System.in);
System.out.println("type something and it will be converted into morse code!");
String morseTranslation = morseInput.nextLine().toLowerCase();
for(int i = 0; i < morseTranslation.length(); i++)
System.out.print(morseCode[alphabet.indexOf(morseTranslation.charAt(i))] + " ");
First, by using a loop, you can convert a string of any length.
Also, by storing all your values in an array/enum or any type of collection, you can simply refer to a code by it's position to avoid repeating yourself (ie: 8th letter of the alphabet should match 8th morse code)
ps: morseInput.nextLine().toLowerCase() is used to only have to compare
lowercase letters instead of implementing lowercases AND uppercase letters. If you want to save the message in its original form, you can always store it first before applying .toLowerCase()
Need help. Remove letter “e” in the end of each word if word length > 1.
I have tried to do it via strig split and toCharArray, but I can't convert array after removing to string.
Thank you in advance.
public class RemoveE {
public static void main(String args[]) {
String str = "like row lounge dude top";
String[] words = str.split("\\s|[,.;:]");
for (String subStr : words) {
if (subStr.endsWith("e"))
subStr = subStr.substring(0, subStr.length() - 1);
String finalString = new String(subStr);
System.out.println(finalString);
}
}
}
It would be much simpler if you do it via regex like this
finalString = str.replaceAll("e\\b", "");
This is giving following output:
lik row loung dud top
PS: This solution assumes that you would like to drop even a single e in string since in the question, we're using if (subStr.endsWith("e")) which will also remove a single e in the String.
For your code, all the splitting and if conditions are right, all you need to do is add the subStr to finalString when process is completed. I've re-arranged 3 lines from your code, you can find explanation within comments:
public class RemoveE {
public static void main(String args[]) {
String str = "like row lounge dude top";
String[] words = str.split("\\s|[,.;:]");
String finalString = ""; // Bring the declaration outside of for loop
for (String subStr : words) {
if (subStr.endsWith("e"))
subStr = subStr.substring(0, subStr.length() - 1);
finalString += subStr + " "; // Add the substring and a whitespace to substring and add it to finalString to create the sentence again
}
System.out.println(finalString); // Print the String outside of final `for` loop
}
}
This gives the following output:
lik row loung dud top
Raman's first answer provides a good start for a solution with a regular expression. However to ensure that that it only drops the e if the word itself has more than one character, you can add a negative lookbehind to ensure that there is no word boundary immediately before the letter e with (?<!\\b) :
String str = "like row lounge dude top e";
String replaced = str.replaceAll("(?<!\\b)e\\b", "");
System.out.println("Replaced: " + replaced);
This solution is without regex. Adding this as reference as this may be helpful too in future.
I guess, explanation is not needed as a new char array is created and simple for-loop is used to iterate through the input string and keep the valid char in the new char array in appropriate position by checking the conditions.
public class RemoveE {
public static void main (String[] args) {
String str = "like row lounge dude top";
char[] strChars = str.toCharArray();
int size = str.length();
int temp = 0;
char[] newStringChars = new char[size];
String newString = null;
newStringChars[0] = strChars[0];
for(int i=1; i<size; i++) {
if(!(strChars[i] == 'e' && strChars[i+1] == ' ')) {
temp++;
newStringChars[temp] = strChars[i];
}
else if(strChars[i] == 'e' && strChars[i+1] == ' ' && strChars[i-1] == ' ') {
temp++;
newStringChars[temp] = strChars[i];
}
else {
continue;
}
}
newString = String.valueOf(newStringChars);
System.out.println(newString);
}
}
For String str = "like row lounge dude top"; output is:
lik row loung dud top
AND
For String str = "like row e lounge dude top"; (only one e present
in a word, i.e. not word length > 1 as mentioned in the question),
output is:
lik row e loung dud top
I need to do some keywords search and print if true.
works fine if i am comparing in order. but i want to
compare the following cases and expect them to be true.
do some java programming = true
some java = true
do programming = true
and finally most importantly
programming java = true
programming java some do = true
I need to return true for all the cases mentioned above but so far it only works for case 1 and 2
public class Examples {
public static void main(String[] args) {
String[] given = new String[20];
given[0] = ("do some java programming");
given[1] = ("do some grocery shopping");
given[2] = ("play soccer at the west field");
String input = new String();
Scanner userInput = new Scanner(System.in);
System.out.println("Enter the string to compare");
input[0] = userInput.nextLine();
for (int i=0; i <20; i++){
if(given[i].contains(input))
{
System.out.println(given[i]);
}
else
{
//do nothing
}
}
}
}
Outline of one way to solve this:
Each string in given should be converted to a Set<String> that is a set of all the words in the string. Use split() on each string to get the words, then go through the list of words and add each word to the Set.
For each input string, use split() to split it into words, then create any kind of collection (a Set<String> will work, but creating a List<String> by using Arrays.asList works too.
You can then see if the collection of words from the input is a subset of the set of words in each given string by using a Set's containsAll method.
(Note that you'll have to make sure the input string isn't the empty set first. Also, if the input string has more than one occurrence of any word, this approach won't catch that, without some extra logic.)
For this Regex will be your friend.
Here's some working code to play with:
String[] matches = input[0].split(" ");
for (int i=0; i <3; i++){
for(String s: matches){
if(given[i].contains(s))
System.out.println(given[i]);
break;
}
}
}
Split the given lines and store it in a List.
Again split the input line and compare word by word.
Below is the code snippet
public class StringCompare
{
public static final String delimiter = " ";
public static void main( String[] args )
{
String[] given = new String[20];
given[ 0 ] = ( "do some java programming" );
given[ 1 ] = ( "do some grocery shopping" );
given[ 2 ] = ( "play soccer at the west field" );
List< List< String >> listLineAsWords = new ArrayList< List< String >>();
//split each line and store it as list.
for ( String line : given )
{
if ( line == null )
break;
listLineAsWords.add( Arrays.asList( line.split( delimiter ) ) );
}
//Write your own logic to get the input line
String inputLine = "programming java";
if ( compareLine( inputLine, listLineAsWords ) )
System.out.println( "The input line is part of given lines" );
}
private static boolean compareLine( String inputLine, List< List< String >> listLineAsWords )
{
if ( inputLine == null )
return false;
List< String > words = Arrays.asList( inputLine.split( delimiter ) );
for ( List< String > listOfWords : listLineAsWords )
{
boolean isPartOfLine = true;
for ( String word : words )
{
if ( !listOfWords.contains( word ) )
{
isPartOfLine = false;
break;
}
}
if(isPartOfLine)
return true;
}
return false;
}
}
Your code is almost right, yet it needs some changes
First, since in your sample code you have 3 case, it is best to define your given array length 3.
String[] given = new String[3];
Note: for more cases, you can define bigger array length; for example, if you will add other 2 cases, your array length is 5
For all reference types, the default value is null if you have array length more than you need.
read more about it here
Second, in your if statement, you want to check if input contains given element of array or not
if (input.contains(given[i])) {
code:
String[] given = new String[3];
given[0] = ("do some java programming");
given[1] = ("do some grocery shopping");
given[2] = ("play soccer at the west field");
Scanner userInput = new Scanner(System.in);
System.out.println("Enter the string to compare");
String input = userInput.nextLine();
for (int i = 0; i < given.length; i++) {
if (input.contains(given[i])) {
System.out.println(given[i]);
} else {
// System.out.println("do nothing");
}
}
output:
Modify as below assuming everything else is fine
//here initialize 'given' array
//get the user input in a string that is 'input[0]' in your case
int count = 0;
for (String s : given) {
if (s != null && s.matches(input[0])) {
//it matches and print it
} else {
//either it's not a match or the 'given' array has a null at this index
}
count++;
}
I must say, get the user input in a string. I don't understand why you have it in input array.
At input i have some string : "today snowing know " , here i have 3 words , so i must to parse them is such way : every character i must compare with all other characters , and to sum how many same characters these words have , like exemple for "o" letter will be 2 (from "today" and "snowing") or "w" letter will be 2 (from "know" and "snowing"). After that i must to replace these characters with number(transformed in char format) of letters. The result should be "13111 133211 1332".
What i did ?
First i tape some words and
public void inputStringsForThreads () {
boolean flag;
do {
// will invite to input
stringToParse = Input.value();
try {
flag = true;
// in case that found nothing , space , number and other special character , throws an exception
if (stringToParse.equals("") | stringToParse.startsWith(" ") | stringToParse.matches(".*[0-9].*") | stringToParse.matches(".*[~`!##$%^&*()-+={};:',.<>?/'_].*"))
throw new MyStringException(stringToParse);
else analizeString(stringToParse);
}
catch (MyStringException exception) {
stringToParse = null;
flag = false;
exception.AnalizeException();
}
}
while (!flag);
}
I eliminate spaces between words , and from those words make just one
static void analizeString (String someString) {
// + sign treat many spaces as one
String delimitator = " +";
// words is a String Array
words = someString.split(delimitator);
// temp is a string , will contain a single word
temp = someString.replaceAll("[^a-z^A-Z]","");
System.out.println("=============== Words are : ===============");
for (int i=0;i<words.length;i++)
System.out.println((i+1)+")"+words[i]);
}
So i try to compare for every word in part (every word is split in letters) with all letter from all words , But i don know how to count number of same letter and after replace letters with correct number of each letter??? Any ideas ?
// this will containt characters for every word in part
char[] motot = words[id].toCharArray();
// this will containt all characters from all words
char[] notot = temp.toCharArray();
for (int i =0;i<words[i].length();i++)
for (int j=0;j<temp.length ;j++)
{
if (i == j) {
System.out.println("Same word");
}
else if (motot[i] == notot[j] ) {
System.out.println("Found equal :"+lol[i]+" "+lol1[j]);
}}
For counting you might want to use a Map<Character, Integer> counter like java.util.HashMap. If getting a Value(Integer) using a specific key (Character) from counter is 'not null', then your value++ (leverage autoboxing). Otherwise put a new entry (char, 1) in the counter.
Replacing the letters with the numbers should be fairly easy then.
It is better to use Pattern Matching like this:
initially..
private Matcher matcher;
Pattern regexPattern = Pattern.compile( pattern );
matcher = regexPattern.matcher("");
for multiple patterns to match.
private final String[] patterns = new String [] {/* instantiate patterns here..*/}
private Matcher matchers[];
for ( int i = 0; i < patterns.length; i++) {
Pattern regexPattern = Pattern.compile( pattern[i] );
matchers[i] = regexPattern.matcher("");
}
and then for matching pattern.. you do this..
if(matcher.reset(charBuffer).find() ) {//matching pattern.}
for multiple matcher check.
for ( int i = 0; i < matchers.length; i++ ) if(matchers[i].reset(charBuffer).find() ) {//matching pattern.}
Don't use string matching, not efficient.
Always use CharBuffer instead of String.
Here is some C# code (which is reasonably similar to Java):
void replace(string s){
Dictionary<char, int> counts = new Dictionary<char, int>();
foreach(char c in s){
// skip spaces
if(c == ' ') continue;
// update count for char c
if(!counts.ContainsKey(c)) counts.Add(c, 1);
else counts[c]++;
}
// replace characters in s
for(int i = 0; i < s.Length; i++)
if(s[i] != ' ')
s[i] = counts[s[i]];
}
Pay attention to immutable strings in the second loop. Might want to use a StringBuilder of some sort.
Here is a solution that works for lower case strings only. Horrible horrible code, but I was trying to see how few lines I could write a solution in.
public static String letterCount(String in) {
StringBuilder out = new StringBuilder(in.length() * 2);
int[] count = new int[26];
for (int t = 1; t >= 0; t--)
for (int i = 0; i < in.length(); i++) {
if (in.charAt(i) != ' ') count[in.charAt(i) - 'a'] += t;
out.append((in.charAt(i) != ' ') ? "" + count[in.charAt(i) - 'a'] : " ");
}
return out.substring(in.length());
}