Java String Shortener - java

The instructions for the assignment are:
In many methods of communication throughout the last century, from telegrams to SMS messages to tweets, there is a benefit to reducing message length: either the number of characters is limited or using more characters incurs extra cost. Your job in this assignment is to write a program which takes a message as a string and reduces the number of characters it uses in a set way.
The first thing your program will do is ask the user to type a message which will be stored as a String. If the message contains less than 10 characters the program should print “This doesn’t need shortening!” and finish.
Otherwise, the message should be immediately converted to lowercase as this will make processing much easier. The program should then create a string in which every vowel (a, e, i, o, and u) from the message is removed unless the vowel is at the very start of a word (i.e., it is preceded by a space or is the first letter of the message). The program should also remove every repeated non-vowel character (i.e., if a character appears several times in a row it should only appear once at that location).
Finally, the program should output the shortened message, the number of vowels removed, the number of repeated non-vowel characters removed, and how much shorter the shortened message is than the original message. The exact format in which the program should print this information is shown in the sample runs.
my code is:
import java.util.Scanner;
import java.lang.Math;
class Main {
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Type the message to be shortened");
String message = scan.nextLine();
int messagelength = message.length();
String shortmsg = "";
int vowel = 0;
if (messagelength < 10)
{
System.out.print("\nThis doesn't need shortening!");
}
else
{
message = message.toLowerCase();
for(int i = 0; i < message.length(); i++)
{
if (i == 0)
{
shortmsg = "" + message.substring(0,1);
}
else
{
if(message.charAt(i - 1) != ' '){
if (
message.charAt(i) != 'a' &&
message.charAt(i) != 'e' &&
message.charAt(i) != 'o' &&
message.charAt(i) != 'u' &&
message.charAt(i) != 'i')
{
shortmsg += message.charAt(i);
}
else
{
vowel++;
}
}}
}
System.out.println("Shortened message: " + shortmsg);
System.out.println("Vowels removed: " + vowel);
System.out.println("Total characters saved: " + vowel);
}}}
when I put in "Please shorten this message" the output is "Shortened message: pls hrtn hs ssg"
I have been working on this assignment for days and I am failing the class because of it can someone please guide me to the correct answer.
Thanks for your help.

import java.util.Scanner;
import java.lang.Math;
class Main{
public static void main (String str[]){
Scanner scan = new Scanner(System.in);
System.out.println("Type the message to be shortened.");
String message = scan.nextLine();
int messageLength = message.length();
int messageVowels = 0;
String newMessage = "";
int repeat = 0;
int total = 0;
if (messageLength < 10) {
System.out.println("This doesn't need shortening!");
} else {
message = message.toLowerCase();
newMessage = newMessage + message.charAt(0);
for (int i = 1; i < messageLength; i++) {
if (message.charAt(i)== 'a' ||
message.charAt(i)== 'e' ||
message.charAt(i)== 'i' ||
message.charAt(i)== 'o' ||
message.charAt(i)== 'u') {
if (message.charAt(i-1) == ' '){
newMessage = newMessage + message.charAt(i);
}
else {
messageVowels++;
}
} else {
if (message.charAt(i) != message.charAt(i-1)) {
newMessage = newMessage + message.charAt(i);
}
else {
repeat++;
}
}
}
total = repeat + messageVowels;
System.out.println("Shortened message: " + newMessage);
System.out.println("Repeated letters removed: " + repeat);
System.out.println("Vowels removed: " + messageVowels);
System.out.println("Total characters saved: " + total);
}
}
}

Related

guessing letters in a randomized word and printing a progress result to the User. Cannot figure out how [Java]

