[java]Longest consecutive integers sequence, debug - java

I have wrote a method for the question:
input: an array of integers
return: the length of longest consecutive integer sequence.
like: for {9,1,2,3}, return 3, cuz{1,2,3}
the method doesnt run well. hope someone could help me with debugging.
public int solution(int[] arr){
int counter = 1;
int max = arr[1];
//find the max in the array
for (int i : arr){
if (i > max){
max = i;
}
}
int[] nArr = new int[max];
for (int i : arr){
nArr[i] = i;
}
List<Integer> counters = new ArrayList<>();
for (int i = 0; i < max; i++){
if (nArr[i] == nArr[i+1] - 1){
counter++;
}else{
counters.add(counter);
counter = 1;
}
}
max = counters.get(1);
for (int i : counters){
if (i > max){
max = i;
}
}
return max; }
thanks a lot!!!

You dont need to use ArrayList... If all you want is max count of sequential integers, then try this:
int[] a = somethingBlaBla;
int counter = 0; // Stores temporary maxes
int secCounter = 0; //Stores final max
for(int j = 0; j<a.length-1; j++){ // Iterate through array
if(a[j] == a[j+1]-1){
counter++; // If match found then increment counter
if(counter > secCounter)
secCounter = counter; // If current match is greater than stored match, replace current match
}
else
counter = 0; // Reset match to accumulate new match
}
System.out.println(secCounter);
As for your method, the first thing I noticed is that max has value of greatest number in array and not the size of array. So if my array is something like {1,2,3,45,6,7,8,9}, it will throw indexOutOfBoundsException because its gonna try get 45th element in array which is not present.

Related

How to get the multiple index of the same large numbers in an array?

