Number format and index out of bound. - java

Java android is complain about how to make parse Integer from String array. My string array has almost 300 numbers. When I make the same code but parse it as float, the code works fine I don't want the decimal values. I just need the number itself. It is throwing java.lang.NumberFormatException: Invalid int: "97.601006". Would you mind to tell me what should I do. I also have one more question. I want to have the position/index of the peak value (Not the value itself) from my algorithm findPeaks. When I do peaks.get(i) the system is also crashing and says IndexOutOfBoundsException: Invalid index 24, size is 1
Thanks in advance.
String Adata = String.valueOf(stringBuilder);
String dataArray[];
dataArray = Adata.split("\\s+");
Log.i("TAG", "Size of dataArray: " + dataArray.length);
List String_TO_List = new ArrayList<Integer>();
int lastLength = dataArray.length - 1;
for (int i = 0; i < lastLength; i++) {
//the console pointed at this line with number format exception
int dataOfArray = Integer.parseInt(dataArray[i]);
if (dataOfArray > 170) {
String_TO_List.add(dataOfArray);
}
}
Log.i("TAG", "Size of list: " + String_TO_List.size());
List<Integer> List_Of_Peaks = findPeaks(String_TO_List);
Log.i(TAG, "Peaks" + List_Of_Peaks);
Peaks_num.setText(String.valueOf(List_Of_Peaks));
//my algorithm to find the peaks.
ArrayList<Float> peaks = new ArrayList<Float>();
float x1_n_ref = 0;
int alpha = 0; //0=down, 1=up.
int size = points.size();
for (int i = 0; i < size; i+=4) {
float IndexValues = points.get(i);
float delta = x1_n_ref - IndexValues;
if ( delta < 0) {
x1_n_ref = IndexValues;
alpha = 1;
} else if (alpha == 1 && delta > 0) {
peaks.add(x1_n_ref);
// here the system complain with Index exception. I want to know the poition or the index of the peak value so I can pass it to setText or Toast message.
peaks.get(i);
Log.i("TAG", "peak added: " + x1_n_ref);
alpha = 0;
} else if (alpha == 0 && delta > 0) {
x1_n_ref = IndexValues ;
}
//}
}
return peaks;
}

You can use Math.round(). It rounds a floating value to an integer. To round your value you have to parse it from String to double at first.
Replace your line
int dataOfArray = Integer.parseInt(dataArray[i]);
with
int dataOfArray = Math.round(Double.parseDouble(dataArray[i]));
Your example with "97.601006" will result in 98.

Related

Array of eight random Integers where each Integer has a difference of at least 15 from all others in the array?

