How to make my code more time-efficient - java

I am submitting the following code to an online judge.
Input Specification
The data provided by Bill and Ted has the following format: The first line consists of the number p of parties followed by the number g of guesses (with 1 ≤ p ≤ 50 and 1 ≤ g ≤ 10000). Then follow p lines, each line consisting of a unique party name of length ≤ 20 (only containing letters a-z, A-Z and digits 0-9) and the achieved vote percentage of this party with one digit after the decimal point. After the parties follow g lines, each consisting of a guess. A guess has the form P1 + P2 + ... + Pk COMP n, where P1 to Pk are party names, COMP is one of the comparison operators <, >, <=, >= or = and n is an integer between 0 and 100, inclusively. Each party name occurs at most once in each guess.
Output Specification
For each guess, sum up the vote percentages of the parties and compare them with the specified integer n. Then, print a line stating whether the guess was correct. See the sample output for details.
but whatever i do it always gives me time limit exceeded ...and here is my final code,
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String Ints = br.readLine();
String Guess;
String [] Ints_array = Ints.split("[ ]+");
int p = Integer.parseInt(Ints_array[0]);
int g = Integer.parseInt(Ints_array[1]);
HashMap<String, Float> Parties = new HashMap<String, Float>();
for(int i = 0 ; i < p ; i++) {
String temp = br.readLine();
String [] temp_array = temp.split("[ ]+");
Parties.put(temp_array[0],Float.parseFloat(temp_array[1]));
}
for(int j = 0 ; j < g ; j++) {
Guess = br.readLine();
float actual = 0;
String [] temp = Guess.split("[ ]+");
if(Guess.contains("+"))
{
for(int i = 0 ; i < temp.length-2 ; i++)
{
if(!temp[i].contains("+"))
actual+= Parties.get(temp[i]);
}
}
else
{
actual=Parties.get(temp[0]);
}
float guess = Float.parseFloat(temp[temp.length-1]);
if( temp[temp.length-2].contains(">"))
{
if(temp[temp.length-2].contains("="))
{
if(actual >= guess)
System.out.println("Guess #"+(j+1)+" was correct.");
else
System.out.println("Guess #"+(j+1)+" was incorrect.");
}
else
{
if(actual > guess)
System.out.println("Guess #"+(j+1)+" was correct.");
else
System.out.println("Guess #"+(j+1)+" was incorrect.");
}
}
else if( temp[temp.length-2].equals("<"))
{
if(temp[temp.length-2].contains("="))
{
if(actual <= guess)
System.out.println("Guess #"+(j+1)+" was correct.");
else
System.out.println("Guess #"+(j+1)+" was incorrect.");
}
else
{
if(actual < guess)
System.out.println("Guess #"+(j+1)+" was correct.");
else
System.out.println("Guess #"+(j+1)+" was incorrect.");
}
}
else if( temp[temp.length-2].equals("="))
{
if(actual == guess)
System.out.println("Guess #"+(j+1)+" was correct.");
else
System.out.println("Guess #"+(j+1)+" was incorrect.");
}
}
}
}

I'll write a part of the answer, because I think that it would take a good search to have a complete answer.
Try to use Set in place of Arrays, because the function contains would be faster.
Raw String split is not the faster way to make a split. Stack Overflow question Performance of StringTokenizer class vs. split method in Java is a comparison of splitting methods.
Hope this would help.

Related

Check if the input number is in a valid binary format

