Create array which stores odds from -6 to 38 in java - java

I'm learning Java and I found an exercise which I can't solve, in the Arrays chapter.
The exercise says:
Write code that creates an array named odds and stores all odd numbers between -6 and 38 into it using a for loop. Make the array's size exactly large enough to store the numbers.
The only solution I could come up with is this:
import java.util.Arrays;
public class exerciseOddsArray {
public static void main(String[]args){
oddsArray();
}
public static void oddsArray(){
int odds = 0;
for (int i = -6; i <= 38; i++){
if (i % 2 == 1){
odds++;
}
}
int[] numbers = new int[odds];
for (int i = 0; i < numbers.length; i ++){
for (int j = -6; j <= 38; j++){
if(j % 2 == 1){
numbers[i] = j;
}
}
}
System.out.println(Arrays.toString(numbers));
}
}
However, the program prints:
[37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37]
And I don't understand why.

You don't need nested FOR loops here. Just create an integer variable i to track your position in the array and increment it when adding each new item. PS... the array should have been called "odds" based on the specs of the assignment. I suggest renaming that variable you were using to count the number of odds to something else (e.g. numberOfOdds)
int[] odds= new int[numberOfOdds];
int i = 0;
for (int j = -6; j <= 38; j++)
{
if(j % 2 == 1)
{
odds[i++] = j;
}
}

for each i you go over all the odd number j could have and assign them to numbers[i]. Instead, you could (should!) use a single loop:
int min = -6;
int max = 38;
int numOdds = (max - min) / 2; // Ok because both min and max are even
int[] odds = new int[numOdds];
int firstOdd = min;
if (min % 2 == 0) {
++firstOdd;
}
int index = 0;
for (int i = firstOdd; i < max; i += 2) {
odds[index++] = i;
}
BTW - I get this is a school exercise, and that you're supposed to use a for loop, but frankly, Java 8's streams would solve this in a much neater fashion:
odds = IntStream.range(-6, 38).filter(i -> i % 2 != 0).toArray();

odds is a single value, you need to keep all the odd numbers you find in a list.
int odds = 0;

You have two for loops when you only need one.
Unrolling the loops, your program is doing the following:
numbers[0] = -6;
numbers[0] = -4;
numbers[0] = -2;
etc...
numbers[0] = 37;
numbers[1] = -6;
numbers[1] = -4;
etc...

Try the below below please
public static ArrayList<Integer> getOddList(int min,int max){
ArrayList<Integer> myList = new ArrayList<>();
for( int i = min ; i <= max ; i++){
if(i % 2 != 0){
myList.add(i);
}
}
return myList;
}
[-5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37]
I am assuming here min and max u r providing are in order. Also I have not tested my function. But this is an utility u can take. Please let me know

U created int value and changed it 22 times i guess in first for loop. Then u add for your array the same value for another million times. Try to add your value to an array in first loop:
int[] odds= new int[numberOfOdds];
int i = 0;
for (int j = -6; j <= 38; j++)
{
if(j % 2 == 1)
{
odds[i++] = j;
}
}
Better use list if u don't know length of your set.

Thank you guys for the answers. I changed my method to :
public static void oddsArray(){
int numberOfOdds = 0;
for (int i = -6; i <= 38; i++){
if (i % 2 == 1){
numberOfOdds++;
}
}
int[] odds = new int[numberOfOdds];
int i = 0;
for (int j = -6; j < 39; j++){
if (j % 2 == 1){
odds[i++] = j;
}
}
}
Now it prints only the positive odd numbers.

You can do this without knowing the number of odd numbers in advance.
int[] oddNumbers = IntStream.range(-6, 38)
.filter(i -> i % 2 != 0)
.toArray();

I'm not sure if it's necessary, but you could recreate the array holding the odd numbers each time you come across a new odd number. The method below will work no matter what range you are working with. I know that you can just use an ArrayList, but the question seems to want an array.
public class exerciseOddsArray {
public static void main(String[] args) {
private int[] odds;
private int start = -6;
private int end = 38;
odds = findOdds(start, end);
if (odds== null)
System.out.println("There weren't any odds");
else
System.out.println(Arrays.toString(odds));
}
public static int[] findOdds(int start, int end) {
private int[] arrayOfOdds;
private int[] tempArray;
private int numberOfOdds = 0;
if (start < end)
{
while (start != end)
{
if ((start % 2) == 1)
{
if (arrayOfOdds != null)
{
tempArray = new int[arrayOfOdds.length + 1];
for (int i = 0; i < arrayOfOdds.length; i++)
tempArray[i] = arrayOfOdds[i];
tempArray[arrayOfOdds.length] = start;
arrayOfOdds = tempArray;
} else {
arrayOfOdds = new int[1];
arrayOfOdds[0] = start;
}
}
start++;
}
}
return arrayOfOdds;
}
}