I am currently trying to right a rough draft code block for an object oriented hangman assignment I have to tackle. I know that similar questions have been asked but I didn't find a solution for the specific way i'm attempting to write this (which quite possibly is actual shite).
The way the code is intended to work is as follows.
Word_to_guess pulls a word from the array wordBank[] which contains 19 different fruits and 1 pickle (this is just to entertain my professor).
Then, the following While loop checks if "noSuccess" has been falsified, while it remains true the loop asks for character input from the user as a guess.
then the nested for loop iterates through the length of word_to_guess to check if Characters at index i match character c which has been set to userGuess.charAt(0) (in case the user enters more than 1 letter restricting their guess to the first letter in the string they might enter).
now this is where I'm having my issues. I don't know how to use the .replace method to fill in spots with specific characters and store newWord for each iteration of the for loop and have it print a progress report to the user as they guess so that they can keep track of their guesses. I had attempted to use the following statement
newWord = newWord.replace(newWord.CharAt(i), c) but this did not work and caused a compiling error stating that the index could not be found. Which i didn't understand and still don't.
the final if statement checks if noSuccess has been falsified which is defined by booleancheck.contentEquals(word_to_guess)
booleancheck is defined by newWord without any spaces between characters.
If anyone can lend me a hand in sorting out that portion of the code or any other parts that look iffy I'd greatly appreciate it.
Thank you so much!
Alex
word_to_guess = wordBank[num];
boolean noSuccess = true;
while(noSuccess)
{
System.out.println("Enter your guess: ");
System.out.println("letters used - " + lettersUsed);
userGuess = keyboard.nextLine();
c = userGuess.charAt(0);
for(int i = 0; i < word_to_guess.length(); i++)
{
if(word_to_guess.charAt(i) == c)
{
if(newWord.charAt(i) == ' ')
{
newWord = newWord.replace(' ', c);
}
else if(newWord.charAt(i) == '_')
{
newWord = newWord.replace('_', c);
}
}
else
newWord = newWord.replace(' ', '_');
}
System.out.println(newWord);
counter ++;
lettersUsed = lettersUsed + c;
System.out.println("letters used - " + lettersUsed);
String booleanCheck = newWord.replaceAll("\\s+","");
if(booleanCheck.contentEquals(word_to_guess ) && counter > 1)
{
noSuccess = false;
System.out.println("Great job, you guessed the right letters!");
}
Update #1:
I came up with the following code:
for(int i = 0; i < word_to_guess.length(); i++)
{
if(word_to_guess.charAt(i) == c)
{
strProg.setCharAt(i, c);
}
else
{
strProg.setCharAt(i, '_');
}
newWord = strProg.toString();
}
but i'm not sure what I'm doing wrong with the .toString() method because each iteration replaces the previous progress with "_" instead of being additive.
Update: #2
Edit to the previous update, I read that using StringBuilder in this instance is better than StringBuffer. I also discovered that the append and insert methods are available to the StringBuilder object.
This string object is located outside of the while loop the for loop is in.
String newWord = String.join("", Collections.nCopies(word_to_guess.length(),
" "));
this is inside the while loop.
StringBuilder strProg = new StringBuilder(newWord);
for(int i = 0; i < word_to_guess.length(); i++)
{
if(word_to_guess.charAt(i) == c)
{
strProg.insert(i, c);
}
else if(word_to_guess.charAt(i) != c && newWord.charAt(i) == '_')
{
strProg.delete(i, i);
}
else
{
strProg.insert(i, '_');
}
}
the .insert method is resulting in a much longer string. I don't know what to do now.
//The bugs was on replace method: I used a naive way to fix it
//Maybe you need also to check your initialization ...
public void hangman(){
String word_to_guess = "pickle";//wordBank[num];
boolean noSuccess = true;
//start: initializations
char c;
String lettersUsed = "";
String userGuess;
Scanner keyboard = new Scanner(System.in);
int counter=0;
//end: initializations
String newWord = word_to_guess.replaceAll("(?s).", " ");
while(noSuccess)
{
System.out.println("Enter your guess: ");
System.out.println("letters used: " + lettersUsed);
userGuess = keyboard.nextLine();
//sanity check: To ignore empty entry
if(userGuess.isEmpty())
continue;
c = userGuess.charAt(0);
for(int i = 0; i < word_to_guess.length(); i++)
{
if(word_to_guess.charAt(i) == c)
{
if(newWord.charAt(i) == ' ')
{
newWord = newWord.substring(0,i) + c + newWord.substring(i+1); //newWord = newWord.replace(' ', c);
}
else if(newWord.charAt(i) == '_')
{
newWord = newWord.substring(0,i) + c + newWord.substring(i+1);//newWord.replace('_', c);
}
}
else
newWord = newWord.replace(' ', '_');
}
System.out.println("New Word: "+newWord);
counter ++;
lettersUsed = lettersUsed + c;
System.out.println("letters used: " + lettersUsed);
String booleanCheck = newWord.replaceAll("\\s+","");
System.out.println("Check: "+booleanCheck);
if(booleanCheck.contentEquals(word_to_guess ) && counter > 1)
{
noSuccess = false;
System.out.println("Great job, you guessed the right letters!");
}
}
}

User string input. Counting characters

My code works except I have to make it pass some Junit test. It passes all but one. It passes when the character enters nothing, enters upper case, lower case, or a mix of the two, and it works when the enter Hello World!
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] textArray = new int[26];
System.out.print("Enter text: ");
readText(input, textArray);
}
public static void readText(Scanner input, int[]text){
char letter = 0;
if (input.hasNext() == false) {
System.out.println();
}
else {
while (input.hasNext()) {
String a = input.nextLine();
for (int i = 0; i < a.length(); i++) {
letter = a.charAt(i);
if (letter >= 'A' && letter <= 'Z') {
text[letter-65] = (text[letter-65]) + 1;
}
else if (letter >= 'a' && letter <= 'z') {
text[(letter - 32) - 65] = (text[(letter - 32) - 65]) + 1;
}
else if (letter == ' ') {
System.out.print("");
}
else {
System.out.print("");
}
}
}
}
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"};
for (int y = 0; y < text.length; y++) {
if (text[y] > 0) {
System.out.println(alphabet[y] + ": " + text[y]);
}
}
}
The Junit tests this input: 1 2 3%n! ? >%n:) !!%n
The expected output is
Enter text:
//empty line here
But instead the output from my code is
Enter text: //with no line after
I'm not sure how to get the extra line after without ruining my other junit tests. I tried one way and it worked but then my Hello World didn't work properly.
And example of when its working:
When I hit run the console will say
Enter text:
I have a Scanner input so the user will enter some words and it will look like this in console
Enter text: sOme wordS
Then it will count the number of times each letter was used and print that to console like this
Enter text: sOme wordS
D: 1
E: 1
M: 1
O: 2
R: 1
S: 2
W: 1
If I don't enter anything when asked and just hit the enter key the output is
Enter text:
//empty line here
But when I enter
Enter text: 1 2 3
? ! >
:) !!
The output doesn't add an extra line at the end.
Try using System.out.println("Enter text: "); instead of System.out.print("Enter text: ");
Update: After getting clarified your requirement I propose to use the following code.
public static void readText(Scanner input, int[]text){
char letter = 0;
while (input.hasNext()) {
String a = input.nextLine();
for (int i = 0; i < a.length(); i++) {
letter = a.charAt(i);
if (letter >= 'A' && letter <= 'Z') {
text[letter-65] = (text[letter-65]) + 1;
}
else if (letter >= 'a' && letter <= 'z') {
text[(letter - 32) - 65] = (text[(letter - 32) - 65]) + 1;
}
else if (letter == ' ') {
System.out.print("");
}
else {
System.out.print("");
}
}
}
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"};
boolean emptyOutput = true;
for (int y = 0; y < text.length; y++) {
if (text[y] > 0) {
System.out.println(alphabet[y] + ": " + text[y]);
emptyOutput = false;
}
}
if (emptyOutput) {
System.out.println();
}
}