i tried to make a simple program,which check if the input number from the user is a binary number and that number is in correct binary format -> without leading zeros. That below is my code,but it doesn't work. I would appreciate if someone could help.
public class CheckNumberBinary {
public static void main(String args[]) {
int r = 0, c = 0, num, b;
Scanner sl = new Scanner(System.in);
num = sl.nextInt();
int firstDigit = Integer.parseInt(Integer.toString(num).substring(0, 1));// i want to get the first digit from the input
if (firstDigit>0||firstDigit==1 ){
while (num > 0) {
if ((num % 10 == 0) || (num % 10 == 1))
c++;
r++;
num = num / 10;
}
if (c == r) {
System.out.println(true);
} else
System.out.println(false);
} else System.out.printf("WARNING: The number starts with 0");
}
}
There are a better solution, you can check if your input contain only 0 and 1 and the input great then 0 then valide number, so instead you can use String for example :
String num;
Scanner sl = new Scanner(System.in);
num = sl.next();
if (num.matches("[01]+") && !num.startsWith("0")) {
System.out.println("Correct number :" + num);
}else{
System.out.println("Not Correct number!");
}
num.matches("[01]+") will check if your input contain only 0 and 1.
!num.startsWith("0") this to answer this part without leading zeros
Test:
10010 -> Correct number :10010
00001 -> Not Correct number!
11101 -> Correct number :01101
98888 -> Not Correct number!
You can try something like this:
public static void main(String args[]) {
boolean binary=true; // boolean for final decision
String input;
int counter=0; // to count how many leading zeros there are in the input
int target = 5; // specify how many leading zeros allowed!!
Scanner in = new Scanner(System.in);
input = in.nextLine(); // take the entire line as a String
//first loop through the whole input to check for any illegal entry (i.e. non digits)
for(char digit : input.toCharArray()){
if(!Character.isDigit(digit)){ // catch any non-digit !
System.out.println("Illegal Input Found!"); // inform user and exit
System.exit(0);
}
if(digit!='0' && digit!='1'){ // check if it's not 1 and not 0
binary = false;
}
}
// now if there are no illegal inputs, check if it starts with leading zeros
if(input.charAt(0)=='0'){ // potential leading zeros, check the rest
while(input.charAt(counter)=='0'){ // while there are followed zeros
counter++;
if(counter>target && binary){ // leading zeros only in case it's a binary
System.out.println("Illegal Leading Zeros!");
System.exit(0);
}
}
}
// now if your program reach this point that means the input is valid and doesn't contain leading zeros in case it's a binary
if(binary){
System.out.println("It is a binary number");
}
else{
System.out.println("It is NOT a binary number");
}
}
Test:
01010101 -> It is a binary number
01010105 -> It is NOT a binary number
0000001 -> Illegal Leading Zeros!
0000005 -> It is NOT a binary number
000000A -> Illegal Input Found!
Why not simply use the standard library methods?
static boolean isValidBinary(final int input) {
final String binary = String.valueOf(input);
return binary.replaceAll("[01]", "").isEmpty() && !binary.startsWith("0");
}
you should not use sl.nextInt(); it will transfer '011' to 11, so when user input '011', the variable 'num' get the int value 11.
You should simply use sl.next() to get the input of user.
I think you need to check your "if" condition before the while, because you don't want that the number starts with 0, right? so... just ask for it, I have tryied and worded fine to me:
public class CheckNumberBinary {
public static void main(String args[]) {
int r = 0, c = 0, num, b;
Scanner sl = new Scanner(System.in);
String input = sl.next();
num = Integer.parseInt(input);
String firstDigit = (input.length() > 0 ? input.substring(0, 1) : "" );
if (firstDigit.equals("0")) {
System.out.printf("WARNING: The number starts with 0");
} else {
while (num > 0) {
if ((num % 10 == 0) || (num % 10 == 1))
c++;
r++;
num = num / 10;
}
if (c == r) {
System.out.println(true);
} else
System.out.println(false);
}
}
}
The rest of your code Fulfills its mission! It tells you if the number is binary or not, and now plus tells you if your code begins with useless zeros
import java.util.*;
public class BinaryTest {
public static void main(String [] args){
Scanner input=new Scanner(System.in);
int count=0;
boolean check=true;
System.out.print("Enter a number: ");
int num=input.nextInt();
for(int i=0; i<=num; i++){
count=num%10;
if(count>1) {
check=false;
break;
}
else {
check=true;
}
num=num/10;
}
if(check)
System.out.println("Binary");
else
System.out.println("Not Binary");
}
}

string index out of bounds exception, on an if else statement

The problem code is below, if you need the entire main method to help me, please ask. The code complies but does not run as expected. I am trying to make the code report back an exclamation mark if the number is out of bounds/larger than the last position of the source text, which is a string the user inputs, so the length cannot be predefined. Exception is 'StringIndexOutOfBoundsException'
TDLR num is an int, sourcetext is a string, both are inputs. Exception: when code should output an '!' instead.
import java.util.Scanner;
public class Temp {
public static void main(String[] args) {
Scanner sc;
int result, num= 0, end = -2, temp, infolost, count;
String word, sourcetext, answer, space= " ";
String sourcetext2, temp2;
char input, result2, chalost;
sc = new Scanner(System.in);
System.out.println("please enter sourcetext");
sourcetext = sc.nextLine(); // user inputs source text
sourcetext = sourcetext.toLowerCase(); // converts sourcetext into lowercase
System.out.print("Would you like to 1 encrypt, or 2 decrypt?");
answer = sc.next(); // user inputs choice
if (answer.equals("1")||(answer.equals("encrypt"))) {
System.out.println("Please enter at least one word to encrypt");
word = sc.next(); // user inputs one word
for (int i= 0; i < word.length(); i++) {
temp = sourcetext.indexOf(word.charAt(i)); // uses index to convert char positions int num
System.out.print(space + temp + space);
}
System.out.print(space + end);
}
else if (answer.equals("2")||(answer.equals("decrypt"))) {
System.out.println("Please enter digits, with one space between each. End with -2");
while (num > -2) {
num = sc.nextInt(); // num to decrypt
if (num > -2) {
result2 = sourcetext.charAt(num); // num converted into characters
System.out.print(result2);
} else if (num > sourcetext.length()) {
System.out.print("!");
} else if (num<0) {
System.out.print("end");
}
}
}
}
}
Try it like this:
int stringLength = sourcetext.length();
if (num > stringLength) {
System.out.print("!");
}
else if (num<0) {
System.out.print("end");
}
This could lead to an IndexOutOfBoundsException - since -1 is greater than -2 - but still out of bounds...
if (num > -2){
result2 = sourcetext.charAt(num); // num converted into characters
System.out.print(sourcetext.indexOf(num));
}
Edit: Unless the users input is -2 - the first if-Statement will always run... You probably need to re-work the logic there.
Edit2: If num is -1 sourcetext.charAt(num); leads to an IndexOutOfBounds. Do something like
if(num == -2) {
System.out.print("end");
} else if (num >= 0 && num < sourcetext.lenght()) {
// index ok
result2 = sourcetext.charAt(num); // num converted into characters
System.out.print(result2);
} else {
// index out of bounds
System.out.print("!");
}

