My question is related to the fibonacci sequence of numbers (but for simplicity, you could apply it to things like square/prime numbers etc)
long f1 = 0;
long f2 = 1;
long fibonacci = 0;
long[] fibonaccinumbers = new long[52];
fibonaccinumbers[0]=0;
fibonaccinumbers[1]=1;
for(int count = 2; count<=51; count++)
{
fibonacci = f2+f1;
fibonaccinumbers[count] = fibonacci;
f1 = f2;
f2 = fibonacci;
}
The above code generates the array for fibonacci numbers 0-51.
Now what I'm looking to do is enter a number, we'll use 30 as an example. and then find and display the numbers before and after it in the sequence, which would be 21 and 34.
What is tripping me up is getting into the array and searching above and below my given number to find a match. How could I do this?
Since the Fibonaccy series is a sorted array (having ascending order), you can use int index = Arrays.binarySearch(fibonaccinumbers,30); to get the index such that fibonaccinumbers[index-1] < 30 < fibonaccinumbers[index].
Therefore fibonaccinumbers[index-1] will contain 21 and fibonaccinumbers[index] will contain 34.
Note that Arrays.binarySearch will return fibonaccinumbers.length if all the numbers in your array are smaller than the number you are searching for.
This should be very simple, you just need to access the array at +1 and -1 of the index you have entered, for example, if the user enters 30...
System.out.println("BEFORE: " + fibonaccinumbers[input-1]);
System.out.println("AFTER: " + fibonaccinumbers[input+1]);
Where input is what the user enters, so in the case, input-1 would be 29.
Just be sure to make sure input-1 and input+1 do not go out of the bounds od your array.
If you wanted to find out what the actual fibonnaci number is as opposed to its number in the sequence, you will need to do a search for this first and then use the index you find to again, find what is before and after.
If you´d don´t want to use the binary search provided by the Arrays class then you could simply loop over the array and check for the needed values. You just need an int value that indicates the index in the array.
public static void main(String[] args) {
long[] fibs = createFib();
long search = 30;
int small = 0;
for(long i : fibs) {
if(i < search) {
++small;
} else {
break;
}
}
if(small < fibs.length)
System.out.println(fibs[small-1] + " and " + fibs[small] + " do surround the value " + search);
else {
System.out.println(" the value " + search +" is to high, only " + fibs[small-1] + " is in range");
}
}
private static long[] createFib() {
long f1 = 0;
long f2 = 1;
long fibonacci = 0;
long[] fibonaccinumbers = new long[52];
fibonaccinumbers[0]=0;
fibonaccinumbers[1]=1;
for(int count = 2; count<=51; count++)
{
fibonacci = f2+f1;
fibonaccinumbers[count] = fibonacci;
f1 = f2;
f2 = fibonacci;
}
return fibonaccinumbers;
}
Related
I want to get the minimum number of my array, but my "if" compare only checks the first and last positions of array.
Here is my code:
int[] randNumbers = new int[20]; //deklaracja nowej tablicy 20-elementowej
Random r = new Random(); // Dodana metoda random do losowania
for(int i=0; i<randNumbers.length; i++) {
randNumbers[i] = r.nextInt(101);
int min = randNumbers[0];
System.out.println("Number "+i+": " + randNumbers[i]);
if (randNumbers[i] < min) {
min = randNumbers[i];
}
if (i == randNumbers.length-1) {
System.out.println("Min number is: " + min);
}
}
You don't even need the array here. Just iterate from 0 to N and check each random number if it less than min:
Random r = new Random();
int min = 101; // assign max value 101 before loop
for(int i = 0; i < 20; i++) {
int number = r.nextInt(101);
System.out.println("Number " + i + ": " + number);
if (number < min) {
min = number;
}
}
System.out.println(min);
If you want use array, you could initialize it before. For example using Random.ints():
int[] randNumbers = new Random().ints(20, 0, 101).toArray();
And then use the same for-loop idea with randNumbers[i] instead of nextInt(101)
try this out, your int min = randNumbers[0]; resets the min value every time so move it out of the loop
int min = 100;
for(int i=0; i<randNumbers.length; i++) {
randNumbers[i] = r.nextInt(101);
System.out.println("Number "+i+": " + randNumbers[i]);
if (randNumbers[i] < min) {
min = randNumbers[i];
}
}
System.out.println("Min number is: " + min);
The issue is that you are not remembering the minimum number as the loop runs. If you make a variable outside of the loop, it won't get updated every single iteration. Your code might look something like this:
int[] randNumbers = new int[20]; //deklaracja nowej tablicy 20-elementowej
Random r = new Random(); // Dodana metoda random do losowania
int min = 0;
for(int i=0; i<randNumbers.length; i++) {
int number = r.nextInt(101);
if(i == 0) min = number;
randNumbers[i] = number;
System.out.println("Number "+i+": " + number);
min = Math.min(min, number);
}
System.out.println("Min number is: " + min);
A few things to notice:
The variable min was moved outside of the loop. This is to make sure it is persistent across the loop, and won't be updated every iteration of the loop.
A new variable number is introduced. This is to prevent you from constantly calling randNumbers[i], which looks nicer, and to my knowledge slightly speeds it up. It also make it easier to change the variable once, and have it effective everywhere it is needed.
The last S.O.P was moved outside of the loop. There is no point in checking if the loop is at the last element if you can just put the statement the line after the loop ends. It will work the same functionally, but this looks nicer.
Instead of using an if statement to set min, it uses the output of Math.min. This is just a cosmetic change, and behaves the exact same with an if statement.
Move min int outside loop with value 0 isn't working, because my result will be everytime because Not initialized array have only '0'
Move it with 100+ is good idea. It's working when we know maximum number.
#geneSummons "int min = Integer.MAX_INT"
This works very well with different range/scope of numbers:) Thanks
Btw. I still don't understand why it's compare only first and last number ;)
In the process of learning algorithms, I have written code to compare 2 algorithms performance in terms of running time. The task of these algorithms is to find all the pairs of numbers in an array that add up to a specific number.
First approach - Brute force.
2 for loops to find the pairs of numbers that add up to the given number. Basically time complexity is O(n*n).
Second approach - Efficient
First sort the array, then have start and end as index to the beginning and end of array, and depending on the sum of these elements in the positions, move left or right to find pairs of numbers.
My question is -
I am printing the running time of each algorithm approach. But it seems like the running time of the Brute force approach is faster than the Efficient one. Why is this happening?
See the code here -
public class MainRunner {
final private static int numberRange = 100000;
public static void generateRandomNumbers(int[] array, int[] dupArray) {
System.out.println("Generated Array: ");
Random random = new Random();
for (int i = 0; i < array.length; i++) {
int generatedRandomInt = random.nextInt(array.length) + 1;
array[i] = dupArray[i] = generatedRandomInt;
}
}
public static void main(String[] args) {
int[] array = new int[numberRange];
int[] dupArray = new int[numberRange];
generateRandomNumbers(array, dupArray);
Random random = new Random();
int sumToFind = random.nextInt(numberRange) + 1;
System.out.println("\n\nSum to find: " + sumToFind);
// Starting Sort and Find Pairs
final long startTimeSortAndFindPairs = System.currentTimeMillis();
new SortAndFindPairs().sortAndFindPairsOfNumbers(sumToFind, array);
final long durationSortAndFind = System.currentTimeMillis() - startTimeSortAndFindPairs;
// Starting Find Pairs
final long startTimeFindPairs = System.currentTimeMillis();
new FindPairs().findPairs(sumToFind, dupArray);
final long durationFindPairs = System.currentTimeMillis() - startTimeFindPairs;
System.out.println("Sort and Find Pairs: " + durationSortAndFind);
System.out.println("Find Pairs: " + durationFindPairs);
}
}
SortAndFindPairs.java
public class SortAndFindPairs {
public void sortAndFindPairsOfNumbers(int argNumberToFind, int[] array) {
Arrays.sort(array);
System.out.println("\n\nResults of Sort and Find Pairs: \n");
int startIndex = 0;
int endIndex = array.length - 1;
while (startIndex < endIndex) {
int sum = array[startIndex] + array[endIndex];
if (argNumberToFind == sum) {
//System.out.println(array[startIndex] + ", " + array[endIndex]);
startIndex++;
endIndex--;
} else if (argNumberToFind > sum) {
startIndex++;
} else {
endIndex--;
}
}
}
And the FindPairs.java
public class FindPairs {
public void findPairs(int argNumberToFind, int[] array) {
System.out.println("\nResults of Find Pairs: \n");
int randomInt1 = 0;
int randomInt2 = 0;
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
int sum = array[i] + array[j];
if (argNumberToFind == sum) {
//System.out.println(array[i] + ", " + array[j]);
//randomInt1++;
//randomInt2--;
}
}
}
}}
Only on adding the two variables randomInt1 and randomInt2 in the FindPairs.java, the running time difference is seen. Or else, the running time of FindPairs.java is much less than SortAndFindPairs.java. So why does adding just 2 variable operations increase time by so much? According to conventions, simple operations should consume negligible time. Am I missing out something here?
Results for numberRange = 1000000
Results of Find Pairs:
Sort and Find Pairs: 641
Find Pairs: 57
I think the problem is your compiler optimization playing tricks to you. I tried different permutations of your code, and noticed that the double for loop in FindPairs is doing almost nothing. So the compiler may be stripping some of the code.
I got this numbers with the exact copy of your code:
Sort and Find Pairs: 43
Find Pairs: 13
Consistently (I ran it several times to double check) Sort and find was slower, everytime.
But then I changed the inner loop for to do nothing:
for (int j = i + 1; j < array.length; j++) {
//int sum = array[i] + array[j];
//if (argNumberToFind == sum) {
//System.out.println(array[i] + ", " + array[j]);
//randomInt1++;
//randomInt2--;
//}
And guess what? I got:
Sort and Find Pairs: 20
Find Pairs: 11
Tried several times and the numbers were pretty similar. By removing both loops the runtime for find pairs went to 1. So My guess, maybe the optimization step of the compiler is assuming that the code inside the inner loop doesn't have any effect and thus removes it. The code in Sort and find is a little smarter and so it gets kept.
Now, I tried a different thing, I commented out the increment of randomInt1, but left the sum and if commented,
for (int j = i + 1; j < array.length; j++) {
//int sum = array[i] + array[j];
//if (argNumberToFind == sum) {
//System.out.println(array[i] + ", " + array[j]);
randomInt1++;
//randomInt2--;
//}
and then I got:
Sort and Find Pairs: 42
Find Pairs: 5
Wow, suddenly it got faster! (maybe the compiler replaced the for for the arithmetic calculation of randomInt1 by using the loop bounds?)
My last attempt. You can noticed that this is not a fair comparison, the sort and find have a lot of logic involved, while the find doesn't. It actually does nothing when it find a pair. So to make it apples to apples we want to be sure find pairs actually do something, and lets make sure sort and find do the same extra amount (like adding the same number on both sides of the equation). So I changed the methods to calculate the count of matching pairs instead. Like this:
System.out.println("\nResults of Find Pairs: \n");
long randomInt1 = 0;
int randomInt2 = 0;
int count = 0;
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
int sum = array[i] + array[j];
if (argNumberToFind == sum) {
count++;
}
}
}
System.out.println("\nPairs found: " + count + "\n");
and
public void sortAndFindPairsOfNumbers(int argNumberToFind, int[] array) {
Arrays.sort(array);
System.out.println("\n\nResults of Sort and Find Pairs: \n");
int startIndex = 0;
int endIndex = array.length - 1;
int count = 0;
while (startIndex < endIndex) {
int sum = array[startIndex] + array[endIndex];
if (argNumberToFind == sum) {
//System.out.println(array[startIndex] + ", " + array[endIndex]);
startIndex++;
endIndex--;
count++;
} else if (argNumberToFind > sum) {
startIndex++;
} else {
endIndex--;
}
}
System.out.println("\nPairs found: " + count + "\n");
}
And then got:
Sort and Find Pairs: 38
Find Pairs: 4405
The time for find pairs blowed up! And the sort and find kept in line with what we were seeing before.
So the most likely answer to your problem is that the compiler is optimizing something, and an almost empty for loop is something that the compiler can definitely use to optimize. whilst for the sort and find, the complex logic may cause the optimizer to step back. Your algorithm lessons are find. Here java is playing you a trick.
One more thing you can try is use different languages. I'm pretty sure you will find interesting stuff by doing so!
As stated by LIuxed, sort operation takes some time. If you invest time in sorting, why do you then not take advantage of the fact that list items are sorted?
If list elements are sorted, you could use a binary search algorithm... start in the middle of the array, and check if you go 1/2 up, or 1/2 down. As a result, you can get faster performance with sorted array for seeking a value. Such an algorithm is already implemented in the Arrays.binarySearch methods.
See https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#binarySearch(int[],%20int)
You will notice the difference when you sort just once, but seek many times.
Calling the Array.sort(MyArray) method, takes long time because it uses a selection algorithm; this means, the Sort method go through all the array x times ( x= array.lenght) searching for the smallest/biggest value, and set it on top of the array, and so on.
Thats why, using this method takes a long time, depending on the array size.
I removed everything from your sortAndFindPairsOfNumbers method, just kept
Arrays.sort(array);
But still time difference is much more.
This means most of the time taken is by sort method.
So your thinking that second approach is Efficient one is not correct. Its all about input size.
If you keep numberRange, lets say, 1000, then SortAndFindPairs will be faster.
I'm trying to make it so the random generator doesn't produce the same number in the array. I also don't know how to find the missing number. I tried the if statement, and it works, but it repeats.
The question problem "find the missing number in an array. The array consists of numbers from 1 to 10 in random sequence. One of the numbers in the array is absent and you must find it. Use one loop. An example {5,6,9,4,1,2,8,3,10} – the result will be: 7
import java.util.Random;
public class questionThree
{
public static void main(String[] args)
{
int [] numbers = new int [10];
Random rand = new Random();
int numArr = 1;
for (int i = 1; i < 9; i++)
{
int n = rand.nextInt(10) + 1;
numbers[i] = n;
if (numbers[i] == numArr)
numArr++;
else
System.out.println("The missing num is " +numArr);
}
for(int val : numbers)
{
System.out.println("The next value is " +
val);
}
}
}
Assumption:
Numbers are unique
Only one entry is missing
number ranges from [1, 10] inclusive.
Solution
return 55 - Arrays.stream(yourArr).sum();
This is with O(n) runtime and O(1) space complexity.
If we break assumptions.
You will need O(N) space to figure out which entries are missing. To hold the marker either you can use List or BitSet or 2 bytes and manage it by hand. N is here the random number generation width.
There seems to be no mention on using a temporary data structure.
You can either sort the array and find the missing number, OR use a temporary sorted data structure.
You are conflating two things: the generator algorithm for a problem case and the solution to the problem itself. You shouldn't be interested in how the "random array" is generated at all (unless you want to test your solution). What you certainly shouldn't do is try to write the code that solves the problem in the method that generates the sample array.
If you want a randomly sorted list, Collections.shuffle will handle that for you. If you want a list without a single element, just generate a list of all elements 1..n and then remove the randomly selected number (then shuffle). So much for the generator. As for the solution, there are many methods to do it, someone already suggested using the sum, that's a perfectly valid solution.
It seems you are looking for this code.
import java.util.Random;
public class questionThree
{
public static void main(String[] args)
{
int [] numbers = new int [9];
Random rand = new Random();
int numArr = 1;
numbers[0] = rand.nextInt(10) + 1;
for (int i = 1; i < 9; i++)
{
int n = rand.nextInt(10) + 1;
numbers[i] = n;
int x =0;
while(x<i){
if(numbers[x] == n){
i = i-1;
break;
}
x++;
}
}
int sum = 0;
for (int val : numbers) {
sum = sum + val;
System.out.println("The next value is " +
val);
}
System.out.println("Missing number is " + (55 - sum));
}
}
Output is -
The next value is 6
The next value is 2
The next value is 8
The next value is 1
The next value is 4
The next value is 3
The next value is 9
The next value is 10
The next value is 7
Missing number is 5
I am generating 9 Numbers between(1 to 10) randomly and then printing which number is missing among them.
You have two options:
The way I did it in the code below: setting the random array without repeating the same number. And then a for loop from 1 to 10 and check if that number exist in the array.
You know that 1 + 2 + 3 + 2 + 3 + 4 + 5 + 6 + 8 + 9 + 10 = 55. So if you get the sum of all ints in the array you will have 55 - (the missing number). So now the missing number = 55 - sum.
This is the code I did (first method):
import java.util.Random;
public class questionThree
{
public static void main(String[] args)
{
int [] numbers = new int [9];
Random rand = new Random();
for (int i = 0; i <9; i++)
{
//setting random numbers in array without repeating
numbers[i] = checkForANumber(rand, numbers, i);
}
//print all nums
for(int val: numbers) System.out.println("The next value is " +
val);
for (int i = 1; i <= 10; i++)
{
boolean exist = false;
for(int val : numbers)
{
if(val == i){
exist = true;
}
}
if (!exist) System.out.println("The missing number is " + i);
}
}
private static int checkForANumber(Random rand, int[] numbers, int i){
int n = rand.nextInt(10) + 1;
boolean NumAlreadyExist = false;
for(int j = 0; j < i; j++)
{
if(numbers[j] == n){
NumAlreadyExist = true;
}
}
if(NumAlreadyExist) return checkForANumber(rand, numbers, i);
else return n;
}
}
Output:
The next value is 9
The next value is 3
The next value is 8
The next value is 6
The next value is 7
The next value is 10
The next value is 4
The next value is 2
The next value is 1
The missing number is 5
Im very new to Java, and I'm trying to write a program using arrays and arraylists where you enter in however many values you want, and it outputs how many values are between two parameters using asterisks.
ex:
[5,14,23,43,54,15]
1-10: *
11-20: **
21-30:*
31-40:
41-50:*
51-60: *
And so on. Here's what I have so far, but I'm getting errors and out of bounds exceptions. Can anyone say whether or not I'm on the right track or not? Any help is appreciated!
package arraylists;
import java.util.ArrayList;
import java.util.Scanner;
public class numberslists {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner reader = new Scanner(System.in);
ArrayList numbers = new ArrayList();
int [] number = new int[10];
int x, count = 0;
System.out.println("how many numbers would you like?");
count = reader.nextInt();
System.out.println("enter in those numbers please");
for (x=0; x < count; x++){
number[x] = reader.nextInt();
numbers.add(number[x]);
}
System.out.println(numbers);
int x10 = numbers.indexOf(number[x] < 10);
numbers.remove(x10);
System.out.println(numbers);
}
}
In short, as Lahiru said, you need to change the line: int x10 = numbers.indexOf(number[x] < 10);
The main problem with your code is the expression number[x] < 10 which returns a boolean (true or false). Therefore the numbers.indexOf(number[x] < 10) is going to return 1 or -1.
Finally, when the code gets to numbers.remove(x10); and if is -1 (for false) then you will get java.lang.ArrayIndexOutOfBoundsException because there is no way to do a numbers.remove(-1);. See the documentation.
There is room for improvement in your code. Below is a suggestion to what you could do. But just look at this suggestion after you try fixing your own code (so you can have a better learning experience).
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CountOcurrancesInArray {
private static Scanner reader = new Scanner(System.in);
private static List<Integer> numbers = new ArrayList<Integer>(); // Use generics when possible: <Integer>
public static void main(String[] args) {
int x, count = 0;
System.out.println("how many numbers would you like?");
count = reader.nextInt();
System.out.println("enter in those numbers please");
for (x=0; x < count; x++){
// I don't see a need for this line. number[x] = reader.nextInt();
numbers.add(reader.nextInt());
}
System.out.println(numbers);
int[] comparingNumbers = requestComparingNubers();
System.out.println("You entered these numbers: " + numbers);
String matchingNumbers = checkForNumbersInTheList(comparingNumbers);
System.out.println("Numbers between " + comparingNumbers[0] + "-" + comparingNumbers[1] + ":" + matchingNumbers);
}
/**
* Counts how many entries are in the list between 'comparingNumbersInput'
* #param comparingNumbersInput
* #return number of entries as asterisks "*"
*/
private static String checkForNumbersInTheList(int[] comparingNumbersInput) {
String result = "";
for(Integer i : numbers) {
if (i >= comparingNumbersInput[0] && i <= comparingNumbersInput[1]) {
result += "*";
}
}
return result;
}
/**
* Asks the user to enter 2 numbers to be compared against the all the numbers in the list.
* #return returns a int[2] sorted ascendingly
*/
private static int[] requestComparingNubers() {
int [] result = new int[2];
System.out.println("Counting how many numbers there are in between x and y.");
System.out.println("What is the first number?");
result[0]=reader.nextInt();
System.out.println("What is the second number?");
result[1]=reader.nextInt();
// Sort comparingList
if (result[0] > result[1]) {
int temp = result[1];
result[1] = result[0];
result[0] = temp;
}
return result;
}
}
Declare Array after getting count from user.
int x, count = 0;
System.out.println("how many numbers would you like?");
count = reader.nextInt();
int [] number = new int[count];
Also have a look at the Line of code that caused the error.
To me, this makes more sense as a Map, where you store a counter for each range found in the array of inputs. Now that means you have to first figure out what the range if that each input fits within, then update your counter that matches the range. Since we have to calculate the range as a String for output and you want the counter to be represented as a String of asterisk anyway, Storing the range as a String for the Map.key and the counter as a String of asterisk as the Map.value works nicely.
Here is some example code that does just that, where numbers is the ArrayList of the original values input by a user.
//Declare a Map that stores the range as a String ( "01-10") as the key
//and a counter in astericks as the value
Map<String,String> counters = new HashMap<>();
//Loop over the array ov values
for(Integer value: numbers){
//For each value calculate the diviser by diving by 10
Integer lowRange = value / 10;
//To get the low range, multiply the diviser by 10 and add 1
lowRange = (10 * lowRange) + 1;
//The high range is 9 mor ethan the low range
Integer highRange = lowRange + 9;
//Finally calcualte what the range looks like as a String
//Note that it handles "1" as a special case by prepending a "0" to make the value "01"
String rangeString = ((lowRange < 10) ? "0" + lowRange : lowRange) + "-" + highRange;
//Now check the map to see if the rangeString exists as a key, meaning
//we have previously found a value in the same range
String count = "";
if(counters.containsKey(rangeString)){
//If we found the same range, get the previous count
count = counters.get(rangeString);
}
//Place the count back into the map keyed off of the range and add an asterick to the count String
counters.put(rangeString, count + "*");
}
//Finally iterate over all keys in the map, printing the results of the counters for each
for(String range: counters.keySet()){
System.out.println(range + " " + counters.get(range));
}
As an example of output, if the user inputs the values:
[5,14,23,43,54,15,41]
The output would be:
01-10 *
11-20 **
41-50 **
51-60 *
21-30 *
Java arrays are zero-based index. For example, if you declare an array with 10 elements, the index of these elements will be from 0 to 9.
In your code snippet below, when java finishes the "for" loop
for (x=0; x < count; x++){
number[x] = reader.nextInt();
numbers.add(number[x]);
}
The value of x variable will be equal to the number of elements you have inputted to the number array (x = count).
So, when you get the element at x position as below:
int x10 = numbers.indexOf(number[x] < 10);
If x < 10, you will get -1 for x10. Then an exception will occur at:
numbers.remove(x10);
If x >= 10, an ArrayIndexOutOfBoundsException will occur at number[x]
Yet another Homework question
import java.util.ArrayList;
import java.util.Scanner;
import java.util.*;
public class numberlists {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner reader = new Scanner(System.in);
LinkedList < Integer > numbers = new LinkedList < Integer > ();
//int [] number = new int[10]; no need, and the input is variable size
int x, count = 0;
System.out.println("how many numbers would you like?");
count = reader.nextInt();
System.out.println("enter in those numbers please");
Map < Integer, Integer > range_numbers = new HashMap < Integer, Integer > ();
for (x = 0; x < count; x++) {
//number[x] = reader.nextInt(); no need
numbers.add(reader.nextInt());
int rs = ((int) numbers.getLast() / 10) * 10 + 1; //range start for number i.e rs(15)=11
if (!range_numbers.containsKey(rs)) { //check if has number in that range
range_numbers.put(rs, 1);
} else { //gets the prev count, add 1 and stores back for range
range_numbers.put(rs, range_numbers.get(rs) + 1);
}
}
System.out.println(numbers);
Map < Integer, Integer > sortedpairs = new TreeMap < Integer, Integer > (range_numbers); // need to sort
for (Map.Entry < Integer, Integer > pair: sortedpairs.entrySet()) {
System.out.printf("\n%d-%d: %s", pair.getKey(), pair.getKey() + 9,
new String(new char[pair.getValue()]).replace("\0", "*"));
//little trick to repeat any string n times
}
}
}
Enjoy.
This question already has answers here:
Maximum number that can be formed from the given digits
(2 answers)
Closed 7 years ago.
I have a number which I need to re-arrange to find the largest number. As an example input number is 355 so for this number I need to find the largest number which can be formed by re-arranging the digits. So for 355, various combination can be possible after re-arranging -
355, 535 and 553
So here 553 is the largest number and that's what I need to return. Basically given an input, I need to find the largest number which can be formed by re-arranging the numbers.
How should I go ahead and solve this problem?
So far I am able to do shuffle the numbers like this:
public static void main(String[] args) {
//generate random number
int number = 355;
//put each digit in an element of a list
List<Character> numberList = new ArrayList<Character>();
for (char c : String.valueOf(number).toCharArray()) {
numberList.add(c);
}
//shuffle
Collections.shuffle(numberList);
//output
String shuffledNumber = "";
for (Character c : numberList) {
shuffledNumber += c;
}
System.out.println(shuffledNumber);
}
But I am confuse how can I find the largest number given an input after rearranging the numbers.
If you need to rearrange the numbers so that, if we read it from left to write, it should be largest number among all the arrangements,
then it's simple, you just need to sort the number in descending order.
Try this code :
public static void main(String args[]) {
//generate random number
int number = 355;
String numStr = number + "";
char[] numCharArr = numStr.toCharArray();
int[] numArr = new int[numStr.length()];
for(int i = 0 ; i < numCharArr.length ; i ++) {
numArr[i] = Integer.parseInt(numCharArr[i] + "");
}
// Sort in descending order
for(int i = 0 ; i < numArr.length ; i ++) {
for(int j = 0 ; j < i ; j ++) {
if(numArr[i] > numArr[j]) {
// swap
int temp = numArr[i];
numArr[i] = numArr[j];
numArr[j] = temp;
}
}
}
String largestNumber = "";
for(int i : numArr) {
largestNumber += i;
}
System.out.println("The largest number is : " + largestNumber);
}
Unless you actually need to create all the combinations, I wouldn't bother.
You can actually do it using arithmetic, but in this case it's probably easier in terms of strings
naive algorithm:
source number = number.toString()
target number = ""
While source number is not empty
d = remove biggest number from source number
target number += d
You can then convert target number back to an int if required.
Another approach would be count the number of 9s and append that many 9s to the result. Repeat for 8s, then 7s, then 6s...