I have answer, this works
int[] odds = new int[22];
for(int i = 0;i<odds.length;i++){
odds[i]=2*i-5;
}

Number of odds is 22, this can be changed, but you must also change the parameters (ie. -6 and 38)
int[] odds = new int [22];
int i = 0;
for (int temp = -6; temp <= 38; temp++)
if (Math.abs(temp % 2) == 1)
{
odds[i++] = temp;
}

Related

Trying to get non repeating numbers by using nested loop..(2-D array)

I am trying to figure out a way that I can insert random numbers into a 2-d array that is 5x5. I am working on a bingo game so it anyone could help me I would be greatly appreciative. I am fairly new to Java, so any help would be good. Thanks.
Consider:
boolean matchFound; // used to track when a repeat is found
int rand; // temporarily store the random number before putting it into the array to check if it's a repeat
Random rn = new Random();
for (int i = 0; i < 25 ; i++) {
rand = rn.nextInt(15) + 1;
matchFound = false; // assume that the number generated is not a repeat
for (int x = 0; x <= 5; x++) {
for (int j = 0; j <= 5 ; ++j){
if (rand == b[x][j]) { // check if the number just generated is a repeat
matchFound = true; // if it is, set the boolean to True and use that after the loop
}
if (matchFound == true) { // if the last number is a repeat, then
i = i - 1; // reduce the loop counter by 1 to go back to that place for the new number
} else {
b[i][j] = rand; // the number was not repeated so insert it.
}
}
}
}
I would recommend treating it like a bingo game - where you have a set of numbers, randomize them, and the 'pick' numbers for the board. I believe bingo ranges from 1-75? but you could change that. And then just pick the first 25 numbers from your ArrayList, they are sure to be random and not repeated this way.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class Test {
public static void main(String[] args){
ArrayList<Integer> bingo = new ArrayList<Integer>();
int[][] b = new int[5][5];
// create a list in order
for (int i = 1; i <= 75; i++) {
bingo.add(i);
}
Collections.shuffle(bingo); // randomize
// Add to the board
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
b[i][j] = bingo.remove(0); // remove the first item in the shuffled list
}
}
System.out.print(Arrays.deepToString(b));
}
}
As in bingo game, You need to track the column number to get the right range boundary of each column (min & max values in below code).
and for each iteration in the outer loop of column values these values will change accordingly
public static void main(String[] args) {
int[][] b = new int[5][5]; // 5x5 grid
for (int i = 0; i < 5; i++) { // loop for columns
int min = i * 15 + 1;
int max = (i + 1) * 15;
for (int j = 0; j < 5; j++) { // loop for rows
int rand;
do {
rand = getRandom(min, max); // generate random int between min & max values
} while (isMatch(rand, b));
b[j][i] = rand;
}
}
/* print array values */
for (int[] x : b)
System.out.println(Arrays.toString(x));
}
/* return true if num is in the array b */
private static boolean isMatch(int num, int b[][]) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (num == b[i][j]) {
return true;
}
}
}
return false;
}
/* return integer number between min & max inclusive */
public static int getRandom(int min, int max) {
return (int) ((Math.random() * (max + 1 - min)) + min);
}
Output
[14, 22, 37, 57, 62]
[15, 20, 45, 55, 63]
[6, 29, 38, 52, 69]
[11, 30, 34, 59, 74]
[4, 16, 36, 54, 67]

Generating random array of fixed length [duplicate]

