I've been trying to see if there is a way of solving this problem with a double loop. Looping over each word in the array and checking to see if all of the chars provided exist in that word.
Broken keyboard Problem:
Input A = "Hello, my dear friend!"
Input B = ['h', 'e', 'l, 'o', 'm']
We have a broken keyboard here in which only the alphabet keys (both lower case and upper case) in list B, number keys and punctuation keys work.
Write the function which take a string A and list of char B, and return how many words we can type.
Explanation
input: A "Hello, my dear friend!", B = ['h', 'e', 'l, 'o', 'm'] output: 1
Explanation: For the first word "Hello," (including the comma), we can find every char in list B.
Since all punctation key works fine, so output++.
For the second word "my", we only can find char 'm' in list B, so we can't type the whole word. Then the same, "dear", can't find char 'd', so continue; "friend!", can't find char 'f', so continue;
This is what I have tried so far, but I can't use String's .contain() method as it only accepts a char sequence not a char array. How can I check each individual word for an array of chars using JAVA?
Thanks in advance, any support is appreciated.
public class BrokenKeyboard
{
public static void main(String[] args)
{
String stringText = "Hello my dear friend";
char [] charLetterArray = {'h', 'e', 'l', 'o', 'm'};
howManyWordsCalc(stringText, charLetterArray);
}
// Only words from stringText that can be typed in whole should be printed.
// If the letters present in the word aren't present in charLetterArray they don't get printed
public static int howManyWordsCalc(String text, char[] letters)
{
int wordCount = 0;
// sanitise input
if (text.isEmpty())
{
return 0;
}
else
{
text = text.toLowerCase();
String[] stringSeparated = text.split(" ");
for (int i = 0; i < stringSeparated.length; i++)
{
System.out.println(stringSeparated[i]);
for (int j = 0; j < letters.length; j++)
{
// stringSeparated[i].contains(letters)
if (stringSeparated[i].contains())
{
wordCount++;
}
}
}
return wordCount;
}
}
}
Here's a sample solution:
public class Main{
public static void main(String[] args){
String stringText = "Hello my dear friend";
char [] charLetterArray = {'h', 'e', 'l', 'o', 'm'};
System.out.println(howManyWordsCalc(stringText, charLetterArray));
}
// Only words from stringText that can be typed in whole should be printed.
// If the letters present in the word aren't present in charLetterArray they don't get printed
public static int howManyWordsCalc(String text, char[] letters){
int wordCount = 0;
// sanitise input
if (text.isEmpty()){
return 0;
}
else{
text = text.toLowerCase();
String[] stringSeparated = text.split(" ");
for (int i = 0; i < stringSeparated.length; i++){
int validLetters = 0;
for(int j = 0; j < stringSeparated[i].length(); j++){
for(char c: letters){
if(c == stringSeparated[i].charAt(j)){
validLetters++;
break;
}
}
}
if(validLetters == stringSeparated[i].length()){
wordCount++;
}
}
return wordCount;
}
}
}
The way that this code works is exactly the same as yours, except the algorithm for checking whether or not a word can be made up of available letters.
The algorithm that I first iterate through every word in the array. Then, I create an integer called validLetters, where we will check how many letters in the word we can type. If the number of validLetters is equal to the length of the word, then the word can be typed.
To check whether a letter can be typed, we will loop through every letter in the word, and see if it is inside of the array letters. If it is, we increase our validLetters and exit the loop.
Alternatively, if you want to strictly do this in two for loops, this is a shortened version:
import java.util.*;
public class Main{
public static void main(String[] args){
String stringText = "Hello my dear friend";
char [] charLetterArray = {'h', 'e', 'l', 'o', 'm'};
System.out.println(howManyWordsCalc(stringText, charLetterArray));
}
// Only words from stringText that can be typed in whole should be printed.
// If the letters present in the word aren't present in charLetterArray they don't get printed
public static int howManyWordsCalc(String text, char[] letters){
int wordCount = 0;
// sanitise input
if (text.isEmpty()){
return 0;
}
else{
text = text.toLowerCase();
String[] stringSeparated = text.split(" ");
for (int i = 0; i < stringSeparated.length; i++){
int validLetters = 0;
for(int j = 0; j < stringSeparated[i].length(); j++){
if (new String(letters).indexOf(stringSeparated[i].charAt(j)) != -1) {
validLetters++;
}
}
if(validLetters == stringSeparated[i].length()){
wordCount++;
}
}
return wordCount;
}
}
}
Let me know if you have any questions/clarifications!
I changed it a little bit, have a look:
public static void wordCalc(String input, char[] chars) {
String[] inputWords = input.toLowerCase().split(" ");
boolean[] allLetters = new boolean[26];
for(int i=0; i<chars.length; i++) {
allLetters[chars[i] - 'a'] = true;
}
int wordCount = 0;
for(String word : inputWords) {
boolean isWordPossible = true;
for(int i=0; i<word.length(); i++){
if(!allLetters[word.charAt(i) - 'a']){
isWordPossible = false;
break;
}
}
if(isWordPossible) {
System.out.println("word " + word + " is possible");
wordCount++;
}
}
System.out.println(wordCount);
}
I found this really neat trick on the internets once. Storing the allowed letters in a boolean array. That way, when you want to check if a char is allowed, you can just check the value of the array at index corresponding to that char!
This does bring me to an important note however. Chars are stored as ints, which is why you can cast them back and forth and do funky stuff like word.charAt(i) - 'a' (that will give you the position in the boolean array because it will give you the distance between the letter "a" and whatever letter is at position "i" in the word").
Strings are ultimately char arrays. So you can do:
char[] stuff = someString.toCharArray();
Its also pretty important to note that strings are immutable, and string literals point to the same object.
Final note on time complexity, its best to avoid nesting loops as much as possible. If you have loads of input, it will become really slow! If you have one loop, it's O(n) time, 2 loops its already O(n^2), which is quite slow as far as time complexity goes. I can't think of a different way for this case however. The structures you use and method of access can hugely impact performance. I think you'll really like HashSets, especially for this problem where allowed characters are unique anyway.
You could just check if all the characters in the word are contained in letters character array by using another loop (which actually has the same complexity as String::contains).
Also, I'd suggest to get the words by splitting on repeated punctuation and/or whitespace characters using [\p{Z}\p{P}]+ regex where \p{Z} stands for whitespaces and \p{P} for punctuation.
public static int howManyWordsCalc(String text, char[] letters) {
int wordCount = 0;
String[] words = text.toLowerCase().split("[\\p{P}\\p{Z}]+");
for (String word : words) {
// System.out.print("'" + word + "'\t");
boolean allFound = true;
for (char c : word.toCharArray()) {
boolean found = false;
for (char letter : letters) {
if (c == letter) {
found = true;
break;
}
}
if (!found) {
// System.out.println("not found letter: " + c + " in word " + word);
allFound = false;
break;
}
}
if (allFound) {
wordCount++;
// System.out.println("all found");
}
}
return wordCount;
}
Test:
System.out.println(howManyWordsCalc(
"Hello, my dear friend!", new char[] {'h', 'e', 'l', 'o', 'm', 'y'}
));
Output (with debug prints enabled):
'hello' all found
'my' all found
'dear' not found letter: d in word dear
'friend' not found letter: f in word friend
2
I have tried same in c#, but you also can use the HashSet collection and try the same. Java HashSet also has Contains().
I hope this will be helpful.
class Program
{
static void Main(string[] args)
{
string a = "Hello, my dear friend!";
string A = a.ToUpper();
string[] seperate = A.Split(new Char[] { ' ', ',', '.', '-', '\n', '\t', '!' });
HashSet<Char> hash = new HashSet<char>();
hash.Add('H');
hash.Add('E');
hash.Add('L');
hash.Add('O');
hash.Add('M');
int count = 0;
bool flag = true;
foreach (var w in seperate)
{
if (w.Length > 0) {
Char[] ca = w.ToCharArray();
foreach (var d in ca)
{
if(!hash.Contains(d))
{
flag = false;
break;
}
}
if(flag)
{
flag = true;
count++;
}
}
}
Console.WriteLine("Count : " + count);
Console.Read();
}
}
I'm trying to convert a sentence to pig latin but can't seem to get the correct output to work. For example the input
the rain in spain stays mainly in the plain yields an output of ethay ethay ethay with my current code whereas the expected output is ethay ainray inay ainspay aysstay ainlymay inay ethay ainplay
For those unfamiliar, the basic rules of pig latin are:
If the word begins with a consonant, take the beginning consonants up until the first vowel and move them to the end of the word. Then append ay at the very end. (so cricket would become icketcray)
If the word begins with a vowel, simply add ay to the end. (apple would become appleay)
If y is the first letter in the word, treat it as a consonant, otherwise it is used as a vowel. (young would become oungyay and system would become ystemsay)
My code is as follows:
import java.util.Scanner;
public class PigLatin{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String line = scan.next();
String piglatin = translateSentence(line);
System.out.println(piglatin);
}
public static String translateSentence(String line){
for (int i =0; i < line.length(); i++ ) {
char c = line.charAt(i);
//for loop to analyze each word
if (Character.isAlphabetic(c)) {
//if (i <='a' || i<='A' || i>='z' || i>='Z'){
String piglatin = translateword(line);
return piglatin;
}
}
return line;
}
public static String translateword(String line) {
Scanner scan = new Scanner(System.in);
int position = firstVowel(line);
String words = "";
String output = "";
for(int i = 0; i<line.length();i++){
words = "";
if (firstVowel(line) == 0) {
words = line + "-way";
} else if (firstVowel(line) == -1) {
words = line + "";
} else {
String first = line.substring(position);
String second = line.substring(0,position) + "ay";
words = first + second;
}
output = output + " " + words;
//words = "";
}
return output;
}
public static int firstVowel(String line) {
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) == 'a' || line.charAt(i) == 'e'
|| line.charAt(i) == 'i' || line.charAt(i) == 'o'
|| line.charAt(i) == 'u') {
return i;
}
}
return -1;
}
}
Any help is greatly appreciated, thank you.
first write a separate function to get list of words from line
public String[] getWords(String line) {
String list[]=new String[100];
int j=0;
int end;
end=line.indexOf(' ');
while (end!=-1) {
list[j]=line.substring(0, end);
line=line.substring(end+1,line.length());
j++;
end=line.indexOf(' ');
}
list[j]=line.substring(0,line.length());
return list;
}
then modify your translate line to call translate word multiple times, each time pass a single word.
Assuming your translateWord() returns a single correctly translated word. translateLine change in the following way:
if (Character.isAlphabetic(c)) {
String wordList[]=getWords(line);
String piglatin="";
int i=0;
while(!line[i].equals("")) {
piglatin = piglatin+translateword(word[i]);
i++;
}
return piglatin;
}
I am trying to figure out how to write a method that will remove letters in a
string based on another string. The method would end up like so:
removeLetter("file", "fe")
The only thing that should be returned is the string "il". So far I have something like this:
public class h
{
public static void main(String[] args)
{
String a="file";
String b="fe";
char letter;
int i;
int j;
for (letter = 'a'; letter <= 'z'; letter++)
{
for (i=0; i < a.length()-1; i++)
{
for (j=0; j < b.length()-1; j++) // This is the loop i get stuck on
{
char r = b.charAt(j);
char s = a.charAt(i);
if ( letter == r && letter == s);
System.out.print(r + " " + s);
}
}
}
}
}
I know the bottom part is wrong but I am not sure where to go from here.
You can do this with a regular expression:
a.replaceAll("[" + b + "]", "")
This works by constructing a character class like [fe], and replacing characters which match that with the empty string.
Of course, this is a bit of a hack, in that you can easily choose b such that it won't yield a valid regular expression. However, if you know that b will only ever contain letters, this would work.
Here's a pretty simple nested array using a flag boolean :
public static void main(String[] args) {
String a = "file";
String b = "f";
String c = "";
StringBuilder sb = new StringBuilder();
boolean contains;
for (int i = 0 ; i < a.length() ; i++){
contains = false;
for (int j = 0 ; j < b.length() ; j++){
if (a.charAt(i) == b.charAt(j)) contains = true;
}
if (!contains) sb.append(a.charAt(i));
}
System.out.println(sb);
}
It checks every char of the first word with the chars of the second and changes the flag to true if the char is contained in both.
If it is not the case, the char of the first word is added to the new String, if the contrary, nothing happens and we continue to the next char of the first String.
Let's remove all the vowels of this word : Supercalifragilisticexpialidocious
String a = "Supercalifragilisticexpialidocious";
String b = "aeiou";
Here's the output :
Sprclfrglstcxpldcs
Is there a way to remove all non alphabet character from a String without regex?
I'm trying to check if the String is a palindrome
This is what i tried so far.
public static boolean isPalindrome( String text )
{
int textLength = text.length() - 1;
String reformattedText = text.trim().toLowerCase();
for( int i = 0; i <= textLength; i++ )
{
if( reformattedText.charAt( i ) != reformattedText.charAt( textLength - i ) )
{
return false;
}
}
return true;
}
But if the input is:
System.out.println( isPalindrome( "Are we not pure? No sir! Panama’s moody"
+ "Noriega brags. It is garbage! Irony dooms a man; a prisoner up to new era." ) );
It should be true.
I'm really having a hard time thinking of how to remove or ignore those non alphabet characters on the String.
I would do something like this:
public static String justAlphaChars(String text) {
StringBuilder builder = new StringBuilder();
for (char ch : text.toCharArray())
if (Character.isAlphabetic(ch))
builder.append(ch);
return builder.toString();
}
Just tested method above in your example bellow and worked. Returned true.
System.out.println( isPalindrome( justAlphaChars ( "Are we not pure? No sir! Panama’s moody"
+ "Noriega brags. It is garbage! Irony dooms a man; a prisoner up to new era." ) ) );
OOPS. Java, not Python.
You can still use list-like access in Java, just a bit more work.
char[] letters = text.toCharArray();
int nletters = 0;
for (int i=0; i<letters.length; ++i) {
if (Character.isLetter(letters[i])
letters[nletters++] = Character.toUpperCase(letters[i]);
}
// print out letters in array:
System.out.print("letters only: ");
for (int i=0; i<nletters; ++i) {
System.out.print(letters[i]);
}
System.out.println();
Now use the first nletters positions only in the letters array, since those positions will hold the lowercased letters from the input. An example that just displays the remaining characters is included above.
Now write a loop to compare letters[0] with letters[nletters-1], letters[1] with letters[nletters-2], and so on. If all pairs are equal, you have a palindrome.
String removeNonAlpha(final String word) {
final StringBuilder result = new StringBuilder();
for (final char ch : word.toCharArray()) {
final int ascii = ch;
if (((ascii >= 65) && (ascii <= 90)) || ((ascii >= 97) && (ascii <= 122))) {
result.append(ch);
}
}
return result.toString();
}
Explanation:
The method will retrieve a string containing only A-Z and a-z characters.
I am simply verifying the ascii code for the given char.
Please refer to the ASCII code table
I am trying to see if there are spaces after a certain char, if there aren't I will count++ if there are then it won't, I have no idea how to do this! I am doing it in an if statement, and I know how to check for the letter but not if there are spaces afterwards. I tried this but it doesn't seem to work!
if ((letter == '#')&&(letter+1!='\t')&&(letter+1 != ' '))
In Java your letter variable of type char is not a pointer like in C. So doing letter+1 simply gives you the next letter (as in next in the character table, not your string) after #, which is $. So as a result your $ will never be equal neither to \t nor to .
You may want to get the next character the same way you are getter the character into letter - as a separate variable, and check that against the tab and space. Like so:
int position = 0;
char letter = mystring.charAt(position);
char next = mystring.charAt(position+1);
if (letter == '#' && next != '\t' && next != ' ')
This is of course very crude and prone to errors, but I hope it explains your current issue.
There are better ways to do what you are trying to do.
Have you try java regular expression?
String input = "# input for test";
Pattern pattern = Pattern.compile("#\\s");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("find");
}
Just iterate your string and collect the character before the space...
public class CharCheck {
public static void main( String[] args ) {
String string = "Check for spaces after a char";
List<Character> chars = new ArrayList<>( );
for(int i = 0; i < string.length(); i++) {
if( string.charAt( i ) == (' ') ) {
chars.add( string.charAt( i - 1 ) );
}
}
System.out.println("Characters with spaces after them :");
for(Character character : chars) {
System.out.print( character );
}
}
}
RESULT
Characters with spaces after them :
krsra