I am trying to write a method that creates and returns an array of random Integers that has a length of eight and is within the range [25, 725].
Every Integer in the array must be higher or lower than every other Integer in the array by at least 15. However, my method isn't returning arrays that meet this requirement.
I set up a main() method that checks the output of my method 100,000 times, and throws an Exception if there are any Integers that are too close.
How can I create a method that will return an array of Integers where the difference between every Integer and every other Integer is at least 15?
public class Test {
public static void main(String[] args) throws Exception {
Integer[] distances = new Integer[8];
for (int i = 0; i < 100000; i++) {
distances = createPlanetDistances(distances.length);
// check distances for values within 15
for (int x = 0; x < distances.length; x++) {
for (int y = 0; y < distances.length; y++) {
if (x == y)
continue;
if (Math.abs(distances[x] - distances[y]) < 15) {
System.out.println(distances[x] + " " + distances[y]);
throw new Exception("Doesn't work");
}
}
}
for (int distance : distances)
System.out.print(distance + " ");
System.out.println(System.lineSeparator());
}
}
/**
* Creates an array of distances-from-the-sun for a given number of Planets.
* It does not allow distances to be within 15 of any other distance.
*
* #param planetAmount The number of distances to return.
* #return An array of distances-from-the-sun.
*/
private static Integer[] createPlanetDistances(int planetAmount) {
SplittableRandom random = new SplittableRandom();
final int min = 25;
final int max = 726;
HashSet<Integer> distanceSet = new HashSet<>();
// make sure there are no duplicate Integers
for(int i = 0; i < planetAmount; i++) {
int num = random.nextInt(min, max);
while (distanceSet.contains(num))
num = random.nextInt(min, max);
distanceSet.add(num);
}
// make sure each distance is 15 away from all others
Integer[] distances = distanceSet.toArray(new Integer[]{});
for(int i = 0; i < distances.length; i++) {
// check distances[i] with all other Integers
for (int j = 0; j < distances.length; j++) {
// do not compare an element with itself
if (j == i)
continue;
int difference = Math.abs(distances[i] - distances[j]);
if (difference < 15) {
while (difference < 15) {
distances[i] = random.nextInt(min, max);
difference = Math.abs(distances[i] - distances[j]);
}
// check all Integers again
System.out.println("HERE " + i + " " + j);
i = 0;
break;
}
}
}
return distanceSet.toArray(new Integer[]{});
}
}
To find COUNT numbers in range MIN to MAX (exclusive) that are more than DISTANCE apart, build a TreeSet and use the ceiling(...) method to find nearby values.
Example
final int DISTANCE = 15, MIN = 25, MAX = 726, COUNT = 8;
ThreadLocalRandom random = ThreadLocalRandom.current();
TreeSet<Integer> numbers = new TreeSet<>();
while (numbers.size() < COUNT) {
int value = random.nextInt(MIN, MAX);
Integer ceiling = numbers.ceiling(value - DISTANCE);
if (ceiling == null || ceiling > value + DISTANCE)
numbers.add(value);
}
System.out.println(numbers);
Sample Output
[86, 104, 120, 369, 425, 532, 682, 713]
You can always shuffle the result if you don't want them in ascending order.
How It Works
The ceiling method returns the least value in the set greater than or equal to the given value, or null if there is no such value.
So if e.g. value is 134 and DISTANCE is 15, then ceiling(value - DISTANCE) will find the smallest value that is >= 119. If that value is >= 149, then we know the nearby range 119-149 is clear and we can use the 134 value.
You are generating planetary orbits, so it should be OK to have monotonically increasing numbers. Each number you generate has constraints imposed on it by the following numbers, and in turn imposes constraints on them once it is generated.
Constraint: If you want to generate N orbits between min and max separated by D, then your bounds for the first orbit are [min, max - D * (N - 1)]. This is simply because you can't pack the following N - 1 planets into a space that is less than D * (N - 1).
You can update the second constraint as you go, since the new minimum is going to be the last generated number + D. Here is a simple O(n) implementation (assuming that genrating a random number is O(1)):
final int DISTANCE = 15, MIN = 25, MAX = 726, COUNT = 8;
Random random = Random();
orbits = new int[COUNT];
if(MAX - MIN < DISTANCE * COUNT) {
throw new IllegalArgumentException("Insert pithy comment about COUNT");
}
min = MIN;
for(int i = 0; i < COUNT; i++) {
max = MAX - DISTANCE * (COUNT - i - 1);
orbits[i] = random.nextInt(max - min + 1) + min;
min = orbits[i] + DISTANCE;
}
The following approach avoids acceptance/rejection sampling by removing the spacing requirement, generating values uniformly over the correspondingly shortened range, adding the spacing gaps back, and shuffling to yield the results in a randomized order.
static Random r = new Random();
public static ArrayList<Integer>
gen_array(int lower_bound, int upper_bound, int n, int separation) {
upper_bound -= (n - 1) * separation;
if(upper_bound < lower_bound) {
throw new IllegalArgumentException("Infeasible arguments");
}
ArrayList<Integer> ary = new ArrayList<>();
while(ary.size() < n) {
ary.add(lower_bound + r.nextInt(upper_bound - lower_bound + 1));
}
Collections.sort(ary);
for (int i = 0; i < n; ++i) {
ary.set(i, ary.get(i) + i * separation);
}
Collections.shuffle(ary);
return ary;
}
If you call it with a value of 8 for n, a lower_bound of 25, an upper_bound of 130, and a separation of 15, it yields the correct result immediately where an acceptance/rejection approach could take an awful lot of iterations to cough up the unique set of values for the answer.