This question already has answers here:
Creating a random array of type int. Java
(3 answers)
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 1 year ago.
I am just looking to change my code so that a random array of a fixed length of 100 integers is generated every time the code is ran rather than just have a pre-set array within the code. I am quite new to this so just need a guide in the right direction, thanks
public class Selectionsort {
public static void main(String[] args) {
int[] numbers = {15, 8, 6, 21, 3, 54, 6, 876, 56, 12, 1, 4, 9};
sort(numbers);
printArray(numbers);
}
public static int[] sort(int[] A) {
for (int i = 0; i < A.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < A.length; j++) {
if (A[j] < A[minIndex]) {
minIndex = j;
}
}
int temp = A[minIndex];
A[minIndex] = A[i];
A[i] = temp;
}
return A;
}
public static void printArray(int[] A) {
for (int i = 0; i < A.length; i++) {
System.out.println(A[i]);
}
}
}
public class Selectionsort {
public static void main(String[] args) {
int[] numbers = new int[100]
Random random = new Random();
for (int i = 0; i < numbers.length; i++) {
numbers[i] = random.nextInt(100);
}
sort(numbers);
printArray(numbers);
}
}
The above snippet will help you to create a random numbers between 1 to 100 for the array of size 100.
You should look at the Random class.
More specifically:
nextInt() to fill it one by one
ints​(long) to get an IntStream of fixed size, which can be easily converted to an array with .toArray()
The below would fill an array of 100 integers with Random numbers from 1-1000
int[] numbers = new int[100];
Random rand = new Random();
for (int i = 0; i < numbers.length; i++) {
numbers[i] = rand.nextInt(1000);
}
However note that the above code might insert duplicates. If you want to avoid that, using a List in parallel to the array and checking whether the generated value already exists should ensure uniqueness :
int[] numbers = new int[100];
List<Integer> numbersList = new ArrayList<Integer>(numbers.length);
Random rand = new Random();
for (int i = 0; i < numbers.length; i++) {
int j = rand.nextInt(1000);
while (numbersList.contains(j)) {
j = rand.nextInt(1000);
}
numbers[i] = j;
numbersList.add(j);
}
Even though I think it would be wiser to get rid of the array and use just the List...
You can use Math.random method. This code generates an array of 10 random numbers in the range [50,60] inclusive.
int length = 10, min = 50, max = 60;
int[] arr = IntStream.range(0, length)
.map(i -> (int) (min + Math.random() * (max - min + 1)))
.toArray();
System.out.println(Arrays.toString(arr));
// [54, 51, 58, 59, 57, 56, 56, 54, 54, 58]
Full set of 11 random numbers:
Set<Integer> set = new HashSet<>();
while (set.size() < max - min + 1) {
set.add((int) (min + Math.random() * (max - min + 1)));
}
System.out.println(set);
// [50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]

Generate even numbers in an int array?

