Hello I'm writing a code that asks the user for a tweet then tells the user if the tweet is the correct length and how many #'s #'s and links that are in it but everytime I run this I get the error string index out or range: 7. Any ideas?
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 ("Please enter a tweet: ");
String tweet = scan.nextLine();
int hashtags = 0;
int attributions = 0;
int links = 0;
if (tweet.length() > 140) {
int excess = tweet.length()-140;
System.out.println ("Excess Characters: " + excess);
} else {
System.out.println ("Length Correct.");
while (tweet.length() <= 140) {
if (tweet.charAt(0) == '#'){
hashtags ++;
}
if (tweet.charAt(0) == '#'){
attributions ++;
}
if (tweet.substring(0,8) == "http://") {
links ++;
}
tweet = tweet.substring(1);
}
System.out.println ("Number of Hashtags: " + hashtags);
System.out.println ("Number of Attributions: " + attributions);
System.out.println ("Number of Links: " + links);
}
}
}
Two problems, at least. The first is that you should not use substring on a string that's too short. It's far better to use String.startsWith:
if (tweet.startsWith("http://")) ...
so that you don't have to even worry about the length of the string, or getting your character count wrong, or having it fail because you used == rather than String.equals() :-)
Secondly, regarding the following code:
while (tweet.length() <= 140) {
:
tweet = tweet.substring(1);
}
That's going to keep going once your string is empty, simply because zero (and every negative number for that matter) is less than 140.
And, of course, doing something like tweet.charAt(0) on an empty string is going to give you a bit of a problem, similar to your use of substring. You need to re-examine your terminating condition for the loop, making it something like:
while (tweet.length() > 0) {
The first problem is that you're trying to get an 8-length substring of the tweet string without knowing how long the tweet is. What if the tweet is only 6 characters? If it is, you get an index out of bounds exception because you're looking two indices past where the array ends.
You should add a conditional guard:
if (tweet.length() >= 8 && tweet.substring(0,8).equals("http://")) {
links++;
}
The && operator means that tweet.substring() will never be checked if the length of the string is less than 8, so you avoid stepping out of bounds.
The second problem is that, even once you add that condtional guard, what you're doing doesn't make any sense. The length of the string returned by substring(beginIndex, endIndex) is equal to endIndex - beginIndex, or 8 in this case. The string "http://" is only seven letters, so it's logically impossible for an 8-character string to ever equal it. Use the startsWith() function instead of substring from the 0 position:
The line from before should look like so:
if (tweet.startsWith("http://")) {
links++;
}
You should definitely use a for loop instead:
String string= "hello";
for (int i = 0; i < string.length(); ++i)
{
if (string.charAt( i ) == '#')
{
//do something
}
}
That will insure that you traverse the entire string correctly.
Secondly, you need to make sure that the substring(0, 8) is inbounds before you assume. That is probably what's causing your error in some test cases.
Related
I am trying to create a Java program for my AP Computer Science class that asks the user for a string and tests whether or not the string is a palindrome or not. The teacher specifically told us to not do the project by building the reversal of the string and testing it to see if it matches. I know how to do it while building the reversal but I can't think of another way to do it.
import java.util.*;
public class mondayassignment
{
public static void main(String args[])
{
Scanner scan = new Scanner(System.in);
System.out.print("Enter a String: ");
String s = scan.nextLine();
while(s.indexOf(" ") >= 0)
{
s = s.substring(0, s.indexOf(" ")) +
s.substring(s.indexOf(" ") + 1);
}
System.out.println("Spaces Removed:");
System.out.println(s);
String reverse="";
for(int pos = 0; pos < s.length(); pos++)
{
reverse = s.substring(pos, pos + 1) + reverse ;
}
System.out.println("Reverse Of The String You Inputed Is:" );
System.out.println(reverse);
System.out.println("Testing For Palindrome:");
if (reverse.equals(s))
{
System.out.println(s + " " + "is a palindrome" );
}
else {
System.out.println(s + " " + "is not a palindrome" );
}
}
}
Can someone help me create a code that does it without building the reversal of the string? Many solutions I've found online uses boolean and char but the thing is, is that I haven't learn those yet. I've only learned double int and string. SO would there be a way without using boolean and char? I don't think my teacher wants us using boolean and char either because we have never discussed them.
When you visually confirm whether a word is a palindrome or not, usually you would just check the characters from either end and start moving inwards.
So really that's two steps:
Check the end bits of the char if they're the same. If they aren't, it's not a palindrome, otherwise, next step
Move inwards from both ends, and repeat #1 till there are 1 or 0 characters left to be checked. (Hint: If you can't use chars, maybe try using a single character string :) )
Compare the string char starting from head and tail. If all the letters are equal till the middle of the string it's palindrome.
boolean palindrome(string str){
for(int i = 0 ; i < str.lenght()/2 ; i++) {
if (str.charAt(i) != str.charAt(str.lenght() - i )
return false;
}
return true;
}
package paintadvance;
import java.util.Scanner;
class Palindrome_without_reverse{
public static void main(String[] ishan_vimukthi_is_my_name) {
Scanner scan= new Scanner(System.in);
String string="";
/*while loop to keep running the programme unlit user need it to end*/
while (true) {
System.out.println("Enter string for palindrome check");
string=scan.nextLine();
/*this is for exiting the programme. If needed for user just type
"exit".It's not casesensitive that means "EXIT" is also ok.*/
if (string.equalsIgnoreCase("exit")) {System.out.println("Programme closed"); System.exit(0); }
/*get the length of string to a int variable */
int length=string.length();
/*get mid point of string in eg:- "aasaa" midpoint is letter "s" that means 2 when count from 0 .
We can get it from dividing string length from 2.Because we use int we will get 2 as the answer. */
int midpoint=length/2;
boolean ispalindrome=true;
String x="";
String y="";
/*check length is odd or even eg:- "aasaa" is odd "aassaa" is even*/
if (length%2==1) {
/*if you want to see the method. uncomment this and understand it.
System.out.println("odd string");
System.out.println(string.substring(midpoint,string.length())+" X part");
System.out.println(string.substring(0, midpoint+1)+" Y part");*/
x =string.substring(midpoint,string.length());
y=string.substring(0, midpoint+1);
}else{
/*if you want to see the method. uncomment this and understand it.
System.out.println("even string");
System.out.println(string.substring(midpoint,string.length())+" X part");
System.out.println(string.substring(0, midpoint)+" Y part");*/
x=string.substring(midpoint,string.length());
y=string.substring(0, midpoint);
}
int ylength=y.length()-1;
int ylength_end=y.length();
aa: for (int i = 0; i < x.length(); i++) {
/* by this code we compare each
string part of both x and y strings
in eg:- aasaa x=saa y=aas
we compair 0,1 of x and 2,3 of y
and keep going.this is not a reversal but this is comparing x and y parts
if its not equal we assign ispalindrome false if its equal it will be in true state
*/
if ( !(x.substring(i, i+1).equals( y.substring(ylength--, ylength_end--)))) {
ispalindrome=false;
}
}
/* after for loop We check string is a palindrome or not */
if (ispalindrome) { System.out.println("This is a palindrome");}else{ System.out.println("Not a palindrome");}
}
}
}
Alright, so for a class I am taking I have to make a program that tests tweets. It asks you to input a tweet, then tells you if the tweet is valid (less than 140 characters), tells you the amount of mentions (indicated by the character #) and the number of hashtags (indicated by a #), and tells you whether or not it is a retweet (if it contains "RT:" it is considered a retweet).
I can tell whether it is a valid tweet and can tell if it is a retweet (I coded it so that if the index of "RT:" is greater than or equal to 0, it says it is a retweet), but can't figure out how to count the number of # and # in the string the user enters. I know how to find the index, but am having trouble finding out where to go from there. I don't know what to do as a next course of action. Is there a way to count the amount of a certain character in a string?
I know what the code is currently doing, outputting the index of the first time the character shows up, but I am lost on what else I could do. I thought that maybe I could truncate every letter before and including the # and use a loop to count the amount of times that I get an index for #, then do the same for the #, but I don't know how to truncate every letter before and including a certain character. Or is there a better option? Any help is appreciated
import java.util.Scanner;
import java.lang.Math;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a tweet:");
String s = scan.nextLine();
int length = s.length();
if(length > 140)
System.out.println("Excess Characters: " + ( length - 140));
else{
System.out.println("Length Correct");
int at = s.indexOf('#');
System.out.println("Number of Mentions: " + (at));
int hash = s.indexOf('#');
System.out.println("Number of Hashtags: " + (hash));
if (s.indexOf("RT:") >=0)
System.out.println("The input was a retweet.");
else
System.out.println("The input was not a retweet.");
}}}
.indexOf will return the index of that character in your String.
That might not be the best approach to resolve your problem.
You could do something like this :
for(int i=0; i<s.length(); i++) {
if(s.charAt(i) == '#') {
count++; //or whatever mechanism you want to keep track of those chars.
}
}
Improving slightly on Caleb's answer:
Since you know which two characters you need to count, '#' and '#,' you can have a counter for each and just iterate over the tweet once. Then you just check if a character is one you're looking for, and if it is, the counter is incremented!
int mentions = 0;
int hashtags = 0;
for(int i = 0; i < s.length; i++) {
if(s.charAt(i) == '#') {
mentions++;
} else if(s.charAt(i) == '#') {
hashtags++;
}
}
Now mentions and hashtags should have the countes of #'s and #'s respectively.
You can solve this problem by implementing a simple counting method:
public int charCount(char c, String tweet) {
int count = 0;
for(int i = 0; i < tweet.length()) {
if(tweet.charAt(i) == c) count++;
}
return count;
}
With this, you can count the number of times a character appears in a tweet.
System.out.println("Length Correct");
int at = charCount('#', s);
System.out.println("Number of Mentions: " + at);
int hash = charCount('#', s);
System.out.println("Number of Hashtags: " + hash);
if (s.indexOf("RT:") >= 0)
System.out.println("The input was a retweet.");
else
System.out.println("The input was not a retweet.");
Before I attempted to insert the Array the code was returning indivdual values for the year input but I would prefer if i could input a list and then display the list if it is a leap year. if it is not it should ignore it. I've not used arrays with JOptionPane... in actual fact I've never used arrays as this is my 4th week using java so I'm quite noobish. but definitely willing to take criticism and advice. I want to get better. Thanks in advance.
import javax.swing.JOptionPane;
public class SimpleMath {
public static int printLeap(int r, int k){
if((r % 4 == 0) && (r % 100 != 0) || (r % 400 == 0)){
return r;
}
else if ((r % 4 != 0) && (r % 100 == 0) || (r % 400 != 0));
return k;
}
public static void main(String[] args) {
while (true) { //while the statement is true (so it continues indefinitely until the break occurs).
String year = JOptionPane.showInputDialog("Enter input years to be tested, when done type End");
int year[] = new year[10];
for (int x=0; x<year.length; x++)
if ("End".equals(year)){ //if the user types End then the loop will break. it allows a string to be input for an int value
break;
} {
int r = Integer.parseInt(year);
int k = 0;
int i = printLeap(r, k);
if (i == 0) {
break; // or System.out.println("");
}
else
System.out.println("Leap years entered are: " + i + x);
}
}
}
}
So let's begin with some general code review items:
The code is not formatted well, which makes it hard to read. Fixing the indentation goes a long way toward making it readable for others.
The printLeap method accepts a parameter that you have called k. When you call your method you pass it the value 0 because you have initialized k to 0 and it never changes. So this forces me to ask - why is k a parameter if it never changes?
You have syntax errors in your code. This line: int year[] = new year[10]; is wrong - it should be written int[] year = new int[10]; but when this is fixed it creates a whole new problem which is duplicate variables. The array you declared conflicts with the String above: String year = JOptionPane.showInputDialog(...);
Later on in the code you try to parse the year as an integer, which you can't do because Integer.parseInt(...) takes a String as a parameter not an array.
Variable names are too short and have no meaning. Variables with single character names like r, k, i are in most situations not a good idea. In general the only time it's considered acceptable to use a single character name for a variable is inside of a for loop definition like: for(int i=0; i<10; i++) because this is such a common pattern.
As for your question, it's not entirely clear what you're really asking here. It sounds like you want to accept a list of years as an input and output the years that are leap years.
So I'll help you get started by providing the following code:
//Accept input from the user - a single String containing multiple years separated by commas.
String input = JOptionPane.showInputDialog("Enter years to be tested (comma separated): ");
//Split the String by commas and store the resulting individual years in an array
String[] yearArray = input.split(",");
//Process each year in the array
for(String year: yearArray){
int intYear = Integer.parseInt(year);
System.out.println("Here's the integer value: " + intYear);
//Do more logic here...
}
Hope this helps!
I'm trying to get Java to recognize the output of a while loop as a variable and to use that output in further operations.
I wanted to try and upgrade it by letting one player set the word and the other one guess it. The problem came from making the number of dashes equal to the number of letters in the word that the player entered, so I separated the code out, which worked.
But when I put it all back in main, it would not recognize how many dashes are there after the loop finishes; it only recognizes the initial one which is only 1 dash, and so it poses a problem.
EDIT: Thank you so much guys, its my first time on stack overflow, tnx again.
Works like a charm :D
package iB;
import java.util.Scanner;
import java.lang.String;
public class WordGuess {
/**
* #param args
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String secretWord ;
String guess, dash = "-", upWord;
int numGuesses = 0;
int numWord;
final String SENTINEL = "!";
System.out.println("Player 2, please look away. Player 1, please enter the secter word: \n");
secretWord = input.next().toUpperCase().trim();
numWord = secretWord.length();
//System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
for(int dashNum = 1; dashNum < numWord; dashNum++) {
dash += "-" ;
}
System.out.println("WordGuess game!\n");
do {
System.out.println("Enter a letter (" + SENTINEL + "to guess entire word): ");
guess = input.next().toUpperCase().trim();
numGuesses ++;
if (secretWord.contains(guess) && guess.length() == 1) {
upWord = dash.substring(0, secretWord.indexOf(guess));
upWord += guess;
upWord += dash.substring(secretWord.indexOf(guess) + 1, dash.length());
dash = upWord.toUpperCase();
System.out.println(dash);
if (dash.equals(secretWord)) {
System.out.println("You won!\n" + "The secret word is " + secretWord);
System.out.println("You made " + numGuesses + " guesses."); }
} else if (guess.length() >= 2) {
System.out.println("Please only enter one letter at a time! \n"); }
if (guess.contains(SENTINEL)) {
System.out.println("What is your guess? ");
guess = input.next().toUpperCase().trim();
if (guess.equals(secretWord)) {
System.out.println("You won!\n" + "The secret word is " + secretWord);
System.out.println("You made " + numGuesses + " guesses.");
break;
} else {
System.out.println("You Lose!");
System.out.println("The secret word was " + secretWord);
System.out.println("You made " + numGuesses + " guesses.");
break;
}
}
} while(!guess.contains(SENTINEL));
input.close();
}
}
The problem
The following piece of code appears to be trying to show where in a word the correctly chosen letter can be found
if (SecretWord.indexOf(guess) >= 0) {
UpWord = dash.substring(0, SecretWord.indexOf(guess));
UpWord += guess;
UpWord += dash.substring(SecretWord.indexOf(guess) + 1, dash.length());
System.out.println(UpWord);
} else {
So if the word was this and you guessed i then the output should be
--i-
dash.substring does not repeat dash, it takes a sub part of dash, as dash is 1 letter long, anything other than substring(0,1) will lead to an exception.
Basic solution
I believe you want to repeat dash until you get to the guessed letter, and then after it till the end of the word. Something along the lines of:
if (SecretWord.indexOf(guess) >= 0) {
int guessedIndex=SecretWord.indexOf(guess);
String outString="";
for(int i=0;i<guessedIndex;i++){
outString+=dash; //repeat dash until we get to the correctly guessed letter
}
outString+=guess; //put the letter in
for(int i=guessedIndex;i<SecretWord.length();i++){
outString+=dash; //repeat dash until we get to end of the word
}
System.out.println(outString);
} else {
Better Solution
This however leaves the problem that only the first instance of the letter is shown. This can be solved using annother stack overflow answer in which we see that we can get all the occurances of a character using a function
public static ArrayList<Integer> getAllIndexes(String testChar, String string){
int index=string.indexOf(testChar);
ArrayList<Integer> indexes=new ArrayList<Integer>();
while(index>0){
indexes.add(index);
index=string.indexOf(testChar,index+1);
}
return indexes;
}
Then using that function to find all the indexes at which the letter occurs we can deal with repeated letters
if (SecretWord.indexOf(guess) >= 0) {
int guessedIndex=SecretWord.indexOf(guess);
ArrayList<Integer> indexes=getAllIndexes(guess,SecretWord);
String outString="";
for(int i=0;i<SecretWord.length();i++){
if (indexes.contains(i)){
outString+=guess; //if its one of the guessed letters, put that in
}else{
outString+=dash; //otherwise add a dash
}
}
System.out.println(outString);
} else {
Now a word of hello and a guess of l correctly outputs --LL-
Notes
It is usual to follow the naming convention that variable names are
in lower camel case, meaning they start with a lower case letter, as
such SecretWord should be secretWord. As it is currently written
it looks like SecretWord is a class, which are usually writen in
upper camel case.
It would be nice, if once you've guessed a letter it stops putting a dash in and starts putting the letter in every time after that, this could be achieved by using an array of booleans to check if the letter has been guessed but that is beyond the scope of this question
All of these solutions have appended strings, which can be slow for huge numbers, in your case this is the right thing to do, but is joining lots of strings together in a loop consider using a StringBuilder to remove the overhead of creating loads of intermediate strings
Solution
If the secret word is pony, the String dash should be equal to ----. The problem is that you never actually change dash from being equal to -. Therefore, when you do things like dash.substring(SecretWord.indexOf(guess) + 1, dash.length()), you get errors because dash only contains one character. Here's how I'd make dash the same length as the secret word:
for(int i = 0; i < NumWord; i++) {
dash += "-";
}
With this one change inserted directly before your do-while loop, your program works like a charm. Below are some other things to consider in order to further improve your program.
Improving readability
Java convention dictates that the first word of method and variable names is lowercase. So NumWord should be numWord, SecretWord should be secretWord, etc.
SecretWord.indexOf(guess) >= 0 should be changed to
SecretWord.contains(guess)
Gameplay suggestions
As in hang man, you should probably show all the spots where the guessed letter occurs. For example, if the secret word is happy, a guess of p should produce the output of --PP- instead of --P--.
As a rule, never accept bad input even if it doesn't cause errors. The program shouldn't allow any of the scenarios below:
A user enters a String containing non-alphabetic characters or multiple words as the secret word
When making guesses, non-alphabetic characters are input (excluding !)
When guessing letters, multiple characters are input.
I have made a couple of modifications to your code, it seems to work fine now.
First though, I added an extra method, just to make it a little easier:
public static String printOutWord(String[] UpWord){
String out = "";
for(int i = 0; i < UpWord.length; i++){
out += UpWord[i];
}
return out;
}
Here are the first few changes to you code:
String[] UpWord = new String[NumWord];
for(int i = 0; i < NumWord; i++){
UpWord[i] = "-";
}
printOutWord(UpWord);
System.out.println("\nWordGuess game!");
So, you no longer need the variable dash, and the variable UpWord has been changed to an array of Strings.
And this is the rest of it:
do {
System.out.println("Enter a letter (! to guess entire word): ");
guess = input.next().toUpperCase().trim();
Numguesses++;
if(guess.length() > 1){
System.out.println("Please only enter one letter at a time");
}else if (SecretWord.indexOf(guess) >= 0) {
int index = SecretWord.indexOf(guess);
UpWord[index] = guess;
while(SecretWord.indexOf(guess, index+1) >= index){
index = SecretWord.indexOf(guess, index+1);
System.out.println(index);
UpWord[index] = guess;
}
System.out.println(printOutWord(UpWord));
if(printOutWord(UpWord).equals(SecretWord)){
System.out.println("You won!\n" + "The secret word is " + SecretWord);
return;
}
} else {
if (guess.contains("!")) {
System.out.println("What is your guess? ");
guess = input.next().toUpperCase();
if (guess.equals(SecretWord)) {
System.out.println("You won!\n" + "The secret word is " + SecretWord);
System.out.println("You made " + Numguesses + " guesses");
} else if (!guess.equals(SecretWord)) {
System.out.println("You Lose!");
System.out.println("You made " + Numguesses + " guesses");
}
}
}
} while (!SecretWord.equals(guess));
input.close();
}
Most of the changes are within the first if statement.
I hope this helped, if any clarification is needed about anything, just ask, I'd be happy to help :)
I'm an aspiring java user taking college courses and I've run into a problem. My prof. told us to write a java program that detects a 5 digit number based palindrome. I've written something but it won't work the way I've planned. Could I get some help please? Using netbeans IDE.
package palindrome;
import javax.swing.JOptionPane;
public class Palindrome {
public static void main(String[] args) {
String stringNumber;
int number;
String stringPal;
int palindrome;
stringNumber = JOptionPane
.showInputDialog("Please, if you will, enter a five digit palindrome: ");
number = Integer.parseInt(stringNumber);
if (number < 10000 && number > 99999) {
System.out
.println("Your number is invalid, please enter a FIVE digit number: ");
} else if (number % 10 == number % 100) {
System.out.println("your number: " + number + "is a palindrome");
} else {
System.out.println("You FAIL loser");
}
}
}
Your palindrome logic is incorrect. You check if the remainder when divided by 10 equals the remainder when divided by 100 - that is the case if and only if there is a 0 in the tens digit. That is not the definition of a palindrome.
As already pointed out, that your logic for palindrome is wrong.
What you need to check is if the string/number is same when reversed.
So, suppose you want to check whether the a string is palindrome, reverse it and check if it is same as the original string.
You should try to complete this template:
boolean isPalindrome(String s){
String reverseString = reverseString(s);
if(reverseString.equals(s)){
return true;
}
return false;
}
String reverse(String s){
//add code to reverse String. (and optionally check if it is Integer, if it is a requirement)
}
You can now google how to reverse a string.
PS: You might wanna take a look at StringBuilder class.
i don't understand, how number % 10 == number % 100, implies palindrome, but all it does is compare the value of the last 2 digits to the value of the last 1 digit.
My advice would be to take input as a string or char array and the compare the last element of the string to the first, and then continue until you hit the middle
here's some psudo-code:
isPalindrome = true;
for i=0 to stringLength
if(input[i] != input[length - i - 1])
isPalindrome = false;