I am trying to get the indices of large numbers within an array and I am having trouble doing so..
My code works if there is only one large number in the array. However, if there is one or more of the same large number, it does not works.
For example,
if I have an array {2,1,1,2,1}, it should return me the index 0 and 3 (this does not)
if I have an array {2,1,3,2,1}, it will then return me index 2. (this works)
Currently, I am trying to store the index by making use of an array, however in my code, as given in my example above, it only returns me the index of the first large number it found.
My code:
class Main {
public static void getIndexOfMax(int array[]) {
int max = array[0];
int pos = 0;
int max_index[] = new int[array.length];
int counter = 0;
for(int i=1; i<array.length; i++) {
if (max < array[i])
{
pos = i;
max = array[i];
max_index[counter] = pos;
counter += 1;
}
}
public static void main(String[] args) {
int[] num = {2,1,1,2,1};
getIndexOfMax(num);
}
}
Thanks in advance for any replies!
You need to check another case when you find the maximum value again and store the index. And when the new maximum value starts the counter from 0 again.
public static void printIndexOfMax(int array[]) {
int max = 0;
int max_index[] = new int[array.length];
int counter = 0;
for (int i = 0; i < array.length; i++) {
if (max <= array[i]) { // Allowing same maximum number
if (max < array[i]) // Start counter from 0 when new maximum value found
counter = 0;
max = array[i];
max_index[counter] = i;
counter++;
}
}
for (int i = 0; i < counter; i++) {
System.out.println(max_index[i]);
}
}
You can have another conditional stating, if max is equal to an array element, then store that element index also. Then you would have to declare another array for the max index positions.
`if (max < array[i]) {
pos = i;
indexStorage.add(pos)
max = array[I];
max_index[counter] = pos;
counter += 1;
}`

Finding frequency of most frequent element inside an array

I have an array:
int[] anArray = new int[6];
What if the array contained 1,4,5,4,4? How can I get the most matches? In this case 4 is the most frequent number, and there are three of them, so the function should return 3.
Or if I have 1,2,1,2,3 it should return 2.
Or if I have 4,0,1,2,3 it should return 1.
I really can't figure it out. I tried this:
public static int getCorrectMatches(int[] flowers) throws Exception {
int highest = 0;
for(int index = 0; index < 5; index++) {
int count = countMatches(flowers, index);
if(count > highest) {
highest = index;
}
}
return highest;
}
public static int countMatches(int[] array, int match) throws Exception {
int count = 0;
for(; count < array.length && array[count] == match; count++);
return count;
}
Which didn't work. I'd appreciate any help.
Iterate over the array and for each number store a counter in a hashmap where the key of the map is the number and the value is the counter that tracks the number of occurrences. The first time you encounter a new number (for which there is no key) you'll need insert a new counter. The next time you encounter that same number you simply update the existing counter with a new number.
It also wouldn't be too hard to keep a running 'most matches' number and update it each time you are updating a counter.
public static int numberOfMatches(int[] numbers) {
int mostMatches = 0;
for(int i = 0; i < numbers.length; i++) {
int matches = 0;
int holder = numbers[i];
for(int number : numbers) {
if(number == holder) {
matches++;
}
}
if(matches > mostMatches)
mostMatches = matches;
}
return mostMatches;
}
This accepts an array. It checks the length of the array, and loops for each slot.
For each slot, I create 2 variables. holder grabs the value in the slot, and we increase matches any time there is a match.
Once all possible matches have been found for that slot, it compares the amount of matches found to the highest amount of matches found so far.
for each index in array
HashMap.put(number on index i, occurrences) +=1
check biggest value in the hash map
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put(K,%20V)
Your countMatches() method is incorrect. Decouple count from the loop variable and check the equality inside the loop, instead of putting it in the loop condition. Change it to something like this:
public static int countMatches(int[] array, int match) throws Exception {
int count = 0;
for(int i=0; i< array.length ; i++){
if(array[i] == match) count++;
}
return count;
}
Also, if I were you, I'd change
for(int index = 0; index < 5; index++) {
to,
for(int index = 0; index < flowers.length; index++) {

array with non repeating numbers from a range in ascending order, java

Im trying to generate an array with 1000 integers of non-repeating numbers in ascending order from 0 to 10,000
So far what I have is:
public static void InitArray(int[] arr) { // InitArray method
int i, a_num; // int declared
Random my_rand_obj = new Random(); // random numbers
for (i = 0; i <= arr.length-1; i++) // for loop
{
a_num = my_rand_obj.nextInt(10000); // acquiring random numbers from 0 - 10000
arr[i] = a_num; // numbers being put into array (previoulsy declared of size 1000)
}
}
public static void ShowArray(int[] arr) { // ShowArray method
int i; // int declared
for (i = 0; i <= arr.length-1; i++) { // for loop
System.out.print(arr[i] + " "); // show current array content
}
System.out.println(); // empty line
}
public static void Sort(int[] arr) { // SortArray method
int i, min, j; // int decalred
for (i = 0; i < arr.length-1; i++) { // for loop
min = i; // min is i
for (j = i + 1; j < arr.length; j++) { // nested for loop
if (arr[j] < arr[min]) { // if statement
min = j; // j is the new minimum
}
}
int swap = arr[min]; // swap "method"
arr[min] = arr[i];
arr[i] = swap;
}
}
Is there any way to check the numbers are not repeating? Is there a function besides the random generator that will let me generate numbers without repeating? Thanks for any help
You can declare array of size 10,000
and init the array in away that each cell in the array will holds the value of it's index:
int [] arr= new int[10000];
for (int i=0 i < arr.length; i++){
arr[i] = i
}
Now you can shuffle the array using java Collections.
and take the first 1000 items from the array and sort then using java sort.
This will do I believe..
HashSet hs = new HashSet();
for(int i=0;i< arr.length;i++)
hs.add(arr[i]);
List<Integer> integers=new ArrayList<>(hs);
Collections.sort(integers);
A very simple solution is to generate the numbers cleverly. I have a solution. Though it may not have an even distribution, it's as simple as it can get. So, here goes:
public static int[] randomSortedArray (int minLimit, int maxLimit, int size) {
int range = (maxLimit - minLimit) / size;
int[] array = new int[size];
Random rand = new Random();
for (int i = 0; i < array.length; i++ ) {
array[i] = minLimit + rand.nextInt(range) + range * i;
}
return array;
}
So, in your case, call the method as:
int randomSortedArray = randomSortedArray(0, 10_000, 1_000);
It's very simple and doesn't require any sorting algorithm. It simply runs a single loop which makes it run in linear time (i.e. it is of time complexity = O(1)).
As a result, you get a randomly generated, "pre-sorted" int[] (int array) in unbelievable time!
Post a comment if you need an explanation of the algorithm (though it's fairly simple).

Why am I receiving an ArrayIndexOutofBoundsException?

In my JAVA code, I am given a data and I have to find the mode. Everything successfully compiled, and every method works. However, when I try to access the mode, I get an java.lang.ArrayIndexOutOfBoundsException: 987 in my terminal window. The highlighted portion is in the following method, which is one of my max methods. The data array, by the way, is just int [] data.
public int maxOfData(int [] oa)
{
int max = oa[0];
for (int i = 1; i < size; i++)
{
if (oa[i] > max)
max = oa[i];
}
return max;
}
The exception is on the line if(oa[i] > max)
And the mode code is this:
public int[] modeOfData()
{
int[] tally = new int[maxOfData() + 1];
for( int i = 0; i < size; i++)
{
tally[data[i]]++;
}
//max contains frequency of modes
int max = maxOfData (tally);
int count = 0;
for( int i = 0; i < tally.length; i++)
{
if( tally[i] == max )
count++;
}
//count occurence of maxValue in tally (for)
//that determines how many modes there are
//declare another int called modes
int[] modes = new int[count];
//size of array should be count
//loop through tally and extract modes: it's the index value.
int pos = 0;
for( int i = 0; i < tally.length; i++)
{
if(tally[i] == count)
modes[pos++] = i;
}
return modes;
//modes are where the values are == max
}
My other max for data is the same but data instead of oa. I need both max methods, just like that, according to my teacher. So what do I do? How do I fix this?
I think the line
for (int i = 1; i < size; i++)
should be
for (int i = 1; i < oa.length; i++)
ArrayIndexOutOfBound Exception is thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array. Whenever you iterate an Array object. you need to iterate while checking the index is always lesser than its length
for example,
for(int i=1;i<array.length;i++){
//access array content in ith position
System.out.println(array[i]);
}
Your size variable has the value of an illegal array index. that's the problem
Look at the number stored into size and then check to see what size you declared oa[] to be. If size is bigger than the size of oa[] then you have a problem.
Problem is in this part of code
int max = oa[0];
for (int i = 1; i < size; i++)
{
if (oa[i] > max)
max = oa[i];
}
rewrite the method maxOfData(int [] oa) with proper checks like this
public int maxOfData(int[] oa) {
if (oa == null) {
throw new IllegalArgumentException("Input array is null");
}
int max=oa[0];
for (int i = 1; i < oa.length; i++) {
if (oa[i] > max)
max = oa[i];
}
return max;
}
if input array is null it should not be processed.

Array of 20 rolls of one die in java

I'm working on an exercise that requires that I print 20 rolls of a die out and group repeated values in parentheses. My code below follows the pseudocode the book I'm reading says to use. I am able to group the repeated values in parentheses but the next exercise requires that I group the values that are repeated the most in parentheses.
For example:
(333)51314121(22)326(55)14
would be:
(333)51314121223265514
EDIT: If there is more than one largest group of repeated values only the first is to be grouped in parentheses.
How can I accomplish this? Many thanks in advance for any help on this.
public void run() {
Random generator = new Random();
ArrayList<Integer> a = new ArrayList<Integer>();
for (int i = 0; i < 21; i++) {
int die = generator.nextInt(6)+ 1;
a.add(die);
}
for (int j = 0; j < a.size() - 1; j++) {
if (inRun) {
if (a.get(j) != a.get(j - 1)) {
System.out.print(")");
inRun = false;
}
}
else {
if (a.get(j) == a.get(j + 1)) {
System.out.print("(");
inRun = true;
}
}
System.out.print(a.get(j));
}
if (inRun) {
System.out.print(")");
}
}
You don't really need a data structure other than an ordinary array.
You can make it O(n) by checking while inserting:
If the added number equals the previous, you increment the sequence count - if not, you reset the count.
When you increment a sequence count, check if it is bigger than the already stored max sequence count length - if it is bigger, the current sequence count becomes the max sequence count.
Check the code - some comments there to help understanding (run demo online here):
public void run() {
Random generator = new Random();
int[] a = new int[20];
int biggerSequence = 1; // starts pointing to the first char
int biggerSequenceEndIndex = 1; // starts pointing to the first char
int currentSequence = 1;
int previous = -1;
for (int i = 0; i < 20; i++) {
int die = generator.nextInt(6)+ 1;
a[i] = die;
if (die == previous) { // if inserted equals previous
currentSequence++; // increment sequence
if (currentSequence > biggerSequence) { // if it is bigger than max
biggerSequence = currentSequence; // max becomes it
biggerSequenceEndIndex = i+1;
}
} else {
previous = die;
currentSequence = 1; // reset the count
}
}
for (int i = 0; i < a.length; i++) {
if (i == biggerSequenceEndIndex-biggerSequence) { System.out.print("("); }
System.out.print(a[i]);
if (i+1 == biggerSequenceEndIndex) { System.out.print(")"); }
}
}
Example outputs:
(1)2345678901234567890
(11)345678901234567890
1(22)45678901234567890
1(22)45578901234567890
123456789012345678(99)
54(3333)43514564513551
You need to make multiple passes over the array. Go through it once and tally up how long all the runs are. Then decide what the maximum run length is. Finally, go back and print out the array, putting parentheses around runs of the maximum length.
Try something like this (exact implementation left to you):
runContents = a list containing the first random number
runLength = [1], i.e. a one element list with the number 1 in it
maxLength = 1
for each subsequent random number you want to consider {
if the last element of runContents == the next random number {
add 1 to the last element of runLength
} else {
if maxLength < the last element of runLength {
maxLength = the last element of runLength
}
append the random number to runContents
append a 1 to runLength
}
}
i = 0
while i < length(runContents) {
if runLength[i] == maxLength {
print runLength[i] copies of runContents[i] surrounded by parens
} else {
print runLength[i] copies of runContents[i]
}
}
Just try storing the number of repeated values starting at any given index. Something like:
public void run(){
Random generator = new Random();
ArrayList<Integer> a = new ArrayList<Integer>();
for (int i = 0; i < 21; i++) {//Generate your numbers
int die = generator.nextInt(6)+ 1;
a.add(die);
}
//store the number of repeats by index. (index is key, # of repeats is key)
HashMap<Integer, Integer> repeats = new HashMap<Integer, Integer>();
//This will find store the number of repeated numbers starting at any given index.
int index = 0;
repeats.put(index, 1);
for(int i = 1; i < a.size(); i++){
if(a.get(i) == a.get(index)){//Repeated values occurring
repeats.put(index, repeats.get(index) + 1);
} else {//End of a repeated sequence (even if that sequence was only 1 number long)
repeats.put(i, 1);
index = i;
}
}
//Find the index at which the maximum number of repeats occurs
int max = 0;
int startIndex = 0;
for(Integer i : repeats.keySet()){
//If the number of repeats is bigger than anything seen before
if(repeats.get(i) > max){
//Store the number of repeats and the index at which they start
max = repeats.get(i);
startIndex = i;
}
}
//print everything out
for(int i = 0; i < a.size(); i++){
if(i == startIndex)//Prints the open parenthesis before the repeats start
System.out.print("(");
System.out.print(a.get(i)); //Prints the number
if(i == startIndex + max)
System.out.print(")");//Prints the close parenthesis after the repeats end
}
}
Note that this algorithm assumes that there is only 1 repeated sequence of the maximum size. Should there be multiple that you want to keep, you'll have to store all indexes in another list. But that's a minor fix to the solution that would look like so:
ArrayList<Integer> startIndeces = new ArrayList<Integer>();
int max = 0;
for(Integer i : repeats.keySet()){
//If the number of repeats is bigger than anything seen before
if(repeats.get(i) > max){
//Store the number of repeats and the index at which they start
max = repeats.get(i);
startIndeces = new ArrayList<Integer>();
startIndeces.add(i);
} else if(repeats.get(i) == max)
startIndeces.add(i);
}
Otherwise the algorithm stores the first instance of the longest sequence.

Categories

Resources