For my program I need to make a 10 element array and the goal is to print out the even numbers from 2 to 20. I have to do this by adding 2 to the beginning element. This is what I have so far. I think I should use a loop as shown but I don't know how to go about adding 2 and printing that out. Thanks!
int[] array = new int[10];
for(int counter=0; counter<array.length; counter++) {
}
if you want program print even number between 2 & 20
for(int i=2;i<=20;i++)
{
if(i%2 == 0)
print(i)
}
Start at 2 and increment by 2 to get the even numbers:
int[] array = new int[10]
for(int counter=2; counter <= 20; counter += 2) {
array[counter/2 - 1] = counter
}
or
int[] array = new int[10]
for(int i=0; i <= 10; i++) {
array[i] = i*2 + 2
}
this is also an option
int i, value;
int nums[] = new int[10];
for (i = 0, value = 2; i < nums.length; value = value + 2, i = i + 1) {
nums[i] = value;
}
for (i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
int[] array = new int[10];
for (int i = 0, j = 1; i < array.length && j <= 20; j++) {
if (j % 2 == 0) {
array[i] = j;
i++;
}
}
System.out.println(Arrays.toString(array));
Java 8: int[] array = IntStream.range(1, 11).map(x -> x * 2).toArray();
Or, to just print: IntStream.range(1, 11).map(x -> x * 2).forEach(System.out::println);
From java-9 you can use IntStream.iterate to create int array
int[] arr= IntStream.iterate(2, i->i<=20, i->i+2).toArray();
for Integer array you can use Stream.iterate
Integer[] ary = Stream.iterate(2, i->i<=20, i->i+2).toArray(Integer[]::new);
Dear Alexis,
Below is an example using do-while.
you can simply define a range of expected even numbers using minVal and maxVal.
Program will execute and return list of ordered even numbers for given range. Assuming input values are correct even numbers. You can improve to apply validations.
public class EvenNumberGenerator {
static int minVal=2; //enter valid min value even number
static int maxVal = 20; //enter valid max value even number
public static void main(String[] args) {
List<Integer> evenNumbers = new ArrayList();
do {
if(minVal % 2 == 0) {
evenNumbers.add(minVal);
}
minVal++;
} while (!evenNumbers.contains(maxVal));
System.out.println(evenNumbers);
// evenNumbers.toArray(); in case you need an array
}
}
OUTPUT
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Hope it helps!
Using your code as a start, this will work:
int[] array = new int[10];
for(int counter=0; counter<array.length; counter++) {
array[counter] = (counter + 1) * 2;
}
System.out.println(Arrays.toString(array));
The following will also work with Eclipse Collections:
int[] array = IntInterval.evensFromTo(2, 20).toArray();
System.out.println(Arrays.toString(array));
Note: I am a committer for Eclipse Collections

Dynamic Programming (Codility Q: NumberSolitaire)

This is the question:
codility.com/programmers/task/number_solitaire
and below link is my result (50% from Codility):
https://codility.com/demo/results/training8AMJZH-RTA/
My code (at the first, I tried to solve this problem using Kadane's Algo):
class Solution {
public int solution(int[] A) {
int temp_max = Integer.MIN_VALUE;
int max = 0;
int k = 1;
if(A.length == 2) return A[0] + A[A.length-1];
for(int i = 1; i < A.length-1; i++) {
if(temp_max < A[i]) temp_max = A[i];
if(A[i] > 0) {
max += A[i];
temp_max = Integer.MIN_VALUE;
k = 0;
} else if(k % 6 == 0) {
max += temp_max;
temp_max = Integer.MIN_VALUE;
k = 0;
}
k++;
}
return A[0] + max + A[A.length-1];
}
And below is the solution (100% from Codility result) that I found from web:
class Solution {
public int solution(int[] A) {
int[] store = new int[A.length];
store[0] = A[0];
for (int i = 1; i < A.length; i++) {
store[i] = store[i-1];
for (int minus = 2; minus <= 6; minus++) {
if (i >= minus) {
store[i] = Math.max(store[i], store[i - minus]);
} else {
break;
}
}
store[i] += A[i];
}
return store[A.length - 1];
}
}
I have no idea what is the problem with my code:(
I tried several test cases but, nothing different with the solution & my code
but, codility test result shows mine is not perfectly correct.
(https://codility.com/demo/results/training8AMJZH-RTA/)
please anyone explain me the problem with my code~~
Try this test case[-1, -2, -3, -4, -3, -8, -5, -2, -3, -4, -5, -6, -1].
you solution return -4 (A[0],A[1],A[length-1],Here is the mistake), but the correct answer is -6 (A[0],A[6],A[length-1]).
Here is a my solution,easy to understand:
public int solution(int[] A) {
int lens = A.length;
int dp[] = new int[6];
for (int i = 0; i < 6; i++) {
dp[i] = A[0];
}
for (int i = 1; i < lens; i++) {
dp[i%6] = getMax6(dp) + A[i];
}
return dp[(lens-1)%6];
}
private int getMax6(int dp[]){
int max = dp[0];
for (int i = 1; i < dp.length; i++) {
max = Math.max(max, dp[i]);
}
return max;
}
Readable solution from Java:
public class Solution {
public static void main(String[] args) {
System.out.println(new Solution().solution(new int[]{1, -2, 0, 9, -1, -2}));
}
private int solution(int[] A) {
int N = A.length;
int[] dp = new int[N];
dp[0] = A[0];
for (int i = 1; i < N; i++) {
double sm = Double.NEGATIVE_INFINITY;
for (int j = 1; j <= 6; j++) {
if (i - j < 0) {
break;
}
double s1 = dp[i - j] + A[i];
sm = Double.max(s1, sm);
}
dp[i] = (int) sm;
}
return dp[N-1];
}
}
Here is a solution similar to #0xAliHn but using less memory. You only need to remember the last 6 moves.
def NumberSolitaire(A):
dp = [0] * 6
dp[-1] = A[0]
for i in range(1, len(A)):
maxVal = -100001
for k in range(1, 7):
if i-k >= 0:
maxVal = max(maxVal, dp[-k] + A[i])
dp.append(maxVal)
dp.pop(0)
return dp[-1]
Based on the solutions posted, I made nice readable code. Not best performance.
int[] mark = new int[A.length];
mark[0] = A[0];
IntStream.range(1, A.length)
.forEach(i -> {
int max = Integer.MIN_VALUE;
mark[i] = IntStream.rangeClosed(1, 6)
.filter(die -> i - die >= 0)
.map(r -> Math.max(mark[i - r] + A[i], max))
.max().orElse(max);
});
return mark[A.length - 1];
Because you are not using dynamic programming, you are using greedy algorithm. Your code will fail when the max number in a range will not be the right choice.
function solution(A) {
// This array contains a maximal value at any index.
const maxTill = [A[0]];
// It's a dynamic programming so we will choose maximal value at each
// Index untill we reach last index (goal)
for (let i = 1; i < A.length; i++) {
// Step 1 . max value of each index will be atleast equal to or greater than
// max value of last index.
maxTill[i] = maxTill[i - 1];
// For each index we are finding the max of last 6 array value
// And storing it into Max value.
for (let dice = 1; dice <= 6; dice++) {
// If array index is itself less than backtrack index
// break as you dont have 6 boxes in your left
if (dice > i) {
break;
} else {
// The most important line .
// Basically checking the max of last 6 boxes using a loop.
maxTill[i] = Math.max(
maxTill[i - dice],
maxTill[i]
);
}
}
// Until this point maxStill contains the maximal value
// to reach to that index.
// To end the game we need to touch that index as well, so
// add the value of the index as well.
maxTill[i] += A[i];
}
return maxTill[A.length - 1];
}
console.log(solution([-1, -2, -3, -4, -3, -8, -5, -2, -3, -4, -5, -6, -1]));
This is my solution. I try to make the code easy to apprehend. It might not save space as much as it can.
private static int solution(int A[])
{
// N // N is an integer within the range [2..100,000];
// A[] // each element of array A is an integer within the range [−10,000..10,000].
int N = A.length;
int[] bestResult = new int[N]; // record the current bestResult
Arrays.fill(bestResult, Integer.MIN_VALUE); // fill in with the smallest integer value
// initialize
bestResult[0] = A[0];
for (int i = 0;i < A.length;i++) {
// calculate six possible results every round
for (int j = i + 1; (j < A.length) && (i < A.length) && j < (i + 1) + 6; j++) {
// compare
int preMaxResult = bestResult[j]; // the max number so far
int nowMaxResult = bestResult[i] + A[j]; // the max number at bestResult[i] + A[j]
bestResult[j] = Math.max(preMaxResult, nowMaxResult);
}
}
return bestResult[bestResult.length-1];
}
Here is the simple Python 3 solution:
import sys
def solution(A):
dp = [0] * len(A)
dp[0] = A[0]
for i in range(1, len(A)):
maxVal = -sys.maxsize - 1
for k in range(1, 7):
if i-k >= 0:
maxVal = max(maxVal, dp[i-k] + A[i])
dp[i] = maxVal
return dp[len(A)-1]
100% c++ solution(
results)
#include <climits>
int solution(vector<int>& A) {
const int N = A.size();
if (N == 2)
return A[0] + A[1];
vector<int> MaxSum(N, INT_MIN);
MaxSum[0] = A[0];
for (int i = 1; i < N; i++) {
for (int dice = 1; dice <= 6; dice++) {
if (dice > i)
break;
MaxSum[i] = max(MaxSum[i], A[i] + MaxSum[i - dice]);
}
}
return MaxSum[N-1];
}
100% python solution
with the help of the answers above and https://sapy.medium.com/cracking-the-coding-interview-30eb419c4c57
def solution(A):
# write your code in Python 3.6
# initialize maxUntil [0]*n
n = len(A)
maxUntil = [0 for i in range(n)]
maxUntil[0]=A[0]
# fill in maxUntil, remember to chack limits
for i in range(1, n): # for each
maxUntil[i] = maxUntil [i-1]
# check the max 6 to the left:
# for 1,..,6:
for dice in range(1,7):
if dice > i: # if dice bigger than loc - we are out of range
break
#else: check if bigger than cur elem, if so - update elem
maxUntil[i] = max(maxUntil[i],maxUntil[i-dice])
# add the current jump:
maxUntil[i] +=A[i]
# must reach the last sq:
return maxUntil[n-1]
I would like to explain the algorithm I have come up with and then show you the implementation in C++.
Create a hash for the max sums. We only need to store the elements within reach, so the last 6 elements. This is because the dice can only go back so much.
Initialise the hash with the first element in the array for simplicity since the first element in this hash equals to the first element of the inputs.
Then go through the input elements from the second element.
For each iteration, find the maximum values from the last 6 indices. Add the current value to that to get the current max sum.
When we reach the end of the inputs, exit the loop.
Return the max sum of the last element calculated. For this, we need clipping with module due to the space optimisation
The runtime complexity of this dynamic programming solution is O(N) since we go through element in the inputs. If we consider the dice range K, then this would be O(N * K).
The space complexity is O(1) because we have a hash for the last six elements. It is O(K) if we does not consider the number of dice faces constant, but K.
int solution(vector<int> &A)
{
vector<int> max_sums(6, A[0]);
for (size_t i = 1; i < A.size(); ++i) max_sums[i % max_sums.size()] = *max_element(max_sums.cbegin(), max_sums.cend()) + A[i];
return max_sums[(A.size() - 1) % max_sums.size()];
}
Here's my answer which gives 100% for Kotlin
val pr = IntArray(A.size) { Int.MIN_VALUE }
pr[0] = A.first()
for ((index, value) in pr.withIndex()) {
for (i in index + 1..min(index + 6, A.lastIndex)) {
pr[i] = max(value + A[i], pr[i])
}
}
return pr.last()
I used forwarded prediction, where I fill the next 6 items of the max value the current index can give.

Algorithm to find the largest integer in array

I am trying to create a method which returns an int - the value of the largest integer in the sent array.
The way I want this method to work, is to check the first and the last element of the array in a for-loop, and work their way to the middle. So i = first integer, k = last integer. When i = 0, k = n-1 (indexes), when i = 1, k = n-2 if you catch my drift. In every loop it needs to check if a[i]>a[k]. Then they switch places. Then I know that the largest number is in the leading half of the array, and then I want it to check that half, so ultimately the largest int is at index 0.
I tried like this:
public static int maxOfArray(int[] a)
{
int length = a.length;
if(length<1)
throw new NoSuchElementException("Not at least one integer in array");
while (length > 1)
{
int k = length;
for(int i = 0; i < length/2; i++)
{
k--;
if(a[i]<a[k])
{
int j = a[i];
a[i] = a[k];
a[k] = j;
}
}
length /=2;
}
return a[0];
}
..but I don't really get it.. I'm having a hard time "picturing" what's happening here.. But it's not always working.. (though sometimes).
EDIT
Also: The array {6,15,2,5,8,14,10,16,11,17,13,7,1,18,3,4,9,12}; will spit out 17 as the largest number. I realize I have to fix the odd-length bug, but I would like to solve this even-length array first..
A bug is when encountering length is odd.
In these cases, you "miss" the middle element.
Example: for input int[] arr = { 8, 1, 5, 4, 9, 4, 3, 7, 2 }; - the element 9 will be compared and checked against itself, but then you reduce the size of length, you exclude 9 from the array you are going to iterate next.
I believe it can be solved by reducing the problem to ceil(length/2) instead of length/2 (and handling special case of length==1)
The other issue as was mentioned in comments is: you need to iterate up to length/2 rather then up to length, otherwise you are overriding yourself.
Lastly - the sign is wrong.
if(a[i]>a[k])
should be
if(a[i]<a[k])
Remember - you are trying to swap the elements if the first is smaller the the second in order to push the larger elements to the head of your array.
but I don't really get it.. I'm having a hard time "picturing" what's happening here.. But it's not always working.. (though sometimes).
In that case you should use a debugger to step through the code to get a picture of what each line of code does.
What I would do is:
public static int maxOfArray(int[] a) {
int max = a[0];
for (int i : a)
if (max < i)
max = i;
return max;
}
public static int findMaxTheHardWay(int[] array) {
for (int length = array.length; length > 1; length = (length + 1) / 2) {
for (int i = 0; i < length / 2; i++) {
if (array[i] < array[length - i - 1])
array[i] = array[length - i - 1]; // don't need to swap.
}
}
return array[0];
}
public static void main(String... args) {
Random rand = new Random(1);
for (int i = 1; i <= 1000; i++) {
int[] a = new int[i];
for (int j = 0; j < i; j++) a[j] = rand.nextInt();
int max = maxOfArray(a);
int max2 = findMaxTheHardWay(a);
if (max != max2)
throw new AssertionError(i + ": " + max + " != " + max2);
}
}
This is rather a crazy way to solve the problem, but I'll play along.
The problem is in the inner loop.
You start out with i = 0 and k = length - 1.
If a[i] > a[k] you swap them.
...
You end up with k = 0 and i = length - 1
If a[i] > a[k] you swap them.
If you look at that carefully you will notice that if we swapped the elements in the first swap, we will also swap them in the last swap; i.e. we will UNDO the effects of the first swap. And the same applies pair-wise through the entire array slice.
See?
What you need to do is to stop the inner loop half way ... and then take account of the case where length is odd.
By the way, the reason I called this "rather crazy", because the obvious and simple way is much faster: O(N) versus O(NlogN)
int a[] = {1,7,3};
List<Integer> list = Arrays.asList(a);
Integer largest = Collections.max(list);
This will give you Largest number in Array.
Here is a solution that fits the specifications that you want (unlike many other here, humm, humm):
final Integer[] input = {1, 2, 6, 32, 4, 44 ,12, 42, 3, 7, 17, 22, 57, 23, 102, 103 };
int half = (input.length / 2);
int mod = input.length % 2;
while (half >= 0) {
for (int i = 0, j = (half * 2) + mod - 1; i <= half && j >= half; i++, j--) {
if (input[i] < input[j]) {
final int tmp = input[i];
input[i] = input[j];
input[j] = tmp;
}
}
if (half == 0) break;
half = half / 2;
mod = half % 2;
}
//Here, input[0] = the biggest number in the original input.
Edit: Added mod, so it works if the last element is the largest..
I think your code is working, you just have to ceil the length / 2 in case of odd array but my tests return proper result:
package org.devince.largestinteger;
import java.util.NoSuchElementException;
public class LargestInteger {
final static int[] input = {1, 2, 6, 32, 4, 44 ,12, 42, 3, 7, 17, 22, 57, 23, 102, 103 };
// final static int[] input = { 8, 1, 5, 4, 9, 4, 3, 7, 2 };
// final static int[] input = {1,3,7};
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(String.valueOf(maxOfArray(input)));
}
public static int maxOfArray(int[] a)
{
int length = a.length;
if(length<1)
throw new NoSuchElementException("Not at least one integer in array");
while (length > 1)
{
int k = length;
for(int i = 0; i < length; i++)
{
k--;
if(a[i]>a[k])
{
int j = a[i];
a[i] = a[k];
a[k] = j;
}
}
length = (int) Math.ceil(length / 2f);
}
return a[0];
}
}
Why not just store the first value of the array to a variable max.
After that just loop through the array starting from second position till the last ,
in the loop just check if the current value is greater than max or not.If it is greater just assign max that value.
Return max and you have the largest number.
public int FindLargest()
{
int[] num = { 1, 2, 5, 12, 13, 56, 16, 4 };
int max = num[0];
for (int i = 1; i <num.length; i++)
{
if (num[i] > max)
{
max = num[i];
}
}
return max;
}
As the same u can approach like also,
int length = a.length;
while (length > 1)
{
int k = length;
for(int i = 0; i < length; i++)
{
for(int y = k-1; y >= i; y--)
{
if(a[i]<a[y])
{
int j = a[i];
a[i] = a[y];
a[y] = j;
}
}
}
length /=2;
}
final int validSampleRates[] = new int[]{
5644800, 2822400, 352800, 192000, 176400, 96000,
88200, 50400, 50000, 4800,47250, 44100, 44056, 37800, 32000, 22050, 16000, 11025, 4800, 8000};
ArrayList <Integer> YourArray = new ArrayList <Integer> ():
for (int smaple : validSampleRates){
YourArray.add(smaple);
}
Integer largest = Collections.max(YourArray);
System.out.println("Largest " + String.valueOf(largest));
The best way is to use Array that extends List Collection as ArrayList

Categories