Trying to validate characters in string - Java - java

hoping I can get some help. I'm new here and a student developer.
I'm trying to validate a string to ensure it has only characters included in another string.
There is a string of random generated characters (12 in length) and the user inputs a word but must only use characters from the string.
I also need to repeat the user input until there is a valid input. so a loop is necessary. I have tried numerous approaches but for some reason can't get it right
The user input will be within the main class which then calls a method from another class.
My logic is to check if the characters from the user input do not match the characters in the randomLetters String then count. and while that value is greater than 0 then there is an invalid entry so the use should try again. however, what actually is happening is: no matter what the user inputs the code still continues to show that it is incorrect
Here is my code:
import java.lang.Math;
public class TestValidChar{
private String player1Guess;
private final String ALPHABET;
private String randomLetters;
private StringBuffer strBuff;
private String testValid;
private int validCounter;
public TestValidChar(){
player1Guess=" ";
player2Guess=" ";
ALPHABET = "abcdefghijklmnopqrstuvwxyz";
testValid = " ";
validCounter=0;
}
public void setPlayer1Guess(String player1Guess){
this.player1Guess=player1Guess.toLowerCase();
}
public void setPlayer2Guess(String player2Guess){
this.player2Guess=player2Guess.toLowerCase();
}
public void setRandomLetters(String randomLetters){
randomLetters=" ";
strBuff = new StringBuffer();
//for loop to create a string of 12 random letters -
for (int i = 0; i < 12; i++) {
// generate a random number between
// 0 to 25 (instead of 1-26 for lenght of alphabet)
int index = (int)(ALPHABET.length()* Math.random());
// add Character one by one to strBuff
strBuff.append(ALPHABET.charAt(index));
}//end for loop
randomLetters = strBuff.toString();
this.randomLetters=randomLetters;
}
public void compute(){
validCounter=0;
for(int i=0; i<player1Guess.length(); i++){
for(int j=0; j<randomLetters.length(); j++){
if(player1Guess.charAt(i)!=randomLetters.charAt(j)){
validCounter++;
}
}
}
}
public String getRandomLetters(){
return randomLetters;
}
public int getValidCounter(){
return validCounter;
}
}
and the app class:
import javax.swing.*;
public class TestApp{
public static void main(String[]args){
//data members
String player1Guess;
String player2Guess;
final String ALPHABET;
String randomLetters=" ";
int validCounter;
TestValidChar myTest = new TestValidChar();
myTest.setRandomLetters(randomLetters);
randomLetters=myTest.getRandomLetters();
player1Guess=JOptionPane.showInputDialog(null, " Enter word using these letters: " +randomLetters);
myTest.setPlayer1Guess(player1Guess);
myTest.compute();
validCounter=myTest.getValidCounter();
while(validCounter>0){
player1Guess=JOptionPane.showInputDialog(null, " Invalid Characters used. Use only " +randomLetters+ " " +validCounter);
myTest.compute();
validCounter=myTest.getValidCounter();
}
}
}

The core issue lies in the compute method
public void compute(){
validCounter=0;
for(int i=0; i<player1Guess.length(); i++){
for(int j=0; j<randomLetters.length(); j++){
if(player1Guess.charAt(i)!=randomLetters.charAt(j)){
validCounter++;
}
}
}
}
First of all it is ambiguous, there is a variable named validCounter but it seems you increment it when 2 characters do not match. It is very important for everyone involved in your code, especially you, of course, to provide meaningful names.
Try to watch step by step why this counter will not have the value you expect. Take for example "word" as a player1Guess and "drow" as randomLetters and iterate through the loops to see why it will increment a number of times, although you expect it not to and then update your logic accordingly.
If you want "validCounter" to increment only when a letter is not found in the "randomLetters" you could rename it to "invalidCounter" and try the following:
public void compute() {
invalidCounter = 0;
for (int i = 0; i < player1Guess.length(); i++) {
if (randomLetters.indexOf(player1Guess.charAt(i)) == -1) {
// indexOf returns -1 if char is not found
invalidCounter++;
}
}
}

I fix your code as follows:
public boolean compute() {
validCounter = 0;
for (int i = 0; i < player1Guess.length(); i++) {
for (int j = 0; j < randomLetters.length(); j++) {
if (player1Guess.charAt(i) == randomLetters.charAt(j)) {
// I found a match. The character at player1Guess[i] is ok
validCounter++;
break;
}
}
}
// if all characters are OK returns true.
return validCounter == player1Guess.length();
}

