Hey Guys. thanx for the major help regarding my obstacles.
What my problem this time is, how can I sort the array list that is provided in my code basically dont know WhatI need to add in the provied code below, just to simplyfive it I got 3 arraylist that i want to make them into one arraylist, so they can be sorted in amont of guesses and tries( if 2 players have the same guesses then the time should determine) .
Pretty hard to explain it but i tried my best.............the best thing is to run it then you will figure it what whats the issue is?
Here is the code:
import java.util.*;
import java.util.Scanner.*;
import java.util.ArrayList.*;
public class Main {
public static String ToString(int a, double b, String c)
{
String aS = Integer.toString(a);
String bS = Double.toString(b);
String scoreList = (aS + "\t\t" + bS + "\t\t" + c);
return scoreList;
}
private static void start() {
int tries = 0 ;
int guess = -1;
String name ;
String quit = "quit";
String y = "yes";
String n = "no";
String currentGuess;
String another = ("y") ;
Scanner input = new Scanner (System.in);
ArrayList<String> scores = new ArrayList<String>();
boolean a=false;
do {
a=false;
int answer = (int) (Math.random() * 1000 + 1) ;
System.out.println( " Welcome to Guessing Game " ) ;
System.out.print("Please enter a number between 1 and 1000 : ");
currentGuess = input.nextLine();
long startTime = System.currentTimeMillis();
do
{
if (currentGuess.equalsIgnoreCase(quit))
{
System.out.println("Leaving Us So Soon?");
System.exit(0);
}
try {
guess = Integer.parseInt(currentGuess);
} catch (NumberFormatException nfe)
{
System.out.println(" Dude Can You Read, Only Digits ");
currentGuess = input.nextLine();
}
if (guess < 1 || guess > 1000)
{
System.out.println("Stupid Guess I Wont Count That.");
currentGuess = input.nextLine();
}
if (guess < answer )
{
System.out.println("too low "+answer);
currentGuess = input.nextLine();
tries++;
}
else if(guess > answer )
{
System.out.println("too high "+answer);
currentGuess = input.nextLine();
tries++;
}
else if (guess == answer)
{
//stop stop watch
long endTime = System.currentTimeMillis();
//calculate game time
long gameTime = endTime - startTime;
System.out.println("You Rock Dude, Good Job!");
System.out.println("You guessed " + tries + " times in " + (int)(gameTime/1000) + " seconds.");
System.out.println("Please enter your name.");
name = input.nextLine();
//create score object
String TOString =ToString(tries, gameTime, name);
//add score to arrayList
scores.add(TOString);
boolean s = false ;
while (s==false)
{
System.out.print("Want to go again?(y/n).....");
currentGuess = input.nextLine();
if (currentGuess.matches("y"))
{
System.out.println("HighScore: \nGuess \t Time in milisec\tName");
//print out high score list
for (int i = 0;i < scores.size(); i++)
{
System.out.println(scores.get(i));
}
// Main.start
s=true;
}
//if user doesn't want to play again
if (currentGuess.matches("n"))
{
System.out.println("HighScore:\nGuess \tTime in milisec\tName");
//print out high score list
for (int i = 0;i < scores.size(); i++)
{
System.out.println(scores.get(i));
}
System.out.println("Thanx For Playing.");
a=true;
s=true;
System.exit(0);
}
}
}
} while (guess != answer);
}while(a==false);
}
public static void main(String[] args) {
// ArrayList<Score> scores = new ArrayList<Score>();
Main.start();
}
}
Use Collections.sort() and make sure your class implements Comparable or use something like this:
Collections.sort(list, new Comparator<T>() {
public int compare(T o1, T o2) {
return o1.compareTo(o2);
}});
You can use something like input.nextInt() to read in the next integer instead of the next String. I can see no reason why you are storing Strings instead of ints in your code. Then you can use what everyone else has suggested to combine the lists and/or sort them.
I also think you should do some more reading by yourself. Some of the questions you've asked in your comments are answered in the Java documentation.
When someone posts a suggestion, at the very least look it up in the API and try to understand it. People won't be giving you all the code here, they will just give you hints that you need to follow.
To sort an ArrayList you can use the Collections.sort() method; either with only a List of Comparable elements or with a Comparator.
This is the simplest way.
In your case Collections.sort(scores) will do the thing.
To sort a list, use java.util.Collections.sort( list ).
To make one list out of three, you can use alist.addAll(anotherList). Then sort aList as suggested by Collin Hebert.
I helped to answer this in your previous post. However, I will add it here as well. I think you may want a List instead of a list of Strings. This will allow you to sort on the number of tries the end user has attempted, in a natural way. In addition to the other answers here, the simplest way is then to make a call to Collections.sort(list)
Additionally the toString() method is used for debugging purposes, or to provide human readable information. It shouldn't be used to create objects in the way that you are utilizing it. Just my .02
If you absolutely require a list to be sorted at all times, don't use an ArrayList, use a PriorityQueue. It can be constructed to use the content's natural sort order (i.e. via the Comparable interface on each object), or via a Comparator. The advantage of PriorityQueue is it is always sorted even after new items are added.
Related
I have a program that will help the user to learn a multiplication table and then show results of right/wrong answers. The first step is to simply ask the user for which multiplication table it want to work on (1-9). And then the user will get a random sequence of number multiplied by the chosen multiplication table. If the user answers correctly then that number won't be shown again, but if incorrectly then it will be shown until the correct answer is made.
One scenario could be that the user chooses "3", and it will then be displayed in a random sequence such as (3x7 =, 3x1 =, 3x9 =...). And the user will answer after each "=". Right now, I can only print it all in ascending order, should I use Random multiplied with the chosen table in a while loop instead?.
My second issue, is how I can ask the incorrectly answered numbers again, until correctly answered? Am I right to think that a for loop isn't the best choice in this case?
Here is my code so far:
public class Multiplication {
public static void main (String[] args) {
Scanner inread = new Scanner (System.in);
int answer;
System.out.println("Choose multiplication table (1-9)");
int num1= inread.nextInt();
for (int i=1; i<11; i++) {
System.out.println("Write answer after = ");
System.out.println(num1 + " x " + (i) + " = ");
answer=inread.nextInt();
if (answer == (num1 * i) ) {
System.out.println("Correct answer");
// Do not show that number again
}
else {
System.err.println("Wrong answer");
//Show this number again.
}
}
}
}
New code after int num1 = inread.nextInt();
unanswered.add(1);
unanswered.add(2);
unanswered.add(3);
unanswered.add(4);
unanswered.add(5);
unanswered.add(6);
unanswered.add(7);
unanswered.add(8);
unanswered.add(9);
unanswered.add(10);
Collections.shuffle(unanswered);
while (!unanswered.isEmpty()) {
System.out.println(num1 + "*" + "unanswered" + " = "); //?
answer = inread.nextInt();
if (answer == (num1 * unanswered)) { //?
unanswered.remove(unanswered); //?
}
}
So, I think this is almost the way you suggested? However I'm sure I could add the numbers in a more beautiful way. I am used to looping through lists with a for loop in order to then use the counter to display the list. So where I putted a "?" is because I am not sure how to specify where in the list I am trying, for example to remove a number.
Or should I have the while loop, inside the for loop that I originally had? So that I could use the (i) in the for loop to specify where in the list I will display and perhaps remove?
A good question and a good start on the coding.
One way of asking for input until all the multiplication questions have been solved would be a while loop.
As #Easton pointed out an ArrayList to store the numbers and Collections.shuffle will help with the setup. By creating the ArrayList ahead of time then using a while loop until it is empty to prompt the user to keep answering.
EDIT
Heading in the right direction. To simplify the creation of unanswered numbers make use of the for loop, Something like: for(i=1, i<=10,i++) then add(i) to unanswered.
In the while loop, grab the first index: unanswered[0] and set that to num1 then if the answer is correct, remove it (as you have now). If not use Collections.rotate on unanswered by 1. Which will move the unanswered question to the end of the array for another attempt later.
Bellow you can find a solution for your problem with Hash Tables, you can do modifications to it so that the user can not type a number larger than 9 or smaller than 0 but this should work for your purpose:
import java.util.Random;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Multiplication {
public static void main (String[] args) {
Map<Integer, Integer> list = new HashMap<Integer, Integer>();
Scanner inread = new Scanner (System.in);
int answer;
System.out.println("Choose multiplication table (1-9)");
int num1= inread.nextInt();
for (int i = 1; i<10; i++) {
list.put(i, num1*i);
}
System.out.println(list);
while (!list.isEmpty()) {
System.out.println("Write answer after = ");
Random generator = new Random();
Object[] keys = list.keySet().toArray();
Object randomValue = keys[generator.nextInt(keys.length)];
int next = (Integer) randomValue;
System.out.println(num1 + " x " + (next) + " = ");
answer=inread.nextInt();
if (answer == (num1 * next)) {
System.out.println("Correct answer");
list.remove(next);
} else {
System.err.println("Wrong answer");
}
}
System.out.println("Congrats!!!");
}
}
My program gives a String answer based on comparisons of Integer input. Would there be a more efficient way of doing this instead of prompting the user 3 separate times and calling numberVerify three separate times? How would I do this? Very new to Java.
public static void main(String[] args) {
// TODO code application logic here
// declare variables
int number=0;
System.out.println("Enter the first integer: ");
int number1 = numberVerify(number);
System.out.println("Enter the second integer: ");
int number2 = numberVerify(number);
System.out.println("Enter the third integer: ");
int number3 = numberVerify(number);
String compare = comparison(number1, number2, number3);
printer(compare);
}
public static int numberVerify(int number){
Scanner in = new Scanner(System.in);
if(in.hasNextInt()){
number = in.nextInt();
}
else{
System.out.println("Error! Input must be an integer!");
System.out.println("");
return numberVerify(number);
}
return number;
}
public static String comparison(int number1, int number2, int number3){
String answer;
if(number1 == number2 && number1 == number3)
{
answer = "all the same";
}
else if(number1 != number2 && number1 != number3)
{
answer = "all different";
}
else
{
answer = "neither";
}
return answer;
}
public static void printer(String answer){
System.out.println(answer);
}
Efficiency is irrelevant here.
The user is going to take SECONDS to enter the number. The OS could take MILLISECONDS to do the keyboard event processing, screen redrawing etc. Your Java application is going to take MICROSECONDS or less to do the decision making. Any effort you expend to reduce the microsecond component is wasted effort.
If there are issues to be addressed here (and I'm not saying there are) they would be:
making the user interface easy to use.
writing the code so that it is easy to read and easy to maintain.
writing the code to be "elegant" ... which is not necessarily the same as the previous.
UPDATE - Apparently you are actually interested in simplifying and/or reducing the size of the code.
Firstly, that's NOT what most people mean by efficiency. (Indeed, I would argue that spending time on improving code that is good enough is inefficient use of your time.)
Secondly, simplicity and code size are not the same things. Most people (programmers) would say that simple code is code that is easy to understand ... for the average programmer. Often, a more concise solution to a problem will actually be difficult to understand. (Take #rby's code for example. If you needed to be sure it was correct without testing it, you would need to read it very carefully.)
Finally, professional software engineers follow the general principle that the code needs to be "good enough for purpose"1 ... but no better. Perfect is the enemy of good. Spending your time making a program better than it needs to be is wasting your time, and liable to cost you / your client / your employer money.
1 - The purpose may include performance criteria, readability / maintainability, generality / resuability, and various specific correctness criteria. But that is not necessarily the case. Often, code is written for a context where many of those criteria are irrelevant or even counter-productive. But I digress ....
Use an int array and a for loop instead say :
int [] values = new int[3];
for(int i =0; i<3; i++){
values[i] = in.nextInt();
}
Then modify your compare method to use the array;
For brownie points look up Sets and figure how you can eliminate most of your comparison method with them.
You can use the following single line to replace your entire if blocks in method comparison and return answer as you do:
answer = ( (n1 == n2) ?
( (n2 == n3) ? "all equal" : "neither") :
( n1 == n3) ? "neither" : ( ( n2 == n3 ) ? "neither" : "all different" ) );
return answer;
You can use arrays and little other modifications to make it efficient.
Here is the code.
import java.util.Scanner;
public class efficient {
private static String comparison(int[] numberArray) {
String answer;
if(numberArray[0] == numberArray[1] && numberArray[1] == numberArray[2]){
answer = "all the same";
}else if(numberArray[0] != numberArray[1] && numberArray[1] != numberArray[2]){
answer = "all different";
}else{
answer = "neither";
} return answer;
}
public static void main(String[] args) {
int[] numberArray = new int[3];
Scanner scan = new Scanner(System.in);
System.out.println("Enter the numbers");
for(int i=0;i<=numberArray.length-1;i++){
if(scan.hasNextInt()){
numberArray[i]=scan.nextInt();
}else{
System.out.println("Error! Input must be an integer!");
}
}
String compare = comparison(numberArray);
System.out.println(compare);
}
}
I don't know about more efficient or readable, it seems that way already. But I can make it shorter.
public static void main(String[] args) {
// TODO code application logic here
// declare variables
Scanner in = new Scanner(System.in);
int[] numbers = new int[3];
String[] labels = {"first","second","third"};
for(int i=0; i<3; i++)
{
System.out.print("Enter the " + labels[i] + " integer: ");
numbers[i] = in.nextInt();
}
System.out.println(comparison(numbers[0],numbers[1],numbers[2]));
}
public static String comparison(int number1, int number2, int number3){
String answer;
if(number1 == number2 && number1 == number3)
{
answer = "all the same";
}
else if(number1 != number2 && number1 != number3 && number2 != number3)
{
answer = "all different";
}
else
{
answer = "neither";
}
return answer;
}
I am trying to make a functioning to do list with a limit of 10 elements, however I am having an issue with two major things in the to do list.
The first is that after I first compile and run the program and select to add elements to the list, that functions properly, but if I add two elements and the 'stop' sentinel, when I select the next option to print the to do list, I am presented with a list, showing my two elements and then the stop sentinel along with 7 null values in the list. So the first issue I am having is to get rid of the null values, I attempted using a counter as you can see in my code however that was not proving to be effective.
The next issue that I am having is that I am trying to make it so that you can add to the list, so once you select to add more things to the list, the new options the user writes, rewrites over them in the array and prints out the new values and not along with the old ones. I am assuming that can be done through some sort of recursion method but I am having a hard time figuring it out.
Any help would be greatly appreciated!
Thanks!
import java.util.Scanner;
public class ToDo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int MAX = 10;
String[] list = new String[MAX];
int choice = 0;
while (choice != 3) {
System.out.println();
System.out.println("Type 1 to add a new thing to your to do list.");
System.out.println("Type 2 to print the to do list.");
System.out.println("Type 3 to exit the program.");
System.out.print("Select an option: ");
choice = input.nextInt();
int count = 0;
if (choice == 1) {
System.out.println("Keep hitting enter after to do's, if you want to stop, type 'stop'.");
for (int i=0;i<MAX;i++) {
list[i] = input.nextLine();
if (list[i].equals("stop")) break;
count++;
}
}
if (choice == 2) {
for (int index = 0;index < list.length; index++) {
System.out.println(list[index]);
}
}
}
}
}
As I have mentioned in the comment, you can use an ArrayList instead of String[] to make your processing much easier.
But if you want to use the array itself, there are 3 minor issues with your code.
In your choice 1 for loop, start the loop from count,
for (int i=count;i<MAX;i++) {
list[i] = input.nextLine();
if (list[i].equals("stop")) break;
count++;
}
In your choice 2 for loop, end the loop before reaching count,
for (int index = 0;index < count; index++) {
System.out.println(list[index]);
}
And move your count initialization outside the while loop.
int count = 0;
But beware, if you decide to implement removing tasks, this could get complicated and using ArrayList would become much simpler.
Instead of using a fixed size array of Strings, use an ArrayList of Strings. Then you can add elements to it as you go.
Make sure to
import java.util.ArrayList;
Declaration syntax is
ArrayList<String> myList = new ArrayList<String>();
Add elements to your list with the add() method:
myList.add(input.nextLine())
You don't need that inner for loop, instead break out of the while loop of input options when you've iterated through it 10 times.
To solve your problem of "stop" being in your list, check that the input is "stop", and stop, before you attempt to add to the list.
It is better to use ArrayList but if you still want to stick to String[] then the following program will work for you:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int MAX = 10;
String[] list = new String[MAX];
int choice = 0;
while (choice != 3) {
System.out.println();
System.out.println("Type 1 to add a new thing to your to do list.");
System.out.println("Type 2 to print the to do list.");
System.out.println("Type 3 to exit the program.");
System.out.print("Select an option: ");
choice = input.nextInt();
String userEnteredItem;
if (choice == 1) {
System.out.println("Keep hitting enter after to do's, if you want to stop, type 'stop'.");
for (int i=0;i<MAX;i++) {
userEnteredItem = input.nextLine();
if(!userEnteredItem.isEmpty()) {
list[i] = userEnteredItem;
if (userEnteredItem.equals("stop")) {
break;
}
count++;
} else {
i--; // Do not increase index for empty item.
}
}
}
else if (choice == 2) {
for (int index = 0;index < count; index++) {
System.out.println(list[index]);
}
}
else {
input.close();
}
}
}
It keeps track of user items in static int count and it also closes the scanner when you do not need it.
I have following code in Java:
public class StringSearch
{
public static void main(String[] args)
{
String s = new String("I love my school. I love to play basketball. It is lovely weather. Love is life.");
System.out.println(s);
int i = -1;
int count = 0;
System.out.print("Counting love:");
do{
i = s.findW("love");
if(i != -1){
count++;
System.out.print(count+" ");
}
}while(i != -1);
System.out.println("The word \"love\" appears "+count+" times.");
}
}
I know that s.findW() is incorrect because findW() is not defined for Class String. However, is it possible to add user defined function in the class String and fix this?
Any alternative to fix this?
Hint for this problem is to read JDK documentation and fix the code. :/
I would the use the indexOf method as follows:
String s = new String("I love my school. I love to play basketball. It is lovely weather. Love is life.").toLowerCase();
System.out.println(s);
int i = 0;
int count = 0;
System.out.print("Counting love:");
while(i != -1)
{
i = s.indexOf("love");
if(i != -1){
count++;
s = s.substring(i+1);
System.out.print(count+" ");
}
}
System.out.println("The word \"love\" appears "+count+" times.");
Depending on whether you expect the answer to be 3 or 4, you would need to have the toLowerCase in there so that Love either matches or does not match.
The Java String class is final and cannot be altered. You could write your own but that would be crazy. There is generally enough funtionality on String already. If it doesn't do what you want, write a helper class with some methods.
Java regex is your friend!
String s = "I love my school. I love to play basketball. It is lovely weather. Love is life.".toLowerCase();
int count = (s.length() - s.replaceAll("love", "").length()) / 4;
System.out.println("The word \"love\" appears " + count + " times.");
Hey guys , thanx for the previous help Before I try to explain my problem, you guys need to know what the code is about. Its pretty much "To write a game in which a user is to guess a random number between 1 and 1000. The program should read a number from the keyboard, and print whether the guess was too high, too low or correct. When the user has guessed correctly, the program prints out the numbe of guesses made and time and the playername.When a game is started the program must print the entire high score list, sorted by the number of guesses in ascending"
The Issue is when playing the game and when you manage to get the correct answer it doesn't show the time but when the highscore is printed it shows there, Whats up with that because tried to change the boolean statement but that didn't see to work. Here is an illustration of the problem:
You guessed 2 times in 0 seconds.
Please enter your name.
gert
Want to go again?(y/n).....n
HighScore:
Tries Time Name
1 35 b
2 6 gert
SO basically I'm pretty stuck, I was hoping that u guys could give me some pointers or some kind of help so I could fix the problem,,,,, Any help is appreciated.... BTW this is my first program, basically still in the learning phase So take it easy with the comments. The code is provided below:
import java.util.*;
import java.util.Scanner.*;
import java.util.ArrayList.*;
import java.util.Collections.*;
public class Main {
private static void start() {
int tries = 0 ;
int guess = -1;
String name ;
String quit = "quit";
String y = "yes";
String n = "no";
String currentGuess;
String another = ("y") ;
Scanner input = new Scanner (System.in);
ArrayList<Integer> score = new ArrayList<Integer>();
ArrayList<Long> tg = new ArrayList<Long>();
ArrayList<String> playern = new ArrayList<String>();
boolean a=false;
do {
a=false;
int answer = (int) (Math.random() * 1000 + 1) ;
System.out.println( " Welcome to Guessing Game " ) ;
System.out.print("Please enter a number between 1 and 1000 : ");
currentGuess = input.nextLine();
long startTime = System.currentTimeMillis();
do
{
if (currentGuess.equalsIgnoreCase(quit))
{
System.out.println("Leaving Us So Soon?");
System.exit(0);
}
try {
guess = Integer.parseInt(currentGuess);
} catch (NumberFormatException nfe)
{
System.out.println(" Dude Can You Read, Only Digits ");
currentGuess = input.nextLine();
continue;
}
if (guess < 1 || guess > 1000)
{
System.out.println("Stupid Guess I Wont Count That.");
currentGuess = input.nextLine();
continue;
}
if (guess < answer )
{
System.out.println("too low "+answer);
currentGuess = input.nextLine();
tries++;
}
else if(guess > answer )
{
System.out.println("too high "+answer);
currentGuess = input.nextLine();
tries++;
}
else if (guess == answer)
{
//stop stop watch
long endTime = System.currentTimeMillis();
//calculate game time
long gameTime = endTime - startTime;
gameTime = (gameTime/1000);
System.out.println("You Rock Dude, Good Job!");
System.out.println("You guessed " + tries + " times in " + (int)(gameTime/1000) + " seconds.");
System.out.println("Please enter your name.");
name = input.nextLine();
score.add(tries) ;
playern.add(name);
tg.add(gameTime);
for ( int g=0; g < score.size()-1; g++){
for ( int b=g+1; b < score.size(); b++){
if (score.size()>1){
if (score.get (g) > score.get (b)){
Collections.swap(score, g, b);
Collections.swap(playern, g, b);
Collections.swap(tg, g, b);
}
}
if (score.get (g)==score.get(b) && tg.get (g) > tg.get(b))
{
Collections.swap(score, g, b);
Collections.swap(playern, g, b);
Collections.swap(tg, g, b);
}
}
}
boolean s = false ;
while (s==false)
{
System.out.print("Want to go again?(y/n).....");
currentGuess = input.nextLine();
if (currentGuess.matches("y"))
{
System.out.println("HighScore:");
System.out.println("Tries\tTimentName");
for (int j=0; j<score.size(); j++){
System.out.println(score.get(j) +"\t"+tg.get(j)+ "\t"+playern.get(j));
}
}
s=true;
}
//if user doesn't want to play again
if (currentGuess.matches("n"))
{ System.out.println("HighScore:");
System.out.println("Tries\tTime\t\tName");
for (int j=0; j<score.size(); j++){
System.out.println(score.get(j) +"\t"+tg.get(j)+ "\t"+playern.get(j));
}
System.out.println("Thanx For Playing.");
a=true;
s=true;
System.exit(0);
}
}
} while (guess != answer);
}while(a==false);
}
public static void main(String[] args) {
Main.start();
}
}
first you divide the time here
long gameTime = endTime - startTime;
gameTime = (gameTime/1000);
and then again here
System.out.println("You guessed " + tries + " times in " + (int)(gameTime/1000) + " seconds.");
no wonder why you get 0 :). so, don't divide again, just put gameTime
and then when you add to the tg Array List you add tg.add(gameTime); which is the correct time, that's why when you list the Highscores it works.
A couple of things here.
First, there is no Timer being used here. You are timing something in terms of actual time, but in Java, a Timer (such as java.util.Timer) is an object that schedules a repeated task.
Second, you should try to break up your code into smaller methods. These long, nested do/while loops are very hard to read because you can't see the whole loop without scrolling. Try keeping your methods shorter, and use multiple methods.
But, to answer your question about the time, you are dividing the time by 1000 twice when you try to display it. Your display line is
System.out.println("You guessed " + tries + " times in " + (int)(gameTime/1000) + " seconds.");
But you have already divided gameTime above
long gameTime = endTime - startTime;
gameTime = (gameTime/1000);
So in the display, you're not actually modifying gameTime again (which is why it stores as the proper value), but you are displaying gameTime/1000 (even though it has already been divided by 1000 once).
It is also a good thing for a starting developer to follow the simple indentation rules you've (hopefully) learned.
Also you should't write something like while(a==false); if a is a boolean just write while(a).
In this case you also do not have to use a do - while loop. A while loop will be more suited.