I can't restrict my program to accept only binary numbers

I'm creating a program for my gui number converter. I want my program to ask user a binary string and if he does not enter a binary number, the program will show him error message and will ask him to enter again. The problem is that I can add restriction to alphabets but when it comes to numbers then it fails or it keeps showing the error message.
import java.util.*;
public class test {
Scanner key = new Scanner(System.in);
String in;
int b;
public test(){
do{
System.out.println("Enter the binary string of 5 numbers");
in = key.nextLine();
int i,j;
char ch;
for (i=0 ; i<=5 ; i++){
b = 0;
ch = in.charAt(i);
j = ch;
if (Character.isDigit(ch) && ch<=0 && ch>=1)
b = 1;
else
System.out.println("Please enter a binary number (1 , 0)");
break;
//b = 1;
}
}while(b != 1);
int c;
c = Integer.parseInt(in);
System.out.println("your number is: " + c );
}
public static void main (String args[]){
test obj = new test();
}
}
ch<=0 && ch>=1 does not do what you think it does. The character codes for "0" and "1" are 48 and 49, so you should check for those instead. Also, your >= comparators are backwards, but that's not really the clearest way to write this code. And since you're comparing for just those two values, Character.isDigit(ch) is redundant.
Try one of these:
ch == 48 || ch == 49
ch == '0' || ch == '1'
Scanner has an overloaded nextInt method that uses a radix
int binaryNumber = scanner.nextInt(2);
1) First logic error here for (i=0 ; i<=5 ; i++) replace i<=5 to i<5
2) change the if else condition like below
if (Character.isDigit(ch) && (ch == '0' || ch == '1'))
{
b = 1;
}
else
{
System.out.println("Please enter a binary number (1 , 0)");
break;
}

How to recognize an input of numbers and letters