Related

Java Poem Palindrome Checker: Iterate through array matching elements in order

Currently trying to program a poem Palindrome checker. This is not for palindromes specifically, but that the array has words in the same order both ways. For example the following is a poem palindrome
Life-
imitates nature,
always moving, traveling continuously.
Continuously traveling, moving always,
nature imitates
life
My issue is iterating through the array to match the first and last elements, as currently it compares things in the wrong order.
My code is as follows:
import java.util.Scanner;
import java.io.*;
public class WordPalindromeTest {
public static void main(String[] args) {
System.out.println("This program determines if an entered sentence/word poem is a palindrome.");
Scanner input = new Scanner(System.in);
System.out.println("Please enter a string to determine if it is a palindrome: ");
while(input.hasNextLine()) {
String palin = input.nextLine();
if(palin.equals("quit")) {
break;
}
else {
boolean isPalin = isWordPalindrome(palin);
if(isPalin == true) {
System.out.println(palin + " is a palindrome!");
}
else
System.out.println(palin + " is NOT a palindrome!");
}
}
System.out.println("Goodbye!");
input.close();
}
public static boolean isWordPalindrome(String s) {
boolean isWordPal = false;
String lowerCase = s.toLowerCase();
String replaced = lowerCase.replaceAll("[^a-zA-Z0-9\\s]", "");
String words[] = replaced.split(" ");
for(int i = 0; i < words.length; i++) {
for(int j = 0; j < words.length; j++) {
if (words[i].equals(words[j]) && i != j) {
isWordPal = true;
}
else
isWordPal = false;
}
}
return isWordPal;
}
}
With the specific point in question being
public static boolean isWordPalindrome(String s) {
boolean isWordPal = false;
String lowerCase = s.toLowerCase();
String replaced = lowerCase.replaceAll("[^a-zA-Z0-9\\s]", "");
String words[] = replaced.split(" ");
for(int i = 0; i < words.length; i++) {
for(int j = 0; j < words.length; j++) {
if (words[i].equals(words[j]) && i != j) {
isWordPal = true;
}
else
isWordPal = false;
}
}
return isWordPal;
}
I am confused on how to properly set up the loop to compare the right elements. It should compare the first element to the last, the second to the second to last, etc. until the loop is finished. I realize I have it compare the first to the entire array before moving on.
This seems like a homework assignment so I won't give you a working solution. But this of it like this:
-You don't need two loops. You only need to compare the first to the last, the second to the second to last, etc. (Hint: if you subtract i-1 from the length of the Array you'll get the corresponding element to i that you need to compare to). Also you only need to iterate over half of the length of the Array
-If ever isWordPal becomes false, you need to return false. Otherwise it might get overwritten and at the end it will return true.

a program which identifies the differences between pairs of strings

