logic error? diving 2 int that result in a float - java

I am writing a combat simulator. My attacker class initiates an attack and my defender class is supposed to block it. manager is my main class that computes and prints the results. My problem is with my highRatio, mediumRatio and lowRatio variables. If they are not equal to 1 all of them are set to zero. Any ideas as to what may be going?
//defender class
public int defenseSelector(int highAtkCounter, int mediumAtkCounter, int lowAtkCounter, int rounds, int roundCounter)
{
Random defenseTypeGenerator;
int defense = 0;
float highRatio;
float mediumRatio;
float lowRatio;
defenseTypeGenerator = new Random();
int defenseType = defenseTypeGenerator.nextInt(MAX_ROUNDS) + 1;
highRatio = highAtkCounter/roundCounter;
mediumRatio = mediumAtkCounter/roundCounter;
lowRatio = lowAtkCounter/roundCounter;
if(roundCounter > 3 && roundCounter <= rounds) //AI portion
{
if (highRatio > mediumRatio && highRatio > lowRatio)
{
defense = HIGH;
}
else if (mediumRatio > highRatio && mediumRatio > lowRatio)
{
defense = MEDIUM;
}
else if (lowRatio > highRatio && lowRatio > mediumRatio)
{
defense = LOW;
}
else
{
System.out.println("AI ERROR ratios " + highRatio + " " + mediumRatio + " " + lowRatio);
System.out.println("AI ERROR atkCounters " + highAtkCounter + " " + mediumAtkCounter + " " + lowAtkCounter);
System.out.println("AI ERROR rCounters " + roundCounter);
//manager class
while(roundCounter <= rounds)
{
int attack = theAttacker.attackSelector(high, medium, low);
int highAtkTracker = theAttacker.countHighAtks(attack);
System.out.println("DEBUG " + attack);
System.out.println("DEBUG " + highAtkTracker);
int mediumAtkTracker = theAttacker.countMediumAtks(attack);
System.out.println("DEBUG " + attack);
System.out.println("DEBUG " + mediumAtkTracker);
int lowAtkTracker = theAttacker.countLowAtks(attack);
System.out.println("DEBUG " + attack);
System.out.println("DEBUG " + lowAtkTracker);
highAtkCounter = highAtkCounter + highAtkTracker;
mediumAtkCounter = mediumAtkCounter + mediumAtkTracker;
lowAtkCounter = lowAtkCounter + lowAtkTracker;
int defense = theDefender.defenseSelector(highAtkCounter, mediumAtkCounter, lowAtkCounter, rounds, roundCounter);

In java any arithmetic operation with an integer results in an integer.
Therefore you must cast the integer into the floating point type explicitly:
highAtkCounter = highAtkCounter + (float)highAtkTracker;
mediumAtkCounter = mediumAtkCounter + (float)mediumAtkTracker;
lowAtkCounter = lowAtkCounter + (float)lowAtkTracker;

Related

I can't get the right answer to Project Euler Q8 with Java

There are 2 answers. The first answer is for 4 consecutive numbers and the answer is provided: 5832. The 2nd answer is for 13 consecutive numbers and it's the answer they want me to input. This answer is: 23514624000.
My answer for the 1st questions is: 29760696 which is impossible and way off
public class test {
public static void main(String[] args)
{
String big = "73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450"
;
//System.out.println(big.length());
int product=1;
int newProduct=0;
for(int i=0;i<big.length()-1-4;i++)
{
product=1;
for(int j=i+1;j<i+5;j++)
{
product=(big.charAt(i)-48)*(big.charAt(j)-48)*product;
}
if(product>newProduct)
{
newProduct=product;
}
}
System.out.println(newProduct);
}
My answer for the 2nd question is: 2135048192 and is a lot closer. Why is this the case? My code is as follows. thanks
public class test {
public static void main(String[] args)
{
String big = "73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450"
;
//System.out.println(big.length());
int product=1;
int newProduct=0;
for(int i=0;i<big.length()-1-13;i++)
{
product=1;
for(int j=i+1;j<i+14;j++)
{
product=(big.charAt(i)-48)*(big.charAt(j)-48)*product;
}
if(product>newProduct)
{
newProduct=product;
}
}
System.out.println(newProduct);
}
You are experiencing integer overflow (use a long). Character.digit(char,int) (where the second argument is the radix) can get you the int value of a char). Also, you can use Math.max(long, long) to get the maximum of two long(s). Putting that together, it might look something like
long max = 0;
for (int i = 0; i < big.length() - 13; i++) {
String str = big.substring(i, i + 13);
long product = 1;
for (char ch : str.toCharArray()) {
product *= Character.digit(ch, 10);
}
max = Math.max(max, product);
}
System.out.println(max);
And I get (the expected)
23514624000

Working with BigIntegers

I creating a program where it takes a base unit in the metric system. (Say grams.) And then when you select a prefix changes it to the equivalent amount. (Such as 1000 grams when you select Kilo would change it to 1 Kilogram.)
Problem is when I run the code it'll always end up as zero, which makes me think I'm manipulating the BigIntegers wrong. (I'm using VERY large numbers due to some prefixes being very small or very large beyond the usual long number.)
Here is the code:
import java.util.Scanner;
import java.math.BigInteger;
public class BaseMetricUnits {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Hello, World!");
float meter = 1;
float kilogram = 1;
float second = 1;
float ampere = 1;
float kelvin = 1;
float mole = 1;
float candela = 1;
PrefixConverter();
}
public static void PrefixConverter()
{
BigInteger Yocto = BigInteger.valueOf((long) 0.00000000000000000000000);
BigInteger Zepto = BigInteger.valueOf((long) 0.000000000000000000001);
BigInteger Atto = BigInteger.valueOf((long) 0.000000000000000001);
BigInteger Femto = BigInteger.valueOf((long) 0.000000000000001);
BigInteger Pico = BigInteger.valueOf((long)0.000000000001);
BigInteger Nano = BigInteger.valueOf((long)0.000000001);
BigInteger Micro = BigInteger.valueOf((long)0.000001);
BigInteger Milli = BigInteger.valueOf((long)0.001);
BigInteger Centi = BigInteger.valueOf((long)0.01);
BigInteger Deci = BigInteger.valueOf((long)0.1);
BigInteger Deca = BigInteger.valueOf((long)10);
BigInteger Hecto = BigInteger.valueOf((long)100);
BigInteger Kilo = BigInteger.valueOf((long)1000);
BigInteger Mega = BigInteger.valueOf((long)1000000);
BigInteger Giga = BigInteger.valueOf((long)1000000000);
BigInteger Tera = new BigInteger("1000000000000");
BigInteger Peta = new BigInteger("1000000000000000");
BigInteger Exa = new BigInteger("1000000000000000000");
BigInteger Zetta = new BigInteger("1000000000000000000000");
BigInteger Yotta = new BigInteger("1000000000000000000000000");
long Amount;
double Prefix;
String Units = "";
BigInteger translatedResult;
BigInteger Result;
Scanner inputDevice = new Scanner(System.in);
System.out.print("Please enter the type of unit to be used. (meters, grams, etc.) >> ");
Units = inputDevice.next();
System.out.print("Please enter an amount to be translated >> ");
Amount = inputDevice.nextLong();
System.out.print("Please choose one of the following Prefixes to translate to. ");
System.out.print(" 1 - Yocto ");
System.out.print(" 2 - Zepto ");
System.out.print(" 3 - Atto ");
System.out.print(" 4 - Femto ");
System.out.print(" 5 - Pico ");
System.out.print(" 6 - Nano ");
System.out.print(" 7 - Micro ");
System.out.print(" 8 - Milli ");
System.out.print(" 9 - Centi ");
System.out.print(" 10 - Deci ");
System.out.print(" 11 - Deca ");
System.out.print(" 12 - Hecto ");
System.out.print(" 13 - Kilo ");
System.out.print(" 14 - Mega ");
System.out.print(" 15 - Giga ");
System.out.print(" 16 - Tera ");
System.out.print(" 17 - Peta ");
System.out.print(" 18 - Exa ");
System.out.print(" 19 - Zetta ");
System.out.print(" 20 - Yotta ") ;
Prefix = inputDevice.nextDouble();
if(Prefix == 1)
{
Result = Yocto.multiply(BigInteger.valueOf(Amount));
translatedResult = Yocto.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Yocto" + Units + ".");
}
if(Prefix == 2)
{
Result = Zepto.multiply(BigInteger.valueOf(Amount));
translatedResult = Zepto.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Zepto" + Units + ".");
}
if(Prefix == 3)
{
Result = Atto.multiply(BigInteger.valueOf(Amount));
translatedResult = Atto.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Atto" + Units + ".");
}
if(Prefix == 4)
{
Result = Femto.multiply(BigInteger.valueOf(Amount));
translatedResult = Femto.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Femto" + Units + ".");
}
if(Prefix == 5)
{
Result = Pico.multiply(BigInteger.valueOf(Amount));
translatedResult = Pico.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Pico" + Units + ".");
}
if(Prefix == 6)
{
Result = Nano.multiply(BigInteger.valueOf(Amount));
translatedResult = Nano.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Nano" + Units + ".");
}
if(Prefix == 7)
{
Result = Micro.multiply(BigInteger.valueOf(Amount));
translatedResult = Micro.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Micro" + Units + ".");
}
if(Prefix == 8)
{
Result = Milli.multiply(BigInteger.valueOf(Amount));
translatedResult = Milli.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Milli" + Units + ".");
}
if(Prefix == 9)
{
Result = Centi.multiply(BigInteger.valueOf(Amount));
translatedResult = Centi.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Centi" + Units + ".");
}
if(Prefix == 10)
{
Result = Deci.multiply(BigInteger.valueOf(Amount));
translatedResult = Deci.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Deci" + Units + ".");
}
if(Prefix == 11)
{
Result = Deca.multiply(BigInteger.valueOf(Amount));
translatedResult = Deca.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Deca" + Units + ".");
}
if(Prefix == 12)
{
Result = Hecto.multiply(BigInteger.valueOf(Amount));
translatedResult = Hecto.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Hecto" + Units + ".");
}
if(Prefix == 13)
{
Result = Kilo.multiply(BigInteger.valueOf(Amount));
translatedResult = Kilo.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Kilo" + Units + ".");
}
if(Prefix == 14)
{
Result = Mega.multiply(BigInteger.valueOf(Amount));
translatedResult = Mega.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Mega" + Units + ".");
}
if(Prefix == 15)
{
Result = Giga.multiply(BigInteger.valueOf(Amount));
translatedResult = Giga.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Giga" + Units + ".");
}
if(Prefix == 16)
{
Result = Tera.multiply(BigInteger.valueOf(Amount));
translatedResult = Tera.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Tera" + Units + ".");
}
if(Prefix == 17)
{
Result = Peta.multiply(BigInteger.valueOf(Amount));
translatedResult = Peta.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Peta" + Units + ".");
}
if(Prefix == 18)
{
Result = Exa.multiply(BigInteger.valueOf(Amount));
translatedResult = Exa.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Exa" + Units + ".");
}
if(Prefix == 19)
{
Result = Zetta.multiply(BigInteger.valueOf(Amount));
translatedResult = Zetta.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Zetta" + Units + ".");
}
if(Prefix == 20)
{
Result = Yotta.multiply(BigInteger.valueOf(Amount));
translatedResult = Yotta.divide(BigInteger.valueOf(Amount));
System.out.println("You have " + Result + " " + Units + " which translates to " + translatedResult + "Yotta" + Units + ".");
}
else
{
System.out.println("Not a valid input.");
}
}
}
Thanks for your help.
BigInteger can only store integers, and so is not a suitable data type for this application. I strongly recommend replacing it with BigDecimal.
You should also use string representations of the fractions to initialize:
BigDecimal Zepto = new BigDecimal("0.000000000000000000001");
BigDecimal Atto = new BigDecimal("0.000000000000000001");
BigDecimal Femto = new BigDecimal("0.000000000000001");
BigDecimal Pico = new BigDecimal("0.000000000001");
BigDecimal Nano = new BigDecimal("0.000000001");
Comments on this answer and on the question indicate a concern with using BigDecimal to store the larger numbers. This program illustrates the fact that it is not an issue:
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
BigDecimal googol = new BigDecimal("1e100");
System.out.println(googol);
System.out.println(googol.add(BigDecimal.ONE));
}
}
Output:
1E+100
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001

Java: How can I make this calculus method on limits more efficient?

how can I initialize all of my variables more easier?
is there a calculus package?
is there a more efficient solution overall?
import java.util.Scanner;
public class limits {
public static void main(String[] args)
{
String introMessage = " ***Calculus: Limits***" + "\n"
+ "This application uses the method of exhaustion" + "\n"
+ "to test limits. You enter the number that x" + "\n"
+ "approches and this program will give you three" + "\n"
+ "numbers on either side of the limit showing" + "\n"
+ "closer approximations of the limit.";
System.out.println(introMessage);
System.out.println();
String polynomialMessage = "Our function: " + "\n"
+ " lim f(x) = x^2 + x + 1 = L" + "\n"
+ "x -> a";
System.out.println(polynomialMessage);
System.out.println();
System.out.println("As x approaches a, what will our limit L be?");
System.out.println();
can I initialize all of these at once?
// initialize variables
double belowAOne = 0.0;
double belowATwo = 0.0;
double belowAThree = 0.0;
double belowAFour = 0.0;
double aboveAOne = 0.0;
double aboveATwo = 0.0;
double aboveAThree = 0.0;
double aboveAFour = 0.0;
double totalBAOne = 0.0;
double totalBATwo = 0.0;
double totalBAThree = 0.0;
double totalBAFour = 0.0;
double totalAAOne = 0.0;
double totalAATwo = 0.0;
double totalAAThree = 0.0;
double totalAAFour = 0.0;
double L = 0;
// create a Scanner object named sc
Scanner sc = new Scanner(System.in);
// perform invoice calculations until choice isn't equal to "y" or "Y"
String choice = "y";
while (!choice.equalsIgnoreCase("n"))
{
System.out.println("Please enter a whole number between 1 and 10 for a: ");
double a = sc.nextDouble();
if (a > 0 && a <=10 )
{
// calculate L
L = (a*a) + a + 1;
// create values that approaches a
belowAOne = a - .5;
belowATwo = a - .1;
belowAThree = a - .01;
belowAFour = a - .001;
aboveAOne = a + .5;
aboveATwo = a + .1;
aboveAThree = a + .01;
aboveAFour = a + .001;
totalBAOne = (belowAOne * belowAOne) + belowAOne + 1;
totalBATwo = (belowATwo * belowATwo) + belowATwo + 1;
totalBAThree = (belowAThree * belowAThree) + belowAThree + 1;
totalBAFour = (belowAFour * belowAFour) + belowAFour + 1;
totalAAOne = (aboveAOne * aboveAOne) + aboveAOne + 1;
totalAATwo = (aboveATwo * aboveATwo) + aboveATwo + 1;
totalAAThree = (aboveAThree * aboveAThree) + aboveAThree + 1;
totalAAFour = (aboveAFour * aboveAFour) + aboveAFour + 1;
String chart = " x " + "x^2 + x + 1" + "\n"
+ "---------+--------------" + "\n"
+ " " + belowAOne + " : " + totalBAOne + "\n"
+ " " + belowATwo + " : " + totalBATwo + "\n"
+ " " + belowAThree + " : " + totalBAThree + "\n"
+ " " + belowAFour + " : " + totalBAFour + "\n"
+ " " + " a " + " : " + "L" + "\n"
+ " " + aboveAFour + " : " + totalAAFour + "\n"
+ " " + aboveAThree + " : " + totalAAThree + "\n"
+ " " + aboveATwo + " : " + totalAATwo + "\n"
+ " " + aboveAOne + " : " + totalAAOne + "\n";
System.out.println();
System.out.println();
System.out.println();
System.out.println(chart);
System.out.println();
System.out.println("As X approaches " + a + ", our guess "
+ "for L is: " + L);
System.out.println();
// end the program
choice = "n";
}
else
{
System.out.println();
System.out.println("***Invalid Entry***");
System.out.println();
}
}
}
}
Is there a better way to write this program?
or you could use a loop instead like this:
double[] belowA = {a - .5, a - .1, a - .01, a - .001};
double[] totalBA = new double[4];
for(int i = 0; i < 4; ++i) {
totalBA[i] = (belowA[i] * belowA[i]) + belowA[i] + 1;
}
also with a StringBuilder / StringBuffer
and finally you could create a method to handle below/above in the same way without duplicated code

Methods/functions in Java

With the given code I was given the directions: Java lets us use Methods/Functions so we can store procedures that we may use more than once, so I would like you to update your code where there is common tasks it can be done inside a method/function. Any idea how to do this?
package fifthAssignment;
public class Arithmetic {
public static void main(String[] args) {
// setting up the variable firstNumber and secondNumber
int length = args.length;
if (length != 3) {
System.out.println("Your suppose to enter an int, int then an operation sign like +,-,X or /.");
return;
}
int firstNumber = Integer.parseInt(args[0]);
int secondNumber = Integer.parseInt(args[1]);
int addition = firstNumber + secondNumber;
int minus = firstNumber - secondNumber;
int division = firstNumber / secondNumber;
int multiply = firstNumber * secondNumber;
String arithmetic = args[2];
if (arithmetic.equals("+")) {
System.out.println(args[0] + " " + args[2] + " " + args[1] + " = " + addition);
} else if (arithmetic.equals("-")) {
System.out.println(args[0] + " " + args[2] + " " + args[1] + " = " + minus);
} else if (arithmetic.equals("/")) {
System.out.println(args[0] + " " + args[2] + " " + args[1] + " = " + division);
// I could not use "*" operator as it was looking to pull down all
// the files associated with this program instead of
// using it the way I intended to use it. So in this case I changed
// the "*" to "x" so that I can get the solution you
// were looking for.
} else if (arithmetic.equals("x")) {
System.out.println(args[0] + " " + args[2] + " " + args[1] + " = " + multiply);
}
// following prints out to the console what the length of each argument
// is.
System.out.println(args[0] + " has the length of " + args[0].length());
System.out.println(args[1] + " has the length of " + args[1].length());
if (arithmetic.equals("+")) {
int total = String.valueOf(addition).length();
System.out.println(addition + " has the length of " + total);
}else if (arithmetic.equals("-")) {
int total = String.valueOf(minus).length();
System.out.println(minus + " has the length of " + total);
}else if (arithmetic.equals("/")) {
int total = String.valueOf(division).length();
System.out.println(division + " has the length of " + total);
} else if (arithmetic.equals("x")) {
int total = String.valueOf(multiply).length();
System.out.println(multiply + " has the length of " + total);
}
}
}
I'll provide a singular example, but you should do this on your own.
You have this in your code:
System.out.println(addition + " has the length of " + total);
Instead, you could potentially create a method that would work with two ints:
public void printStatus(int check, int length) {
System.out.println(check + " has the length of " + length);
}
Which would allow you to call
printStatus(addition, total);
This is just a rough example, but you can wrap a "process" of code in a method, and pass the necessary parameters needed to execute the method to it.
package fifthAssignment;
public class Arithmetic {
public static void main(String[] args) {
// setting up the variable firstNumber and secondNumber
int length = args.length;
if (length != 3) {
System.out.println("Your suppose to enter an int, int then an operation sign like +,-,X or /.");
return;
}
int firstNumber = Integer.parseInt(args[0]);
int secondNumber = Integer.parseInt(args[1]);
int addition = firstNumber + secondNumber;
int minus = firstNumber - secondNumber;
int division = firstNumber / secondNumber;
int multiply = firstNumber * secondNumber;
String arithmetic = args[2];
// following prints out to the console what the length of each argument
// is.
System.out.println(args[0] + " has the length of " + args[0].length());
System.out.println(args[1] + " has the length of " + args[1].length());
performOperation(arithmetic);
}
public void performOperation(String arithmetic) {
if (arithmetic.equals("+")) {
int total = String.valueOf(addition).length();
System.out.println(addition + " has the length of " + total);
} else if (arithmetic.equals("-")) {
int total = String.valueOf(minus).length();
System.out.println(minus + " has the length of " + total);
} else if (arithmetic.equals("/")) {
int total = String.valueOf(division).length();
System.out.println(division + " has the length of " + total);
} else if (arithmetic.equals("x")) {
int total = String.valueOf(multiply).length();
System.out.println(multiply + " has the length of " + total);
}
}
}

Longest monotonic subsequence algorithm NOT longest increasing algorithm

I have some numbers at the input:
1 1 7 3 2 0 0 4 5 5 6 2 1
And I look for a longest monotonic subsequence and what is the sum of this subsequence. The result is:
6 20
I cannot find the algorithm at the internet. Do you own/found one? This is about longest monotonic not longest increasing subsequence.
Definition of monotonic: http://en.wikipedia.org/wiki/Monotonic_function
I know that someone will ask: What have you tried? So i tried writing it(please don't check it I only post it so no one asks that question above I look for different algorithm->optimal one)
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Rozwiazanie {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//2^63 > 10^16 = 10^7 * 10^9 longi starcza
//10^9 inty starcza
//int 32 bity, long 64 bity
long podsuma = 0;
int dlugosc = 0;
int maxDlugosc = 0;
long maxPodsuma = 0;
int poczatekRownych = 0;
int poprzedniWyraz = 0, aktualnyWyraz;//uwaga jakby cos nie gralo w sprawdzarce zmien typ na long
boolean czyRosnacy = false, rowny = false;
String[] splittedLinia = br.readLine().split((char) 32 + "");//moglaby byc " " ale tak na wszelki wypadek nie ma chuja zeby sie popierdolilo teraz nawet na linuxie
for (int i = 0; i < splittedLinia.length; i++) {
if (i == 0) {
aktualnyWyraz = Integer.parseInt(splittedLinia[0]);
maxDlugosc = dlugosc = 1;
maxPodsuma = podsuma = aktualnyWyraz;
if (splittedLinia.length > 1) {
int nastepnyWyraz = Integer.parseInt(splittedLinia[1]);
czyRosnacy = nastepnyWyraz > aktualnyWyraz;
rowny = nastepnyWyraz == aktualnyWyraz;
}
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 1);
} else {
aktualnyWyraz = Integer.parseInt(splittedLinia[i]);
System.out.println(rowny);
if (aktualnyWyraz == poprzedniWyraz && rowny) {
podsuma += aktualnyWyraz;
dlugosc++;
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 2);
} else if (rowny) {
rowny = false;
czyRosnacy = aktualnyWyraz > poprzedniWyraz;
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 3);
}
if (!rowny) {
if (aktualnyWyraz >= poprzedniWyraz && czyRosnacy) {
podsuma += aktualnyWyraz;
dlugosc++;
System.out.println("akt:" + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 4);
} else if (aktualnyWyraz <= poprzedniWyraz && !czyRosnacy) {
podsuma += aktualnyWyraz;
dlugosc++;
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 5);
} else {
// if (aktualnyWyraz == poprzedniWyraz) {
rowny = true;
// } else {
if (maxDlugosc < dlugosc) {
maxDlugosc = dlugosc;
maxPodsuma = podsuma;
}
podsuma = poprzedniWyraz + aktualnyWyraz;
dlugosc = 2;
czyRosnacy = aktualnyWyraz > poprzedniWyraz;
rowny = aktualnyWyraz == poprzedniWyraz;
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 6);
//}
}
}
}
poprzedniWyraz = aktualnyWyraz;
}
System.out.println(maxDlugosc + " " + maxPodsuma);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//65 87 47 5 12 74 25 32 78 44 40 77 85 4 29 57:
try this one:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Rozwiazanie {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] splittedLinia = br.readLine().split((char) 32 + "");//moglaby byc " " ale tak na wszelki wypadek nie ma chuja zeby sie popierdolilo teraz nawet na linuxie
int aktualnyWyraz = Integer.parseInt(splittedLinia[0]);//uwaga jakby cos nie gralo w sprawdzarce zmien typ na long
int poprzedniWyraz = 0;
long podsumaRosnaca = aktualnyWyraz;
long podsumaSpadajaca = aktualnyWyraz;
int dlugoscRosnaca = 1;
int dlugoscSpadajaca = 1;
int maxDlugosc = 1;
long maxPodsuma = aktualnyWyraz;
int czyRosnacy = 0; // 0 -- nie znane (jezeli w poczatku wszystkie liczby sa rowne), 1 -- rosnacy, -1 -- spadajacy
boolean rowny = false;
System.out.println("akt: " + aktualnyWyraz + " dlR: " + dlugoscRosnaca + " podsumaR: " + podsumaRosnaca + " dlP: " + dlugoscSpadajaca + " podsumaP: " + podsumaSpadajaca);
for (int i = 1; i < splittedLinia.length; i++) {
poprzedniWyraz = aktualnyWyraz;
aktualnyWyraz = Integer.parseInt(splittedLinia[i]);
if (aktualnyWyraz == poprzedniWyraz) {
podsumaRosnaca += aktualnyWyraz;
podsumaSpadajaca += aktualnyWyraz;
dlugoscRosnaca++;
dlugoscSpadajaca++;
rowny = true;
} else { // rozne liczby
if (aktualnyWyraz > poprzedniWyraz) { // rosnie
podsumaRosnaca += aktualnyWyraz;
dlugoscRosnaca++;
if (rowny) {
dlugoscSpadajaca = 1;
podsumaSpadajaca = 0;
rowny = false;
}
if (czyRosnacy < 0) {
if (dlugoscSpadajaca > maxDlugosc) {
maxDlugosc = dlugoscSpadajaca;
maxPodsuma = podsumaSpadajaca;
}
podsumaSpadajaca = 0;
dlugoscSpadajaca = 1;
}
czyRosnacy = 1;
} else { // spada
podsumaSpadajaca += aktualnyWyraz;
dlugoscSpadajaca++;
if (rowny) {
dlugoscRosnaca = 1;
podsumaRosnaca = 0;
rowny = false;
}
if (czyRosnacy == 1) {
if (dlugoscRosnaca > maxDlugosc) {
maxDlugosc = dlugoscRosnaca;
maxPodsuma = podsumaRosnaca;
}
podsumaRosnaca = 0;
dlugoscRosnaca = 1;
}
czyRosnacy = -1;
}
}
System.out.println("akt: " + aktualnyWyraz + " dlR: " + dlugoscRosnaca + " podsumaR: " + podsumaRosnaca + " dlP: " + dlugoscSpadajaca + " podsumaP: " + podsumaSpadajaca);
}
System.out.println("maxDlugosc " + maxDlugosc + " maxPodsuma " + maxPodsuma);
} catch (Exception e) {
e.printStackTrace();
}
}
}
what I had to change:
you need a counter [dlugosc] (+ sum [podsuma]) for ascending
[rosnacy] and descending [spadajacy] values, as you need to count
both when the values are the same [rowny].
I changed boolean "rowny"
[equal] to int, as I thought that there are 3 values possible:
ascending, descending or unknown. If there are several equal values
at the beginning, there's all the time "unknown".
this program needs at least one number, but therefore you don't need to check in every
iteration of the loop whether i == 0 or not.
Going through the
numbers, I have to check several things, most important is, whether
the actual value [aktualnyWyraz] and the last used value
[poprzedniWyraz] are the same (then all counters and sums have to be
changed) or different. Different can mean ascending or descending, so
we have to increment the related counters and sum up the related sum.
What happens the "opposite" variables? Well, we need to check whether
the counter is bigger then the maximum one (so maybe these values are
useful for the result) and then set them back to their start.

Categories

Resources