I've fixed my code so that it recognizes if their's 4 digits and less or 6 digits and higher but now I want to know whether or not it contains letters within the numbers.
The code below detects the letters and prints the line I want only when I input 5 letters, and I want it to detect even if their's more digits than letters or more letters than digits.
String digit;
String regex;
String regex1;
regex = "[0-9]{5}";
regex1 = "^[a-zA-Z0-9]{5}";
String test;
String validLength= "5";
char one, two, three, four, five;
{
System.out.println("In this game, you will have to input 5 digits.");
do
{
System.out.println("Please input 5-digits.");
digit = console.next();
test = digit.replaceAll("[a-zA-Z]", "");
if (digit.matches(regex))
{
one = (char)digit.charAt(0);
two = (char)digit.charAt(1);
three = (char)digit.charAt(2);
four = (char)digit.charAt(3);
five = (char)digit.charAt(4);
System.out.println((one + two + three + four + five) / 2 );
}
else if (test.length() > 5 || test.length() < 5)
{
System.out.println("You have letters in there.");
}
else if (digit.matches(regex1))
{
test = digit.replaceAll("[a-zA-Z]", "");
System.out.println("You have letters in there.");
}
else
if (digit.length() < 5)
{
System.out.println("You don't have enough digits.");
}
else if (digit.length() > 5)
{
System.out.println("You have to many digits.");
}
} while (!digit.matches(regex));
I won't go into regex here because honestly I think there is some misunderstandings that should be dealt with far before the road of niceties is undergone; plus, I'm no expert and I personally think they are more like rights of passage.
Anyway, let's start from the beginning, or at least when you determine they've entered a valid digit,
if (digit.matches(regex)).
Let's say...
String digits = "12345";
System.out.println(getSum(digits) / 2);
where...
public int getSum(String digits) {
int sum = 0;
for(int i = sum; i < digits.length(); i++) {
sum += digits.charAt(i);
}
return sum;
}
Same as your System.out.println((one + two + three + four + five) / 2 );.
I hope the output of 127 makes you smile.
Going out on a limb, and since you didn't speak of the "char" value sum that, you expected it to treat your chars as decimal digits. Well, that would result in 7. I only guess because of the whole (char)charAt() thing. This -> (char)charAt() sort of shows a lack of understanding that would make the use of regex highly questionable, IMHO of course.
Beyond that else if (test.length() > 5 && test.length() < 5). This says, "if test's length is greater AND less than 5"! Without using some mathematical paradox, tell me that number.
So, on to your question -
but now i want to know whether or not it contains letters within the
numbers.
well let's look at how finding out if any non-digit exists might be done - without regex so we can understand it...
public boolean containsNonDigits(String digits) {
for(int i = 0; i < digits.length(); ++i) {
if(Character.isDigit(digits.charAt(i))) {
continue;
} else {
return true;
}
}
return false;
}
This says, "if the character is a digit keep going; everything's fine, otherwise false".
The other "question" -
i want it to detect even if their's more digits than letters or more
letters than digits.
is an "additive" to the method above so I'll leave that one to you.
You can use Charachter.isDigit(char) and Charachter.isLetter(char) methods.
Here code sample that implements what you asked:
public static void main(String[] args)
{
System.out.println("In this game, you will have to input 5 digits.");
int validLength = 5;
boolean valid = false;
Scanner console = new Scanner(System.in);
while (!valid)
{
System.out.println("Please input 5-digits.");
String digit = console.next();
if (digit.length() != validLength)
{
//if length not valid, mark as not valid and return to next iteration
valid = false;
String message = digit.length() < validLength ? "You don't have enoght digits." : "You have to many digits.";
System.out.println(message);
continue;
}
//here digit.length = 5
int nDigits = 0,nLetters = 0,sum = 0;
for (int i = 0; i < digit.length(); i++)
{
Character ch = digit.charAt(i);
if (Character.isDigit(ch))
{
nDigits++;
sum += Integer.parseInt(ch.toString());
}
else if (Character.isLetter(ch)) {
nLetters++;
}
}
if (nLetters == 0 /* no letters */
|| /* and */
nDigits == validLength /* all chars are digits */)
{
System.out.println(sum/2);
valid = true;
}
else{
System.out.println("You have letters in there.");
}
}
}

Using strings in Java to accept a password based on certain requirements

This program is suppose to accept input into a string, the password. The program then checks to make sure that the password is at least 8 characters in length, contains at least 2 digits, and only contains letters and numbers. I can't seem to get the correct way to count at least 2 digits, although from what i've seen this method should work.
This is the error I get
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 10
at java.lang.String.charAt(String.java:658)
at Password.main(Password.java:35)
import java.util.*;
public class Password{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
String s;
int numbers = 0;
System.out.println("Enter a password (Must contain only letters and numbers, ");
System.out.print("minimum of 8 characters with atleast two numbers): ");
s = input.nextLine();
while(1==1){
if (s.length() < 8){
System.out.println("Password is too short");
System.out.println("Enter correctly formatted password");
s = input.nextLine();
continue;
}
if (s.matches("^[a-zA-Z0-9_]+$")){
}
else{
System.out.println("Password may only contain Letters and Digits");
System.out.println("Enter correctly formatted password");
s = input.nextLine();
continue;
}
int i;
for (i = 0; i <= s.length(); i++){
if (Character.isDigit(s.charAt(i))){
numbers++;
}
}
if (numbers < 2){
System.out.println("Password must contain atleast 2 digits");
System.out.println("Enter correctly formatted password");
s = input.nextLine();
continue;
}
break;
}
while (0==0){
System.out.println("Reenter Password to see if it matches");
String a = input.nextLine();
if (s.equals(a)){
System.out.println("Password matches!");
break;
}
else{
System.out.println("Password does not match");
continue;
}
}
}
}
In your for loop, you should not allow i to equal s.length()
for (i = 0; i <= s.length(); i++)
ArrayIndexOutOfBoundsException is caused when you try to access s[s.length()].
This statement is getting Exception because of using index from 0 to length. Instead of that use 0 to < length.
for (i = 0; i <= s.length(); i++){
if (Character.isDigit(s.charAt(i))){
numbers++;
}
}
Replace for (i = 0; i <= s.length(); i++){ by for (i = 0; i < s.length(); i++){
Example: Let's say the string s = "abc". s.length() = 3. s.charAt(0)= "a", s.charAt(1)= "b", s.charAt(2)= "c". s.charAt(3) does not exist and throw an exception.

Categories