My problem is that I need to identify characters which differ between the two given strings in a visually striking way. Output the two input strings on two lines, and then identify the differences on the line below using periods (for identical characters) and asterisks (for differing characters). For example:
ATCCGCTTAGAGGGATT
GTCCGTTTAGAAGGTTT
*....*.....*..*..
I have tried to write two string with each other but I dont know how to make the program check for every character in the string and see if those match
This is what I have done so far :/
System.out.println("String 1: ");
String var1 = Scanner.nextLine();
System.out.println("String 2: ");
String var2 = Scanner.nextLine();
if (same (var1, var2))
System.out.println(".........");
else
System.out.println("********");
public static boolean same (String var1, String var2){
if (var1.equals(var2))
{
return true;
}
else
{
return false;
}
Can anyone help me with this?
You need to loop through your Strings and compare characters one by one. To run through your list you can make a for-loop. Use an int as counter and use the method length() to obtain your string size.
for(int i=0; i<string1.length(); i++ {
// do stuff
}
Then since you have a counter going through all position of your string, you can obtain the character at a specific position in this string using the method charAt()
char char1 = string1.charAt(i);
Then compare the character to check if they are the same. If they are print a dot . if they're not print an asterisk *
if(char1 == char2) {
System.out.print(".");
} else {
System.out.print("*");
}
In the above part I supposed your two string have the same size. If it's not the case, you can first determine which one is the smallest (and so which is the biggest) :
String smallestString;
String biggestString;
if(string1.size() > string2.sise()) {
smallestString = string2;
biggestString = string1;
else {
smallestString = string1;
biggestString = string2;
}
Then make your for loop go through the smallest String, otherwise you will face IndexOutOfBoundsException.
for(int i=0; i<smallestString.length(); i++ {
// do stuff
}
And the end of this for loop print asterisks for the characters that left in the biggest String
for(int j=smallestString.length(); j<biggestString.length(); j++) {
System.out.print("*");
}
This is what I've come up with.Mind you there are better ways to do this and I've just written it with as much effort as you put in your question.
public class AskBetterQuestion{
public static void main(String[] args) {
// TODO Auto-generated method stub
String w1="ATCCGCTTAGAGGGATT";
String w2="GTCCGTTTAGAAGGTTT";
char[] first = w1.toCharArray();
char[] second = w2.toCharArray();
int minLength = Math.min(first.length, second.length);
char[] out=new char[minLength];
for(int i = 0; i < minLength; i++)
{
if (first[i] != second[i])
{
out[i]='.';
}
else out[i]='*';
}
System.out.println(w1);
System.out.println(w2);
System.out.print(out);
}
}

Combining three words into one?

I have to make a program which needs to generate three words of 10 letters, with each having 1st letter as UpperCase. Afterwards, I have to combine those three words into one word and that word again should have only its 1st letter as UpperCase.
So far I managed do to this:
public static void main(String[] args) {
new DZ05();
}
public DZ05() {
Random word = new Random();
for(int i = 0; i<= 10; i++) {
int x = word.nextInt(25)+97;
if(i==0) {
tekst1+= Character.toUpperCase((char) (x));
} else {
tekst1+= (char) (x);
}
}
for(int i = 0; i<= 10; i++) {
int x = word.nextInt(25)+97;
if(i==0) {
tekst2+= Character.toUpperCase((char) (x));
} else {
tekst2+= (char) (x);
}
}
for(int i = 0; i<= 10; i++) {
int x = word.nextInt(25)+97;
if(i==0) {
tekst3+= Character.toUpperCase((char) (x));
} else {
tekst3+= (char) (x);
}
}
System.out.println(tekst1);
System.out.println(tekst2);
System.out.println(tekst3);
And thats where I dont know what else to do
You should consider breaking the problem down into multiple methods, and have your main program call those methods.
For example, you could build something like:
private String randomWord(int length) { ... }
private String titleCase(String word) { ... }
Your main program could call them and be easier to follow:
String fiveLetterWord = randomWord(5);
String titleCasedWord = titleCase("threeConcatenatedWords");
I will make the assumption that tekst1, tekst2 and tekst3 are Strings, as this is not shown in the provided code.
Firstly, your for loops generate words with 11 not 10 letters. It should be:
for (int i = 0; i < 10; i++)
Now, there are various methods from the String class that you can use to achieve your goal. You can use String concatenation to combine the words:
String combinedWords = tekst1 + tekst2 + tekst3;
Use the String methods toLowerCase and substring to get all the letters except the first in lower case:
String lowerCaseChars = combinedWords.toLowerCase().substring(1);
Use the String method charAt to get the first letter:
char upperChar = combinedWords.charAt(0);
Finally, combining upperCharand lowerCaseChars gives you your desired result:
String result = upperChar + lowerCaseChars

Occurrences of each letter

this is the program that I have to write but I get this error,
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
50
Write a complete program using two arrays, upper and lower to keep the upper
And lower alphabet respectively.
Ask the user to enter string example:
This is a test from Jupiter. Soon you will see who is from
Jupiter!!! May be Dr. D.
Your program should parse the string and keep track of number of alphabet. Both arrays are indexed from 0 to 25. The logical way to do this is to use upper[0] to
Count the number of ‘A’, and upper[1] to count number of ‘B’ and so on. Likewise
For the lower array.
Output should look like:
A: 0 a:2
B: 0 b:0
.
.
.
Z:0 z:0
Code
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class Letter {
public static void main(String[] args) {
// this is get results
char[] chars = userEnters();
System.out.println();
System.out.println("Occurrences of each letter are:");
PrintArray(countLow(chars), countUp(chars));
}
public static char[] userEnters() {
String inputX = JOptionPane.showInputDialog("Enter line of text: ");
char[] chars = inputX.toCharArray();
return chars;
}
public static int[] countLow(char[] input) {
int[] counts = new int[26];
for (int i = 0; i < input.length; i++) {
counts[input[i] - 'a']++;
}
return counts;
}
public static int[] countUp(char[] input2) {
int[] countsUp = new int[26];
for (int i = 0; i < input2.length; i++) {
countsUp[input2[i] - 'A']++;
}
return countsUp;
}
public static void PrintArray(int[] counts, int[] countsUp) {
for (int i = 0; i < counts.length; i++) {
System.out.print(counts[i] + " " + (char) ('a' + i) + " ");
System.out.print(countsUp[i] + " " + (char) ('A' + i) + "\n");
}
}
}
If you enter a character that is not a large cap, countUp will throw an exception and if you enter a character that is not a small cap, countLow will throw an exception.
Example: if you call countLow on a A, you calculate 'A' - 'a' which returns -32 and a negative index is not allowed.
You need to review your logic and call either countLow or countUp depending on the case of the letter and filter invalid characters out.
Or refactor the whole thing and use a char[52] for example where you hold both small and large caps.
I Hope you don't mind I did refactor your code a bit.
Please have a look at this alterantive solution to your problem and then read the comments at the bottom of the answer.
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.JOptionPane;
public class LetterCounter {
//Hash maps don't allow duplication.
//The letter will be the Key and the repetitions the value(Your goal!)
private Map<Character, Integer> resultsMap = new HashMap<Character, Integer>();
public static void main(String[] args) {
LetterCounter letterCounter = new LetterCounter();
letterCounter.fillMap();
letterCounter.showMapContents();
}
private void showMapContents() {
for (Entry<Character, Integer> entry : resultsMap.entrySet())
{
System.out.println("'" + entry.getKey() + "' - " + entry.getValue() + " times");
}
}
private void fillMap() {
char[] userInputAsArray = getUserInputAsLetterArray();
for (int currentLetter = 0; currentLetter < userInputAsArray.length; currentLetter++) {
int count = getOccurences(userInputAsArray[currentLetter],userInputAsArray);
resultsMap.put(userInputAsArray[currentLetter], count);
}
}
private int getOccurences(int letter, char[] userInputAsArray) {
int counter = 0;
for (int currentIndex = 0; currentIndex < userInputAsArray.length; currentIndex++) {
if(userInputAsArray[currentIndex] == letter)
counter++;
}
return counter;
}
public char[] getUserInputAsLetterArray() {
String userInput = JOptionPane.showInputDialog("Enter line of text: ");
char[] chars = userInput.toCharArray();
return chars;
}
}
Whenever you want to do an exercise where you need to manipulate data, you should pick the best data structure for the job. In your case, I think the hash map could be interesting because it avoids duplicates and will do a big part of the job for you. Find a very good cheat sheet in this link: http://www.janeve.me/articles/which-java-collection-to-use
I noticed that you used a lot static and that is not a very Object Oriented thing to do. As an alternative, when you want to just on the run do some quick examples like this one, you can just initialize the class inside itself.
I hope this was useful.
You should probably consider moving from arrays to a more complex and powerful data structure like Map<Character,Integer>.
With that data structure the code you need would look something like
public Map<Character,Integer> countOccurrencies(String inputString){
Map<Character,Integer> occurrencies = new HashMap<Character,Integer>();
for(Character c : inputString){
if(occurrencies.containsKey(c)){
occurrencies.put(c, occurrencies.containsKey(c) + 1);
} else {
occurrencies.put(c, 1);
}
}
return occurrencies;
}
Answer in java:
Here, countOfOccurances("pppggggkkkkpgaaaa") gives you count of occurrences of each character from a String
public static void countOfOccurances(String mainStr)
{
String temp = "";
for (int i = 0 ; i < mainStr.length();i++)
{
CharSequence ch = String.valueOf(mainStr.charAt(i));
temp=mainStr.replace(ch, "");
int count = (mainStr.length()-temp.length());
System.out.println(ch+" = "+count);
mainStr = temp;
i = -1;
}
}
Output of method:
p = 4
g = 5
k = 4
a = 4

write a code to find the number of words in a string using methods

I've been looking and I can't find anywhere how to write a word count using 3 methods. Here is what the code looks like so far. I'm lost on how to use the methods. I can do this without using different methods and just using one. Please help!!!
public static void main(String[] args) {
Scanner in = new Scanner (System.in);
System.out.print("Enter a string: ");
String s = in.nextLine();
if (s.length() > 0)
{
getInputString(s);
}
else
{
System.out.println("ERROR - string must not be empty.");
System.out.print("Enter a string: ");
s = in.nextLine();
}
// Fill in the body with your code
}
// Given a Scanner, prompt the user for a String. If the user enters an empty
// String, report an error message and ask for a non-empty String. Return the
// String to the calling program.
private static String getInputString(String s) {
int count = getWordCount();
while (int i = 0; i < s.length(); i++)
{
if (s.charAt(i) == " ")
{
count ++;
}
}
getWordCount(count);
// Fill in the body
// NOTE: Do not declare a Scanner in the body of this method.
}
// Given a String return the number of words in the String. A word is a sequence of
// characters with no spaces. Write this method so that the function call:
// int count = getWordCount("The quick brown fox jumped");
// results in count having a value of 5. You will call this method from the main method.
// For this assignment you may assume that
// words will be separated by exactly one space.
private static int getWordCount(String input) {
// Fill in the body
}
}
EDIT:
I have changed the code to
private static String getInputString(String s) {
String words = getWordCount(s);
return words.length();
}
private static int getWordCount(String s) {
return s.split(" ");
}
But I can't get the string convert to integer.
You have read the name of the method, and look at the comments to decide what should be implemented inside the method, and the values it should return.
The getInputString method signature should be:
private static String getInputString(Scanner s) {
String inputString = "";
// read the input string from system in
// ....
return inputString;
}
The getWordCount method signature should be:
private static int getWordCount(String input) {
int wordCount = 0;
// count the number of words in the input String
// ...
return wordCount;
}
The main method should look something like this:
public static void main(String[] args) {
// instantiate the Scanner variable
// call the getInputString method to ... you guessed it ... get the input string
// call the getWordCount method to get the word count
// Display the word count
}
count=1 //last word must be counted
for(int i=0;i<s.length();i++)
{
ch=s.charAt(i);
if(ch==' ')
{
count++;
}
}
Use trim() and split() on 1-n whitespace chars:
private static int getWordCount(String s) {
return s.trim().split("\\s+").length;
}
The call to trim() is necessary, otherwise you'll get one extra "word" if there is leading spaces in the string.
The parameter "\\s+" is necessary to count multiple spaces as a single word separator. \s is the regex for "whitespace". + is regex for "1 or more".
What you need to do is, count the number of spaces in the string. That is the number of words in the string.
You will see your count will be off by 1, but after some pondering and bug hunting you will figure out why.
Happy learning!
You can do this by :
private static int getWordCount(String input) {
return input.split("\\s+").length;
}
Use String.split() method like :
String[] words = s.split("\\s+");
int wordCount = words.length;
I'm not sure what trouble you're having with methods but I dont think you need more than one, try this: it uses split to split up the words in a string, and you can chose the delimeters
String sentence = "This is a sentence.";
String[] words = sentence.split(" ");
for (String word : words) {
System.out.println(word);
}
then you can do:
numberOfWords = words.length();
if you want to use 3 methods, you can call a method from your main() method that does this for you, for example:
public String getInputString() {
Scanner in = new Scanner (System.in);
System.out.print("Enter a string: ");
String s = in.nextLine();
if (s.length() > 0) {
return s;
} else {
System.out.println("ERROR - string must not be empty.");
System.out.print("Enter a string: ");
return getInputString();
}
}
public int wordCount(String s) {
words = splitString(s)
return words.length();
}
public String[] splitString(String s) {
return s.split(" ");
}
Based on your code i think this is what you're trying to do:
private static int getWordCount(String input) {
int count = 0;
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == ' ') {
count++;
}
}
return count;
}
Here's what I've done:
I've moved the code you were 'playing' with into the right method (getWordCount).
Corrected the loop you were trying to use (I think you have for and while loops confused)
Fixed your check for the space character (' ' not " ")
There is a bug in this code which you'll need to work out how to fix:
getWordCount("How are you"); will return 2 when it should be 3
getWordCount(""); will return 0
getWordCount("Hello"); will return 0 when it should be 1
Good luck!
Better use simple function of spilt() with arguments as space
int n= str.split(" ").length;
public static int Repeat_Words(String arg1,String arg2)
{
//It find number of words can be formed from a given string
if(arg1.length() < 1 || arg2.length() < 1)
return 0;
int no_words = 99999;
char[] str1 = arg1.toCharArray();
char[] str2 = arg2.toCharArray();
for(int x = 0; x < str1.length; x++)
{
int temp = 0;
for(int y = 0; y < str2.length; y++)
{
if(str1[x] == str2[y])
temp++;
}
if(temp == 0)
return 0;
if(no_words > temp)
no_words = temp;
temp = 0;
}
return no_words;
}

Categories

Resources