I've been working on code to sort integer in an array list, but my code is only returning only 2 numbers can anybody help me understand what I'm doing wrong here. How do I get all the numbers to be displayed? The numbers in my array
ArrayList testNumbers = new ArrayList();
testNumbers.add(48);
testNumbers.add(3);
testNumbers.add(23);
testNumbers.add(99);
[48,3,23,99]. Any help would be greatly appreciated.
public ArrayList<Integer> listSort(ArrayList<Integer> numbers) {
// create variable to store max number
int maxNumber = 0;
// creates an array that will store the sorted numbers
ArrayList<Integer> sortedIntArray = new ArrayList<Integer>();
// loops through each number in the numbers arraylist
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) > maxNumber) {
// set the number to the new max number
maxNumber = numbers.get(i);
// add current max number to sorted array
sortedIntArray.add(maxNumber);
// remove the max number from numbers array
numbers.remove(numbers.get(i));
}
}
return sortedIntArray;
}
//the sortedIntArray returns
[48,99]
Use java.util.Collections.sort(List<T> list). Or are you required to implement your own sorting algorithm?
If you take a careful look at your code, it doesn't do anything if the number you are currently looking at is not bigger than maxNumber.
It adds in 48 because 48 > 0. Then it discards 3 and 23 because they are less than 48. then it adds 99 because it is greater than 48.
I believe you want to archive a classical Selection Sort.
Maybe try good old wikipedia: http://en.wikipedia.org/wiki/Selection_sort
public ArrayList<Integer> listSort(ArrayList<Integer> numbers) {
// create variable to store max number
int maxNumber = 0;
// creates an array that will store the sorted numbers
ArrayList<Integer> sortedIntArray = new ArrayList<Integer>();
// loops through each number in the numbers arraylist
for (int i = numbers.size(); i > 0; i--) {
maxNumber = numbers.get(0);
for(int j = 0; j < numbers.size(); j++) {
if (numbers.get(j) > maxNumber) {
// set the number to the new max number
maxNumber = numbers.get(i);
}
}
// add current max number to sorted array
sortedIntArray.add(maxNumber);
// remove the max number from numbers array
numbers.remove(numbers.get(i));
// add current max number to sorted array
sortedIntArray.add(maxNumber);
}
return sortedIntArray;
}
Basically you're only adding numbers that are greater than the max number you've seen. You also need to account for numbers that are smaller, and store them appropriately.
You are only adding to sortedIntArray when the array element you're looking at is bigger than the biggest found so far. 48 gets added because you haven't found any so far. Then 99 gets added because it's larger than 48.
You need to pass through the array more than once. As it stands, what you're doing is finding every number larger than all the previous numbers in the array. If you're really just looking for a selection sort (not a great idea, it's pretty slow) you want:
int size = numbers.size();
for (int i = 0; i < size; i++)
{
int maxNumber = 0;
for (int j = 0; j < numbers.size(); j++)
{
if (numbers.get(j) > numbers.get(maxNumber))
maxNumber = j;
}
SortedIntArray.add(numbers.get(maxNumber));
numbers.remove(maxNumber);
}
This also returns your array from largest to smallest, which isn't necessarily what you want. Also, by removing from numbers, you're changing the array so it won't be available to you once you're done (unless you pass a clone). In general, you need to rethink your set-up.
you mixed several sorting strats
public ArrayList<Integer> listSort(ArrayList<Integer> numbers) {
// create variable to store max number
int maxNumber = 0;
// creates an array that will store the sorted numbers
ArrayList<Integer> sortedIntArray = new ArrayList<Integer>();
// loops through each number in the numbers arraylist
while (!numbers.isEmpty()) {
int i;
for(i=0;i<number.size();i++){//double loop to get the current max numbers
if (numbers.get(i) > maxNumber) {
// set the number to the new max number
maxNumber = numbers.get(i);
}
}
// add current max number to sorted array
sortedIntArray.add(maxNumber);
// remove the max number from numbers array
number.listIterator(i).remove();
maxNumber=0;//reset maxNumber
}
}
return sortedIntArray;
}
I'm guessing you are asking this for a homework assignment. If you aren't just use any managed languages built in sort method as it will be faster than anything you write.
You are removing entries as you process them.
This means the size is shrinking when you insert entries.
After you add two entries, you have removed two entries leaving two entries so the loop stops.
try this algorithm it works with classes.. you can plug a list of class' into it as well
package drawFramePackage;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Random;
public class QuicksortAlgorithm {
ArrayList<AffineTransform> affs;
ListIterator<AffineTransform> li;
Integer count, count2;
/**
* #param args
*/
public static void main(String[] args) {
new QuicksortAlgorithm();
}
public QuicksortAlgorithm(){
count = new Integer(0);
count2 = new Integer(1);
affs = new ArrayList<AffineTransform>();
for (int i = 0; i <= 128; i++){
affs.add(new AffineTransform(1, 0, 0, 1, new Random().nextInt(1024), 0));
}
affs = arrangeNumbers(affs);
printNumbers();
}
public ArrayList<AffineTransform> arrangeNumbers(ArrayList<AffineTransform> list){
while (list.size() > 1 && count != list.size() - 1){
if (list.get(count2).getTranslateX() > list.get(count).getTranslateX()){
list.add(count, list.get(count2));
list.remove(count2 + 1);
}
if (count2 == list.size() - 1){
count++;
count2 = count + 1;
}
else{
count2++;
}
}
return list;
}
public void printNumbers(){
li = affs.listIterator();
while (li.hasNext()){
System.out.println(li.next());
}
}
}
Related
I have a List that stores different numbers, the maximum of them are elements under indices: 2; 4.
I want to print these 2 elements to the console - as the maximum numbers in the array, but the Collections.max () method returns only the first maximum value it finds, that is, only the element at index 2:
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(5);
numbers.add(9);
numbers.add(50);
numbers.add(12);
numbers.add(50);
System.out.println(Collections.max(numbers));
|Output|
50
What should I use instead of method Collections.max() to find ALL maximum values?
this uses one iteration to find them
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(5);
numbers.add(9);
numbers.add(50);
numbers.add(12);
numbers.add(50);
int max = Integer.MIN_VALUE;
int count = 1;
for(int number : numbers){
if(number > max){
max = number;
count = 1;
} else if(number == max){
count++;
}
}
for(int i=0; i<count; i++){
System.out.println(max);
}
There is no given function doing that by default. So what you can do is filtering this list for the given value. This will cause 2 iterations but be simple in code. If you do it in your own loop if it more code but more efficient.
Depending on the amopunt of data you should choose efficient way or readable way.
// 2 iterations - 1st for finding max , 2nd for filter
int maxValue = Collections.max(numbers);
List<Integer> maxValues = numbers.stream().filter(number -> number == max).collect(Collectors.toList()); // only need size? Add .size() at the end
// efficient - just 1 iteration, but not pretty to read.
int currentMax = numbers[0];
int counter = 0;
for(Integer number in numbers) {
if(currentMax == number) {
counter++;
} else if(currentMax < number) {
counter = 1;
currentMax = number;
}
}
max will always find the maximum value and not the occurences. What you want will always have to be done in 2 steps.
// If you start from a List
List<Integer> numbers = Arrays.asList(5, 9, 50, 12, 50);
IntSummaryStatistics numberStats = numbers.stream().collect(Collectors.summarizingInt(Integer::intValue));
numbers.stream().filter(number -> number == numberStats.getMax()).forEach(System.out::println);
// But you can also start from the stream itself
IntSummaryStatistics numberStats = IntStream.of(5, 9, 50, 12, 50).summaryStatistics();
numbers.stream().filter(number -> number == numberStats.getMax()).forEach(System.out::println);
/*
* You can also use the plain max number instead of the summaryStatistics, which is
* more performant but the stream cannot be reuse for e.g. min or average.
* Note here we use equals because we don't use primitive int but Object Integer as it's not an IntSteam
*/
Integer maxInt = numbers.stream().max(Comparator.naturalOrder()).orElseThrow();
numbers.stream().filter(number -> number.equals(maxInt)).forEach(System.out::println);
Comparator.naturalOrder() means that you do not provide a comparator but let Java use it's default comparator which it has for all primitives, boxed primitives and Strings. Sorting words and numbers is a natural thing that is well known and does not require any implementation.
You can first loop through the list to find the max value, and then loop the list again to put max valus and their index to a map.
Map map = new HashMap();
int curMax = 0;
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i)>=curMax){
curMax = numbers.get(i);
}
}
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) == curMax){
map.put(i, numbers.get(i));
}
}
System.out.println(map.toString());
Output:
{2=50, 4=50}
You can find the maximal elements by lifting the integer values into a list first and reducing that list:
List<Integer> max = numbers.stream()
.collect(Collectors.reducing(
Collections.singletonList(Integer.MIN_VALUE),
Collections::singletonList,
(l1, l2) -> {
if (l1.get(0) > l2.get(0)) {
return l1;
} else if (l2.get(0) > l1.get(0)) {
return l2;
} else {
List<Integer> l = new ArrayList<>(l1);
l.addAll(l2);
return l;
}
}));
So this is a coding question from school I have, I don't want to say "hey guys do my homework for me!", I actually want to understand what's going on here. We just started on arrays and they kind of confuse me so I'm looking for some help.
Here's the complete question:
Write a program in which the main method creates an array with
10 slots of type int. Assign to each slot a randomly-generated
integer. Call a function, passing it the array. The called
function should RETURN the largest integer in the array to
your main method. Your main method should display the number
returned. Use a Random object to generate integers. Create it
with
Random r = new Random(7);
Generate a random integer with
x = r.nextInt();
So, here's what I have so far:
import java.util.Random;
public class Q1 {
public static void main(String[] args) {
Random r = new Random(7);
int[] count = new int[11];
int x = r.nextInt();
for (int i = 0; i < count.length; i++)
{
count[i] = x;
}
}
I created that array with 10 ints, then used a for loop to assign each slot that randomly generated integer.
I'm having a hard time for what to do next, though. I'm not sure what kind of method / function to create and then how to go from there to get the largest int and return it.
Any help is really appreciated because I really want to understand what's going on here. Thank you!
Here is how to generate Random ints
public static void main(String[] args) {
int []count = new int[10];
Random r = new Random(7);
int x=0;
for (int i = 0; i < count.length; i++)
{
x = r.nextInt();
count[i] = x;
}
System.out.println("Max Number :"+maxNumber(count));}//Getting Max Number
Here is how to make method and get max number from list.
static int maxNumber(int[] mArray){//Passing int array as parameter
int max=mArray[0];
for(int i=0;i<mArray.length;i++){
if(max<mArray[i]){//Calculating max Number
max=mArray[i];
}
}
return max;//Return Max Number.
}
Ask if anything is not clear.
This is how we make method which return int.
You can do it by using a simple for loop for the Array.
First you have to create a seperate int variable (eg: int a) and assign value zero (0) and at each of the iterations of your loop you have to compare the array item with the variable a. Just like this
a < count[i]
and if it's true you have to assign the count[i] value to the variable a . And this loop will continue until the Array's last index and you will have your largest number in the a variabe. so simply SYSOUT the a variable
Important: I didn't post the code here because I want you to understand the concept because If you understand it then you can solve any of these problems in future by your self .
Hope this helps
What you have got so far is almost correct, but you currently are using the same random number in each iteration of your for-loop. Even though you need to get a new random number for each iteration of your for-loop. This is due to how the Random object is defined. You can achieve this by changing your code the following way:
import java.util.Random;
public class Q1 {
public static void main(String[] args) {
Random r = new Random(7);
int[] count = new int[11];
for (int i = 0; i < count.length; i++)
{
int x = r.nextInt(); // You need to generate a new random variable each time
count[i] = x;
}
}
Note that this code is not optimal but it is the smallest change from the code you already have.
To get the largest number from the array, you will need to write another for-loop and then compare each value in the array to the largest value so far. You could do this the following way:
int largest = 0; // Assuming all values in the array are positive.
for (int i = 0; i < count.length; i++)
{
if(largest < count[i]) { // Compare whether the current value is larger than the largest value so far
largest = count[i]; // The current value is larger than any value we have seen so far,
// we therefore set our largest variable to the largest value in the array (that we currently know of)
}
}
Of course this is also not optimal and both things could be done in the same for-loop. But this should be easier to understand.
Your code should be something like this. read the comments to understand it
public class Assignment {
public static int findMax(int[] arr) { // Defiine a function to find the largest integer in the array
int max = arr[0]; // Assume first element is the largest element in the array
for (int counter = 1; counter < arr.length; counter++) // Iterate through the array
{
if (arr[counter] > max) // if element is larger than my previous found max
{
max = arr[counter]; // then save the element as max
}
}
return max; // return the maximum value at the end of the array
}
public static void main(String[] args) {
int numberofslots =10;
int[] myIntArray = new int[numberofslots]; // creates an array with 10 slots of type int
Random r = new Random(7);
for (int i = 0; i < myIntArray.length; i++) // Iterate through the array 10 times
{
int x = r.nextInt();
myIntArray[i] = x; // Generate random number and add it as the i th element of the array.
}
int result = findMax(myIntArray); // calling the function for finding the largest value
System.out.println(result); // display the largest value
}
}
Hope you could understand the code by reading comments..
This can be done in one simple for loop no need to have 2 loops
public static void main(String[] args) {
Integer[] randomArray = new Integer[10];
randomArray[0] = (int)(Math.random()*100);
int largestNum = randomArray[0];
for(int i=1; i<10 ;i++){
randomArray[i] = (int)(Math.random()*100);
if(randomArray[i]>largestNum){
largestNum = randomArray[i];
}
}
System.out.println(Arrays.asList(randomArray));
System.out.println("Largest Number :: "+largestNum);
}
Initialize max value as array's first value. Then iterate array using a for loop and check array current value with max value.
OR you can sort the array and return. Good luck!
Here's a basic method that does the same task you wish to accomplish. Left it out of the main method so there was still some challenge left :)
public int largestValue(){
int largestNum;
int[] nums = new int[10];
for (int n = 0; n < nums.length; n++){
int x = (int) (Math.random() * 7);
nums[n] = x;
largestNum = nums[0];
if (largestNum < nums[n]){
largestNum = nums[n];
}
}
return largestNum;
}
So as part of a task, I was asked to create an array with randomized values within a range, and then to sort it from smallest to biggest (I used a bubble sort), and then to firstly, print the sum of all the elements in the array, then to list them from smallest to biggest.
My issue is that I keep getting the ArrayIndexOutOfBoundsException error, but cannot find where this problem lies.
You can see in the code that I've put in the randomArrays method, a for loop that creates the random values for the array size I declared in the main method, then, underneath the for loop, I've created an if statement that checks to see if an element's value is bigger than the element after it, if it is, it swaps the place of the elements, until they're all sorted into smallest to biggest, and the loop is terminated.
Any help is much appreciated, thank you :)
public class MyArray {
public static void main(String[] args) {
int[] elements = new int[50];
int min = 0;
int max = 50;
randomArrays(elements, max, min);
}
public static void randomArrays(int[] elements, int max, int min) {
int range = max - min; //defines the range of the integers
int temp;
boolean fixed = false;
while (fixed == false) {
fixed = true;
for (int i = 0; i < elements.length; i++) {
elements[i] = min + (int) (Math.random() * range);
while (i < elements.length) {
if (elements[i] > elements[i + 1]) {
//if 8 > 5
temp = elements[i + 1];
//store 5 in temp
elements[i + 1] = elements[i];
//put the 8 in the 5's place
elements[i] = temp;
fixed = false;
}
i++;
}
}
}
}
//System.out.println(elements[i]);
}
My issue is that I keep getting the ArrayIndexOutOfBoundsException
error, but cannot find where this problem lies.
Problem lies in the condition of the for loop. You get ArrayOutOfBounds exception when i=49 and then you try to access i+1 index which doesn't exists.
Change
for (int i = 0; i < elements.length; i++)
to
for (int i = 0; i < elements.length-1; i++)
As you can already see that your code is going out of the arrays limit.
if you look at your code, following is where this is happening
while (i < elements.length) {
Its this while loop part, so if you change it to correctly loop thru the right number of elements, your problem will be resolved..change your while loop code with this one
while (i < elements.length-1) {
I am given a problem in which I have to store a list of N numbers in an array and then sort it ,
and then I have to add the numbers at alternative positions and output the sum.
The problem is the constraint of N i.e 0 <= N <= 1011 so I have to declare the N as double type variable here is my code :
ArrayList<Double> myList = new ArrayList<Double>();
myList.add(number);
.....
Collections.sort(myList);
String tempNo = "";
for(double i = 0 ; i < myList.size() ; i=i+2){
tempNo = myStringWayToAdd(tempNo , myList(i)+""); // Since the sum will exceed the limit of double I have to add the numbers by help of Strings
}
But the problem is that the get(int) method takes an int not double. Is there any other way I can solve the problem? , and Is it even allowed to store number of elements that exceed int range?
Any help will be highly appreciated. Thank you in Advance.
Edit 1 :
I can use Strings instead of double in ArrayList and then add up the numbers but my problem is that i need to store N elements which can exceed the range of Integers
You could use LinkedList because it does not have a size limit (although odd things may begin to happen up there). You should also be able to use BigInteger for your numbers if the numbers themselves could get huge (you don't seem to state).
// LinkedList can hold more than Integer.MAX_VALUE elements,
List<BigInteger> myList = new LinkedList<>();
// Fill it with a few numbers.
Random r = new Random();
for (int i = 0; i < 1000; i++) {
myList.add(BigInteger.probablePrime(10, r));
}
// Sort it - not sure if Collections.sort can handle > Integer.MAX_VALUE elements but worth a try.
Collections.sort(myList);
// Start at 0.
BigInteger sum = BigInteger.ZERO;
// Add every other one.
boolean addIt = false;
for (BigInteger b : myList) {
if (addIt) {
sum = sum.add(b);
}
addIt = !addIt;
}
I am not sure if Collections.sort can handle a list of numbers that big, let alone whether it will succeed in sorting within the age of the universe.
You may prefer to consider a database but again you might even have probelms there with this many numbers.
Ah, I misunderstood the question. So we have to store something that is significantly larger than the capacity of int.
Well, we can do this by dividing and conquering the problem. Assuming this is theoretical and we have unlimited memory, we can create a SuperArrayList.
'Scuse my bad generics, no compiler.
public class SuperArrayList<E>() {
private ArrayList<ArrayList<E>> myList;
private int squareRoot;
private double capacity;
public SuperArrayList(double capacity) {
this.capacity = capacity;
squareRoot = Math.ceil(Math.sqrt(capacity)); //we create a 2d array that stores the capacity
myList = new ArrayList<ArrayList<E>>();
for(int i = 0; i < squareRoot; i++) {
myList.add(new ArrayList<E>());
}
}
public E get(double index) {
if(index >= capacity || index < 0) {
//throw an error
}
else {
return myList.get((int) capacity / squareRoot).get(capacity % squareRoot);
}
}
}
As an alternative to squareRoot, we can do maxValue and add additional arraylists of length maxvalue instead.
boolean add = true;
for (Double doubleNum : myList) {
if (add) {
tempNo = myStringWayToAdd(tempNo , doubleNum+"");
}
add = !add;
}
Using this way, you won't have to use index.
I need to make a typical integer filled array with 10 random non repeating numbers from 0 to 20. Also, I need to be able to modify this so I can exclude some random numbers from 0 to 20.
How can I do this?
You can do this in three easy steps:
Build a list with all the candidate numbers you want
Use Collections.shuffle to shuffle that list
Use the n first elements of that shuffled list.
First build a list of size 20 with values 0,...,19
Then shuffle() it
And last - take the sublist containing first 10 elements.
This Method will work for you. It generate 10 unique random numbers from 0 to 20.
public static int[] getRandomArray(){
int randomCount =10;
int maxRandomNumber = 21;
if(randomCount >maxRandomNumber ){
/* if randomCount is greater than maxRandomNumber
* it will not be possible to generate randomCount
* unique numbers
**/
return null;
}
HashMap<Integer, Integer> duplicateChecker = new HashMap<Integer, Integer>();
int[] arr = new int[randomCount ];
int i = 0;
while(i<randomCount ){
// Generate random between 0-20, higher limit 21 is excluded
int random = new Random().nextInt(maxRandomNumber );
if(duplicateChecker.containsKey(random)==false){
duplicateChecker.put(random, random);
arr[i]=random;
i++;
}
}
return arr;
}
* Edited: To make the method deterministic. And Avoid the chance of infinite loop
public static int[] getRandomArray(){
int randomCount =10;
int maxRandomNumber = 21;
if(randomCount >maxRandomNumber ){
/* if randomCount is greater than maxRandomNumber
* it will not be possible to generate randomCount
* unique numbers
**/
return null;
}
ArrayList<Integer> arrayList = new ArrayList<Integer>();
// Generate an arrayList of all Integers
for(int i=0;i<maxRandomNumber;i++){
arrayList.add(i);
}
int[] arr = new int[randomCount ];
for(int i=0;i<randomCount;i++){
// Generate random between 0-20, higher limit 21 is excluded
int random = new Random().nextInt(arrayList.size());
// Remove integer from location 'random' and assign it to arr[i]
arr[i]=arrayList.remove(random);
}
return arr;
}
What about making an arraylist of numbers upto 20, and after each random number call you remove the number from the list and into the array.
example
Random r = new Random();
int[] myArray = new int[10];
ArrayList<Integer> numsToChoose = new ArrayList<Integer>();
int counter = 0;
for(int i = 0; i < 21; i++)
{
numsToChoose.add(i);
}
while(numsToChoose.size() > 11)
{
myArray[counter] = numsToChoose.remove(r.nextInt(numsToChoose.size()));
counter++;
}
That way it should only loop 10 times, I may be wrong though.
Hope it helps
EDIT: And in order to modify this to exclude certain numbers, you would just need a method that takes an array that contains said numbers as a parameter, and loop through it removing each number from the arraylist before you generate your random numbers.
Most of the other responses offer the Collections.shuffle method as a solution. Another way, which is theoretically faster is the following:
First lets build the list:
public class RandomWithoutReplacement {
private int [] allowableNumbers;
private int totalRemaining;
/**
* #param upperbound the numbers will be in the range from 0 to upperbound (exclusive).
*/
public RandomWithoutReplacement ( int upperbound ) {
allowableNumbers = new int[ upperbound ];
for (int i = 0; i < upperbound; i++) {
allowableNumbers[i] = i;
}
totalRemaining = upperbound;
}
}
Next lets consider what we need to do when we need to get the next number.
1) When we request another number, it must be chosen from any one of the available, uniformly.
2) Once it is chosen, it must not repeat again.
Here is what we can do:
First, choose a number at random from the allowableNumbers array.
Then, remove it from the array.
Then remove the number at the end of the array, and place it in the position of the number we are to return.
This ensures all of the 2 conditions we have placed.
public int nextRandom () {
//Get a random index
int nextIndex = (int) ( Math.random() * totalRemaining );
//Get the value at that index
int toReturn = allowableNumbers [ nextIndex ];
//Find the last value
int lastValue = allowableNumbers [ totalRemaining - 1 ];
//Replace the one at the random index with the last one
allowableNumbers[ nextIndex ] = lastValue;
//Forget about the last one
totalRemaining -- ;
return toReturn;
}
With that, your function is almost complete.
I would add a couple more things just in case:
public boolean hasNext () {
return totalRemaining > 0;
}
And at the beginning of the actual function:
public int nextRandom () {
if (! hasNext() )
throw new IllegalArgumentException();
// same as before...
}
That should be it!
Well, I could't help it not to post my solution which is storing a sequance of numbers into twice as many random locations first. Then compacts it into the resultting array.
int[] myRandomSet = generateNumbers(20, 10);
...
public int[] generateNumbers(int range, int arrayLenght){
int tempArray[];
int resultArray[];
int doubleLocations;
Random generator = new Random();
doubleLocations = range * 2;
tempArray = new int[doubleLocations];
resultArray = new int[arrayLenght];
for (int i=1; i<=range; i++){
if (i != 5 && i != 13){ //exclude some numbers
do{
r = generator.nextInt(doubleLocations);
}while(tempArray[r]!=0);
tempArray[r] = i; //enter the next number from the range into a random position
}
}
int k = 0;
for (int i=0; i<(doubleLocations); i++){
if(tempArray[i] != 0){
resultArray[k] = tempArray[i]; //compact temp array
k++;
if (k == arrayLenght) break;
}
}
return resultArray;
}