Why won't my code run second time?

I'm having a problem with some code that I'm doing for homework where it won't repeat when I enter the word for the second time. I'm fairly new to Java so any help would be appreciated. Thanks
class Main
{
public static void main( String args[] )
{
System.out.print( "#Please enter a word : " );
String word = BIO.getString();
int i, length, vowels = 0;
String j;
length = word.length();
for (i = 0; i < length; i++)
{
j = word.substring(i, i + 1);
if (j.equalsIgnoreCase("a") == true)
vowels++;
else if (j.equalsIgnoreCase("e") == true)
vowels++;
else if (j.equalsIgnoreCase("i") == true)
vowels++;
else if (j.equalsIgnoreCase("o") == true)
vowels++;
else if (j.equalsIgnoreCase("u") == true)
vowels++;
}
System.out.print("[ " + vowels + "] vowels in " + "\""+word+"\"");
System.out.print("\n");
System.out.print("#Please enter a word : ");
word = BIO.getString();
}
}
To get the result you expect, you should nest your code inside a loop. Like this:
class Main
{
public static void main( String args[] )
{
System.out.print( "#Please enter a word : " );
String word = BIO.getString();
while(!word.equals("QUIT")){
int i, length, vowels = 0;
String j;
length = word.length();
for (i = 0; i < length; i++)
{
j = word.substring(i, i + 1);
if (j.equalsIgnoreCase("a") == true)
vowels++;
else if (j.equalsIgnoreCase("e") == true)
vowels++;
else if (j.equalsIgnoreCase("i") == true)
vowels++;
else if (j.equalsIgnoreCase("o") == true)
vowels++;
else if (j.equalsIgnoreCase("u") == true)
vowels++;
}
System.out.print("[ " + vowels + "] vowels in " + "\""+word+"\"");
System.out.print("\n");
System.out.print("#Please enter a word : ");
word = BIO.getString();
}
}
That way, your code will loop until you enter the word QUIT.
After the second input executes the program terminates. Use a while(true) block with some sort of special input (like "quit" or an empty string) to break the loop.
Do while loop is the best way to achieve what you want to here ! As mentioned above, you have not included your
System.out.print("#Please enter a word : ");
word = BIO.getString();
part in any type of loop. SO you can't expect the code to run otherwise. Include it in a do-while and you should be doing well. A well modified example is already answered above.

Tweet validation in Java

I have to create a program that accepts a "tweet" from a user and validates it. First it tests to make sure it is less than 140 characters.
If it is valid, it counts the number of hashtags (#), attribution symbols (#), and links ("http://) are in the string, then prints them out. My program works for hashtags and attributions, but not links. How can I fix this code so that it works?
import java.util.Scanner;
class Testing {
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
System.out.println("Please enter a tweet: ");
String input = scan.nextLine();
int length = input.length();
int count = 0;
int hashtags = 0, attributions = 0, links = 0;
char letter;
if (length > 140) {
System.out.println("Excess characters: " + (length - 140));
} else {
while (count < length) {
letter = input.charAt(count);
if (letter =='#') {
hashtags++;
count++;
}
if (letter == '#') {
attributions++;
count++;
}
if (letter == 'h') {
String test = input.substring(count,count+6);
test = test.toLowerCase();
if (test == "http://") {
links++;
count++;
} else {
count++;
}
} else {
count ++;
}
}
System.out.println("Length Correct");
System.out.println("Number of Hashtags: " + hashtags);
System.out.println("Number of Attributions: " + attributions);
System.out.println("Number of Links: " + links);
}
}
I think your code will not work with link like http://test.com/ingex.php?p=1#section. Use regular expressions instead of if () else {} if () else {}. And keep in mind: there is no token(mention, hashtag, link) which contains other token.
import java.util.Scanner;
class Testing
{
public static void main(String[] args)
{
Scanner scan = new Scanner (System.in);
System.out.println("Please enter a tweet: ");
String input = scan.nextLine();
int length = input.length();
int count = 0;
int hashtags = 0, attributions = 0, links = 0;
char letter;
if (length > 140)
{
System.out.println("Excess characters: " + (length - 140));
}
else
{
while (count < length)
{
letter = input.charAt(count);
if (letter =='#')
{
hashtags ++;
count ++;
}
if (letter == '#')
{
attributions ++;
count ++;
}
if (letter == 'h')
{
//String test = input.substring(count,count+6);
//test = test.toLowerCase();
if (input.startsWith("http://", count))
{
links ++;
count++;
}
else
{
count++;
}
}
else
{
count ++;
}
}
System.out.println("Length Correct");
System.out.println("Number of Hashtags: " + hashtags);
System.out.println("Number of Attributions: " + attributions);
System.out.println("Number of Links: " + links);
}
}
}
I changed your code in a few ways, the biggest being that instead of the == you had for checking if the links start with "http://". I also used startsWith(String s, int index) because like #Robin said, anything starting with an h would probably mess up your program.
I also used count to specify where it should start, basically the index part of you parameter
You may find additional functions and documentation in the Strings class javadoc of use.

String index out of bounds? (Java, substring loop)

This program I'm making for a COSC course isn't compiling right, I keep getting the error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 2
at java.lang.String.substring(String.java:1765)
at VowelCount.main(VowelCount.java:13)
Here's my code:
import java.util.Scanner;
public class VowelCount {
public static void main(String[] args) {
int a = 0, e = 0, i = 0, o = 0, u = 0, count = 0;
String input, letter;
Scanner scan = new Scanner (System.in);
System.out.println ("Please enter a string: ");
input = scan.nextLine();
while (count <= input.length() ) {
letter = input.substring(count, (count + 1));
if (letter == "a") {
a++; }
if (letter == "e") {
e++; }
if (letter == "i") {
i++; }
if (letter == "o") {
o++; }
if (letter == "u") {
u++; }
count++;
}
System.out.println ("There are " + a + " a's.");
System.out.println ("There are " + e + " e's.");
System.out.println ("There are " + i + " i's.");
System.out.println ("There are " + o + " o's.");
System.out.println ("There are " + u + " u's.");
}
}
To my knowledge this should work, but why doesn't it? Any help would be great. Thank you!
You may need to take out the = in the line
while (count <= input.length() ) {
and make it
while (count < input.length() ) {
because it is causing the substring to read beyond the length of the string.
===============
But I'll add a few extra bits of advice even though its not asked for:
do not use == to compare strings, use
letter.equals("a")
instead. Or even better, try using
char c = input.charAt(count);
to get the current character then compare like this:
c == 'a'
I think your loop condition should be count < input.length. Right now, the last iteration runs with count == length, so your substring call is given a start index after the last character in the string, which is illegal. These type of boundary errors are very common when writing such loops, so it's always good to double- and triple-check your loop conditions when you encounter a bug like this.
Also, comparing strings with the == operator usually won't do what you want. That compares whether or not the two variables reference the same object. Instead, you want to test string1.equals(string2), which compares the contents of the two strings.
Removing the equal sign should fix that.
while (count < input.length()) {
and since you want to get a single character, you should do this:
substr(count,1)
because the 2nd parameter is actually length, not index.
Fixed it with help from everyone, and especially Vincent. Thank you! Runs wonderfully.
import java.util.Scanner;
public class VowelCount {
public static void main(String[] args) {
int a = 0, e = 0, i = 0, o = 0, u = 0, count = 0;
String input;
char letter;
Scanner scan = new Scanner (System.in);
System.out.print ("Please enter a string: ");
input = scan.nextLine();
while (count < input.length() ) {
letter = input.charAt (count);
if (letter == 'a')
a++;
if (letter == 'e')
e++;
if (letter == 'i')
i++;
if (letter == 'o')
o++;
if (letter == 'u')
u++;
count++;
}
System.out.println ("There are " + a + " a's.");
System.out.println ("There are " + e + " e's.");
System.out.println ("There are " + i + " i's.");
System.out.println ("There are " + o + " o's.");
System.out.println ("There are " + u + " u's.");
}
}
Before loop,try below
if(input.length()>0){
//you code
}

Categories

Resources