How to print very big numbers to the screen

In an interview I had, I was asked to write a program that prints to the screen the numbers 1,2,3,4,5....until 99999999999999.....?(the last number to print is the digit 9 million times)
You are not allowed to use Big-Integer or any other similar object.
The hint I got is to use modulo and work with strings, I tried to think about it but haven't figured it out.
Thanks in advance
You need an array to store the number, and perform operations on the array.
Here's an example
public class BigNumberTest2 {
public static void main(String[] args) {
/*Array with the digits of the number. 0th index stores the most significant digit*/
//int[] num = new int[1000000];
//Can have a million digits, length is 1 + needed to avoid overflow
int[] num = {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int base = 10;
int step = 1;
String endNum = "100000000000000000000000000000000000000000000000000020";//Can have a million digits
while(true) {
//Increment by step
for(int carry = step, i = num.length - 1; carry != 0 && i >= 0; i--) {
int newDigit = num[i] + carry;
num[i] = newDigit % base;
carry = newDigit / base;
}
//Find the position of most significant digit
int mostSignificantDigitIndex = 0;
while(num[mostSignificantDigitIndex] == 0) {/*No need to check if firstNonZero < num.length, as start num >=0 */
mostSignificantDigitIndex++;
}
StringBuilder strNum = new StringBuilder();
//Concatenate to get actual string
for(int i = mostSignificantDigitIndex; i < num.length; i++) {
strNum.append(num[i]);
}
System.out.println(strNum);
//Check if number current number is greater or equal to endNum
if(strNum.length() > endNum.length() || (strNum.length() == endNum.length() && strNum.toString().compareTo(endNum) >= 0)) {
break;
}
}
}
}
Output
1000000000000000000000000000000000000000000000000000001
1000000000000000000000000000000000000000000000000000002
1000000000000000000000000000000000000000000000000000003
1000000000000000000000000000000000000000000000000000004
1000000000000000000000000000000000000000000000000000005
1000000000000000000000000000000000000000000000000000006
1000000000000000000000000000000000000000000000000000007
1000000000000000000000000000000000000000000000000000008
1000000000000000000000000000000000000000000000000000009
1000000000000000000000000000000000000000000000000000010
1000000000000000000000000000000000000000000000000000011
1000000000000000000000000000000000000000000000000000012
1000000000000000000000000000000000000000000000000000013
1000000000000000000000000000000000000000000000000000014
1000000000000000000000000000000000000000000000000000015
1000000000000000000000000000000000000000000000000000016
1000000000000000000000000000000000000000000000000000017
1000000000000000000000000000000000000000000000000000018
1000000000000000000000000000000000000000000000000000019
1000000000000000000000000000000000000000000000000000020
Something like this:
This is a PHP, but you could transform it to java easy...
Recursion with increasing number through string.
function nextNum($num="", $step=1, $end="999999999999999999") {
$string = "";
$saving = 0;
for($i=strlen($num)-1; $i>=0; $i--) {
$calc = intval(intval($num[$i]) + $saving);
if ($i==(strlen($num)-1)) $calc = $calc + $step;
if (strlen($calc)==2) {
$calc = $calc."";
$saving = intval($calc[0]);
$calc = intval($calc[1]);
}
else {
$calc = intval($calc);
$saving = 0;
}
$string = $calc . $string;
}
if ($saving!=0) $string = $saving.$string;
echo $string." ";
if ($end == $string || strlen($end)<strlen($string)) { return; }
else return nextNum($string, $step, $end);
}
nextNum("0", 1, "999999999999999999");
I didn't test it... but it should work..

Attempting to return a fraction (as a float) in Java

In this function:
public float cgRatio(String dna) {
//initialize count to be 0
int count = 0;
//for each character in the string
//if character == 'C' or 'G' increment count
for (int i = 0; i < dna.length(); i++) {
char c = dna.charAt(i);
if (c == 'C' || c == 'G') {
count++;
}
}
//return the ratio of C & G in DNA strand
return count/dna.length();
}
with my test function:
public void testFindGene() {
String[] dnaStrands = new String[6];
dnaStrands[0] = "AGCATGGTAACCAATAAGCGTTAAGCCAT";
dnaStrands[1] = "AATAATGGCATGGCCAATGAATGCGTAACCGATTAA";
dnaStrands[2] = "ATAATGCGGAATTGACATGGTA";
dnaStrands[3] = "AGCATGGTAACCAATTAGCGTTAAGCCAT";
dnaStrands[4] = "AATAATGGCATGGCCAATGAATTGACGTAACCGATTAA";
dnaStrands[5] = "ATAATGCGGAATCTAGACATGGTA";
for (int i = 0; i < dnaStrands.length - 1; i++) {
String gene = findGene(dnaStrands[i], 0);
System.out.println("The DNA strand is: \"" + dnaStrands[i] + "\"");
System.out.println("Gene: " + gene);
System.out.println("CG ratio of gene sequence is: " + String.format("%.02f", cgRatio(gene)));
}
}
My cgRatio return value is always 0.00. If I return just the count, I get accurate results in the form of a float. So that means my cgRatio function fails on this line:
//return the ratio of C & G in DNA strand
return count/dna.length();
Can you not return a fraction in Java? If you can, how can I fix this? If you cannot, why and what is an alternative solution?
try doing as ,
return (float)count/dna.length();
count and length both are int that is why you are getting like that.
Declaring count as a float would also solve the issue. Integer division yield an integer and omits fractions.
float count = 0;
For more clarification as to what is actually happening, the code
return count/dna.length();
is doing integer math then casting the result as a float.
For example if count is 5 and dna.length() returns 7,
5 / 7 = 0.714 which equals 0 when doing integer math (it rounds down to the nearest integer value).
So your code is essentially doing float(0) which gets your result of 0.00.
Cast your variables before dividing return (double)count/(double)dna.length(); Java is making it integer division because both are ints.

Optimisation of string & conversion operations

I had a go at writing this bit of java code which allows me to add and subtract (large) numbers which are represented using a String rather than a numeric datatype. This allows me to do basic calculations on numbers much bigger than the numeric data types can handle.
It is a bit rough and ready, I don't perform any checks on the input strings at all for instance, but for the constraints that I am using the code works fine.
I am not that familiar with java library functions (is there something instead of Character#getNumericValue that works better?) and I was wondering if there is any scope for improving the execution speed. I guess when the input numbers differ considerably in length, using the '0's to keep the loop running isn't very efficient. Perhaps I am not using a very good algorithm to do this at all. Any pointers would be welcome.
public static String addBig(String a, String b)
{
// no checks or exception handling at all ...
String result = "";
int carry = 0;
int a_int, b_int, res_int;
for(int current = 1; ; current++)
{
if(current > a.length() && current > b.length())
{
if(carry == 1)
result = "1" + result;
break;
}
a_int = a.length() - current < 0 ? 0
: Character.getNumericValue(a.charAt(a.length() - current));
b_int = b.length() - current < 0 ? 0
: Character.getNumericValue(b.charAt(b.length() - current));
res_int = a_int + b_int + carry;
if(res_int > 9)
{
res_int -= 10;
carry = 1;
}
else
carry = 0;
result = Integer.toString(res_int) + result;
}
return result;
}
public static String subtractBig(String a, String b)
{
// no checks or exception handling at all, a is expected to be bigger than b
String result = "";
int borrow = 0;
int a_int, b_int, res_int;
for(int current = 1; current <= a.length(); current++)
{
// subtract the digits
a_int = Character.getNumericValue(a.charAt(a.length() - current));
b_int = b.length() - current < 0 ? 0
: Character.getNumericValue(b.charAt(b.length()-current));
res_int = (a_int-borrow)-b_int;
if(res_int < 0)
{
res_int += 10;
borrow = 1;
}
else
borrow = 0;
result = Integer.toString(res_int) + result;
}
// tidy zeros
while(result.length() > 1 && result.charAt(0) == '0')
result = result.substring(1);
return result;
}

How to add numbers(integers) that are stored inside a string

I have to create a program that uses Luhn's algorithm to check to see if a credit card is valid.
The algorithm is this:
Form a sum of every other digit, including the right-most digit; so
5490123456789128 sums to 8+1+8+6+4+2+0+4 = 33
Form double each remaining digit, then sum all the digits that creates it; the remaining digits in our example (5 9 1 3 5 7 9 2) double to 10 18 2 6 10 14 18 4, which sums to 1+0+1+8+2+6+1+0+1+4+1+8+4 = 37
Add the two sums above (33+37 = 70)
If the result is a multiple of 10 (i.e., its last digit is 0) then it was a valid credit card number.
I made a Scanner and saved the credit card number into String card number
Then I created a while loop to save every other character starting from the right into a string. So now, I have a string filled with every other digit of the credit card number, starting from the right. However, I need to add up all of the digits within that string, which I can't figure out.
For example, if the user entered 1234 as the card number, the string everyotherdigit = 42. How can I add up 4 and 2 within the string?
There are numerous ways to do that. You can actually find your own solution by doing a bit of googling.
Anyway, this is what you can do:
Get individual characters from your string, and convert them to int.
String cardNumber = "5490123456789128";
int value = cardNumber.charAt(0) - '0';
Using a for loop and changing 0 to x(loop counter) will solve everything.
Get single String and convert to int.
String cardNumber = "5490123456789128";
int value = Integer.parseInt(cardNumber.substring(0,1));
I'd treat the string as an array of chars, and use Character.digit(int, int) to convert each character to the corresponsing int:
public static boolean isValidCreditCard (String s);
char[] arr = s.toCharArray();
int everyOtherSum = 0;
for (int i = arr.length - 1; i >= 0; i -= 2) {
everyOtherSum += Character.digit(arr[i], 10);
}
int doubleSum = 0;
for (for (int i = arr.length - 2; i >= 0; i -= 2) {
int currDigit = Character.digit(arr[i], 10);
int doubleDigit = currDigit * 2;
while (doubleDigit > 0) {
doubleSum += (doubleDigit % 10);
doubleDigit /= 10;
}
}
int total = everyOtherSum + doubleSum;
return total % 10 == 0;
}
So something like this would work for you:
public static void main(String[] args)
{
String cardNum = "5490123456789128";
String others = null;
int evenDigitSum = 0;
int oddDigitTransformSum = 0;
for (int pos = 0; pos < cardNum.length(); pos++)
{
if ((pos%2) != 0)
{
evenDigitSum += (cardNum.charAt(pos) - '0');
}
else
{
others = Integer.toString((cardNum.charAt(pos)-'0')*2);
for (char c : others.toCharArray())
{
oddDigitTransformSum += (c-'0');
}
}
}
System.out.println("Odds: " + oddDigitTransformSum);
System.out.println("Evens: " + evenDigitSum);
System.out.println("Total: " + (evenDigitSum+oddDigitTransformSum));
System.out.println("Valid Card: " + ((evenDigitSum+oddDigitTransformSum)%10==0));
}
public int cardCount(String numbers){
Stack<Integer> stack = new Stack<>();
int count = 0;
for(char c : numbers.toCharArray()){
stack.push(Character.getNumericValue(c));
}
int size = stack.size();
for(int i=1;i <= size; i++){
if(i%2 != 0){
count = count + stack.pop();
}else{
stack.pop();
}
}
return count;
}
This just does what you asked, not the entire algorithm

Categories

Resources