Extracting a sequence from an array - java

I am writing code that reads an integer array in from a file, checks for an increasing sequence of numbers, and prints the length of the array as well as the sequence of numbers itself. The code I have written appears to correctly print the array, showing that is has found the array in the file, and count off the longest sequence of numbers, but it doesn't quite get the exact sequence right. Below is the code in its entirety and the output.
public static void main(String[] args) throws IOException {
File file = new File("input.txt");
Scanner s = null;
final int MAX_SIZE = 100;
int count = 0;
int[] tempArray = new int[MAX_SIZE];
try {
s = new Scanner(file);
int arrayAddress = 0;
System.out.println("File found!");
while (s.hasNextInt()) {
count++;
tempArray[arrayAddress] = s.nextInt();
arrayAddress++;
}
s.close();
}
catch (FileNotFoundException noFile) {
System.out.println("File not found.");
}
int[] inputArray = new int[count];
for (int i = 0; i < count; i++)
{
inputArray[i] = tempArray[i];
}
int sequence = 0;
int maxSequence = 0;
int sequenceEnd = 0;
for (int j = 0; j < count; j++) {
for (int k = j; k < count - 1; k++) {
if (inputArray[k + 1] == inputArray[k] + 1 ) {
sequence++;
sequenceEnd = k;
}
if (sequence > maxSequence) {
maxSequence = sequence;
sequence = 0;
}
}
}
int temp = 0;
System.out.println("The array is: " + Arrays.toString(inputArray));
System.out.println("The longest sequence of increasing numbers is " + maxSequence);
System.out.println("The sequence is as follows: ");
for (int i = sequenceEnd - maxSequence; i < sequenceEnd; i++) {
temp = inputArray[i];
System.out.println(temp);
}
}
The output for the code above on my sequence was as follows:
File found!
The array is: [7, 2, 13, 4, 5, 18, 11, 1, 20, 17, 15, 10, 19, 8, 16, 12, 6, 14, 9, 3]
The longest sequence of increasing numbers is 2
The sequence is as follows:
2
13
I really hope this isn't a minor oversight, but I can't seem to figure out where I have made an error. Thanks in advance if you have time to look over this and assist me.

There are two problems in your code:
(1) Finding the maximum length of the sequence
Your reset of the sequenc length
if (sequence > maxSequence) {
maxSequence = sequence;
sequence = 0;
}
should not be located within the inner loop. That is the one, where you are still counting the elements. You want to move it to the outer loop, i.e. from
for (int j = 0; j < count; j++) {
for (int k = j; k < count - 1; k++) {
//current location
}
}
for (int j = 0; j < count; j++) {
for (int k = j; k < count - 1; k++) {
}
//assumingly desired location
}
(2) Print sequence
The offset of your print-loop is off by one element and should be
for (int i = sequenceEnd - maxSequence1; i < sequenceEnd; i++) {
temp = inputArray[i-1];
System.out.println(temp);
}
Once maxSequence contains the correct amount of elements (i.e. not 2 as it is currently the case), it will print the entire sequence.

Related

Fill 2D array square and print in specific patterns

Ive been working on this assignment question for about 4 days now and I'm about to go crazy. We have specific directions to follow for this code;
"Your program should proceed as follows:
Display a welcome message.
Prompt the user for an integer which is 3. If the number entered is < 3. keep prompting the user until they enter a number 3 (use a do/while). This number will determine the size of the square array.
Fill the array as per pattern 1 and display it using printf to format the array.
Fill the same array as per pattern 2 and display it using printf t0 format the array.
Display a closing message."
Pattern:
I'm still stuck on pattern one. I tried to do first do a for loop which in it there's an if statement that checks if the column number is even or not, if it is, to print out the code backwards. The question also recommends using a while loop and a do/while loop...?
Also any tips on to how to go about the second patterns.
Here is my code.
import java.util.Scanner;
public class a3q33
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
int n;
do
{
System.out.println("How many rows/columns do you want your array to have? (Must be at least 3)");
n=keyboard.nextInt();
} while(n < 3);
int [][] arr = new int [n][n];
int i, j, k=1;
for(i=0;i<n;i++)
{
if(i % 2 != 0)
{
for(j=n;j>0;j--)
{
k = k+n;
arr[i][j]=k;
k--;
}
}
else
{
for(j=0;j<n;j++)
{
arr[i][j]=k;
k++;
}
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
System.out.printf(arr[i][j]+" ");
}
System.out.printf("");
System.out.println();
}
}
}
Any help would be greatly appreciated!
I assume that you meant "row" instead of "column" for the condition check given that the convention is arr[row][column]?
Also, the for loop in your code:
for(j=n;j>0;j--)
This will decrement the row/column index down to 1 and not 0. So you will miss one element at arr[0][...] or arr[...][0].
Also, j=n will be out of bound.
Instead, try using:
for(j=n-1;j>-1;j--)
It would be a good first steps to look into.
import java.util.Scanner;
public class a3q33{
public static void main(String[] args){
Scanner keyboard = new Scanner(System.in);
int n;
do{
System.out.println("How many rows/columns do you want your array to have? (Must be at least 3)");
n=keyboard.nextInt();
} while(n < 3);
int count = 1;
int [][] arr = new int [n][n];
for(int i = 0;i<n; i++){
if(i%2==0){
for(int j = 0;j<n; j++){
arr [i][j] = count;
count++;
}
}
else{
for(int j = n-1;j>=0; j--){
arr [i][j] = count;
count++;
}
}
}
System.out.println("\nPattern 1 \n");
// print the array
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
System.out.printf("%d\t",arr[i][j]);
}
System.out.println();
}
// reset count back to 1 and fill the array in the same way only without the if/else
// for n = 5 for example this will produce [1, 2, 3, 4, 5 ]
// [6, 7, 8, 9, 10]
// [11,12, 13, 14, 15]
// [16,17, 18, 19, 20]
// [21,22, 23, 24, 25]
count = 1;
for(int i = 0;i<n; i++){
for(int j = 0;j<n; j++){
arr [i][j] = count;
count++;
}
}
// rotate arrays using arraycopy; for array at index 1 rotate by one, at index 2 by 2 and so on see
//http://stackoverflow.com/questions/31174840/how-to-rotate-an-array
//
for (int i = 1; i<n; i++){
int [] temp = new int [n];
for (int j = 0; j < n; j++) {
temp[(j + i) % n] = arr[i][j];
}
System.arraycopy(temp, 0, arr[i], 0, n);
arr[i]=temp;
}
System.out.println("\nPattern 2 \n");
// print the array
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
System.out.printf("%d\t",arr[i][j]);
}
System.out.println();
}
}
}
You can achieve this by checking the modulo:
for (int i = 0; i < n; i++) {
int start = i * n;
for (int j = 0; j < n; j++) {
arr[i][j] = i * n + ((i % 2 === 0) ? (j + 1) : (n - j));
}
}

Trouble with splitting an array into chunks

I have an array:
private static int[] array = {5, 2, 1, 6, 3, 7, 8, 4};
I'm trying to split it into a two-dimensional array with x amount of chunks, where all of the chunks have an equal length (in my case, 2), then assign each value of the original array to a corresponding index within the array. It would then increment the index of the chunk number and reset the index iterating through the individual arrays hit the length of one.
Problem is, the code I wrote to perform all that isn't outputting anything:
public class Debug
{
private static int[] array = {5, 2, 1, 6, 3, 7, 8, 4};
private static void chunkArray(int chunkSize)
{
int chunkNumIndex = 0;
int chunkIndex = 0;
int numOfChunks = (int)Math.ceil((double)array.length / chunkSize);
int[][] twoDimensionalArray = new int[numOfChunks][chunkSize];
for (int i = 0; i < array.length; i++)
{
twoDimensionalArray[chunkNumIndex][chunkIndex] = array[i];
chunkIndex++;
while(chunkNumIndex < numOfChunks)
{
if (chunkIndex == chunkSize)
{
chunkNumIndex++;
chunkIndex = 0;
}
}
}
for(int i = 0; i < chunkNumIndex; i++)
{
for(int j = 0; j < chunkIndex; j++)
{
System.out.printf("%5d ", twoDimensionalArray[i][j]);
}
System.out.println();
}
}
public static void main(String args[])
{
chunkArray(2);
}
}
Could anyone be of assistance in debugging my program?
The problem is that you have an unnecessary while(chunkNumIndex < numOfChunks) which makes no sense. The if statement is sufficient to iterate your variables correctly:
for (int i = 0; i < array.length; i++) {
twoDimensionalArray[chunkNumIndex][chunkIndex] = array[i];
chunkIndex++;
if (chunkIndex == chunkSize) {
chunkNumIndex++;
chunkIndex = 0;
}
}
Also, remember that the values of chunkNumIndex and chunkIndex are dynamic, so for the last for loops, use twoDimensionalArray.length and twoDimensionalArray[0].length instead:
for(int i = 0; i < twoDimensionalArray.length; i++) {
for(int j = 0; j < twoDimensionalArray[0].length; j++) {
System.out.printf("%5d ", twoDimensionalArray[i][j]);
}
}
You're making this unnecessarily hard, there is no need to keep counters for chunkIndex and chunkNumIndex, we can just div and mod i.
int numOfChunks = (array.length / chunkSize) + (array.length % chunkSize == 0 ? 0 : 1);
int[][] twoDimensionalArray = new int[numOfChunks][chunkSize];
for (int i = 0; i < array.length; i++) {
twoDimensionalArray[i / chunkSize][i % chunkSize] = array[i];
}
Something like this should already do the job.

Finding differences in a array

I'm not sure how to set the differences to store in the array differences. The numbers stored should be 5-(1+2+3), 7-(1,2,4), 8-(3,5,9) : the output should be differences[0]= 1, differences[1] = 0, differences[2] = 9
import java.util.Scanner;
public class Main {
public static int[][] Array = { { 5, 1, 2, 3 }, { 7, 1, 2, 4 }, { 8,3,5,9 } }; //My 2D array//
int [] differences = new int [3];
public static int[] Sum(int[][] array) {
int index = 0; //setting the index to 0//
int temp[] = new int[array[index].length]; //making a temperary variable//
for (int i = 0; i < array.length; i++) {
int sum = 0;
for (int j = 1; j < array[i].length; j++) {
sum += array[i][j]; //going to add the rows after the first column//
}
temp[index] = sum;
for(int a = 0; a<differences.length; a++){
if(sum != array[index][0])
sum -= array[i][j];
System.out.println("the first integer " + array[index][0] + " the answer is " + sum); //going to print out the first integer each row and print out the sum of each row after the first column//
index++; //index is going to increment//
}
return temp;
}
public static void main(String[] args) {
new Main().Sum(Array);
}
}
Output:
the first integer 5 the answer is 6
the first integer 7 the answer is 7
the first integer 8 the answer is 17
Why do you want to complicate the task of yours when it is this simple? :)
public int[] Sum(int[][] array)
{
int sum;
for(int i = 0; i < Array.length; i++)
{
sum = Array[i][0] * -1;
for(int j = 1; j < Array[i].length; j++)
{
sum += Array[i][j];
}
differences[i] = sum;
}
return differences;
}
If I understand your problem correctly, I think that you want to put a
differences[i] = Array[i][0] - sum
somewhere in your code

Printing out the least occurring elements in an array

OK, so I found this question from a few days ago but it's on hold and it won't let me post anything on it.
***Note: The values or order in the array are completely random. They should also be able to be negative.
Someone recommended this code and was thumbed up for it, but I don't see how this can solve the problem. If one of the least occurring elements isn't at the BEGINNING of the array then this does not work. This is because the maxCount will be equal to array.length and the results array will ALWAYS take the first element in the code written below.
What ways are there to combat this, using simple java such as below? No hash-maps and whatnot. I've been thinking about it for a while but can't really come up with anything. Maybe using a double array to store the count of a certain number? How would you solve this? Any guidance?
public static void main(String[] args)
{
int[] array = { 1, 2, 3, 3, 2, 2, 4, 4, 5, 4 };
int count = 0;
int maxCount = 10;
int[] results = new int[array.length];
int k = 0; // To keep index in 'results'
// Initializing 'results', so when printing, elements that -1 are not part of the result
// If your array also contains negative numbers, change '-1' to another more appropriate
for (int i = 0; i < results.length; i++) {
results[i] = -1;
}
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) { // <= so it admits number with the SAME number of occurrences
maxCount = count;
results[k++] = array[i]; // Add to 'results' and increase counter 'k'
}
count = 0; // Reset 'count'
}
// Printing result
for (int i : results) {
if (i != -1) {
System.out.println("Element: " + i + ", Number of occurences: " + maxCount);
}
}
}
credit to: https://stackoverflow.com/users/2670792/christian
for the code
I can't thumbs up so I'd just like to say here THANKS EVERYONE WHO ANSWERED.
You can also use an oriented object approach.
First create a class Pair :
class Pair {
int val;
int occ;
public Pair(int val){
this.val = val;
this.occ = 1;
}
public void increaseOcc(){
occ++;
}
#Override
public String toString(){
return this.val+"-"+this.occ;
}
}
Now here's the main:
public static void main(String[] args) {
int[] array = { 1,1, 2, 3, 3, 2, 2, 6, 4, 4, 4 ,0};
Arrays.sort(array);
int currentMin = Integer.MAX_VALUE;
int index = 0;
Pair[] minOcc = new Pair[array.length];
minOcc[index] = new Pair(array[0]);
for(int i = 1; i < array.length; i++){
if(array[i-1] == array[i]){
minOcc[index].increaseOcc();
} else {
currentMin = currentMin > minOcc[index].occ ? minOcc[index].occ : currentMin;
minOcc[++index] = new Pair(array[i]);
}
}
for(Pair p : minOcc){
if(p != null && p.occ == currentMin){
System.out.println(p);
}
}
}
Which outputs:
0-1
6-1
Explanation:
First you sort the array of values. Now you iterate through it.
While the current value is equals to the previous, you increment the number of occurences for this value. Otherwise it means that the current value is different. So in this case you create a new Pair with the new value and one occurence.
During the iteration you will keep track of the minimum number of occurences you seen.
Now you can iterate through your array of Pair and check if for each Pair, it's occurence value is equals to the minimum number of occurences you found.
This algorithm runs in O(nlogn) (due to Arrays.sort) instead of O(n²) for your previous version.
This algorithm is recording the values having the least number of occurrences so far (as it's processing) and then printing all of them alongside the value of maxCount (which is the count for the value having the overall smallest number of occurrences).
A quick fix is to record the count for each position and then only print those whose count is equal to the maxCount (which I've renamed minCount):
public static void main(String[] args) {
int[] array = { 5, 1, 2, 2, -1, 1, 5, 4 };
int[] results = new int[array.length];
int minCount = Integer.MAX_VALUE;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
results[i]++;
}
}
if (results[i] <= minCount) {
minCount = results[i];
}
}
for (int i = 0; i < results.length; i++) {
if (results[i] == minCount) {
System.out.println("Element: " + i + ", Number of occurences: "
+ minCount);
}
}
}
Output:
Element: 4, Number of occurences: 1
Element: 7, Number of occurences: 1
This version is also quite a bit cleaner and removes a bunch of unnecessary variables.
This is not as elegant as Iwburks answer, but I was just playing around with a 2D array and came up with this:
public static void main(String[] args)
{
int[] array = { 3, 3, 3, 2, 2, -4, 4, 5, 4 };
int count = 0;
int maxCount = Integer.MAX_VALUE;
int[][] results = new int[array.length][];
int k = 0; // To keep index in 'results'
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) {
maxCount = count;
results[k++] = new int[]{array[i], count};
}
count = 0; // Reset 'count'
}
// Printing result
for (int h = 0; h < results.length; h++) {
if (results[h] != null && results[h][1] == maxCount ) {
System.out.println("Element: " + results[h][0] + ", Number of occurences: " + maxCount);
}
}
Prints
Element: -4, Number of occurences: 1
Element: 5, Number of occurences: 1
In your example above, it looks like you are only using ints. I would suggest the following solution in that situation. This will find the last number in the array with the least occurrences. I assume you don't want an object-oriented approach either.
int [] array = { 5, 1, 2, 40, 2, -1, 3, 2, 5, 4, 2, 40, 2, 1, 4 };
//initialize this array to store each number and a count after it so it must be at least twice the size of the original array
int [] countArray = new int [array.length * 2];
//this placeholder is used to check off integers that have been counted already
int placeholder = Integer.MAX_VALUE;
int countArrayIndex = -2;
for(int i = 0; i < array.length; i++)
{
int currentNum = array[i];
//do not process placeholders
if(currentNum == placeholder){
continue;
}
countArrayIndex = countArrayIndex + 2;
countArray[countArrayIndex] = currentNum;
int count = 1; //we know there is at least one occurence of this number
//loop through each preceding number
for(int j = i + 1; j < array.length; j++)
{
if(currentNum == array[j])
{
count = count + 1;
//we want to make sure this number will not be counted again
array[j] = placeholder;
}
}
countArray[countArrayIndex + 1] = count;
}
//In the code below, we loop through inspecting each number and it's respected count to determine which one occurred least
//We choose Integer.MAX_VALUE because it's a number that easily indicates an error
//We did not choose -1 or 0 because these could be actual numbers in the array
int minNumber = Integer.MAX_VALUE; //actual number that occurred minimum amount of times
int minCount = Integer.MAX_VALUE; //actual amount of times the number occurred
for(int i = 0; i <= countArrayIndex; i = i + 2)
{
if(countArray[i+1] <= minCount){
minNumber = countArray[i];
minCount = countArray[i+1];
}
}
System.out.println("The number that occurred least was " + minNumber + ". It occured only " + minCount + " time(s).");

Finding multiple modes in an array of integers with 1000 elements

So I need a way to find the mode(s) in an array of 1000 elements, with each element generated randomly using math.Random() from 0-300.
int[] nums = new int[1000];
for(int counter = 0; counter < nums.length; counter++)
nums[counter] = (int)(Math.random()*300);
int maxKey = 0;
int maxCounts = 0;
sortData(array);
int[] counts = new int[301];
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
This is my current method, and it gives me the most occurring number, but if it turns out that something else occurred the same amount of times, it only outputs one number and ignore the rest.
WE ARE NOT ALLOWED TO USE ARRAYLIST or HASHMAP (teacher forbade it)
Please help me on how I can modify this code to generate an output of array that contains all the modes in the random array.
Thank you guys!
EDIT:
Thanks to you guys, I got it:
private static String calcMode(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
toString(modes);
return "";
}
public static void toString(int[] array)
{
System.out.print("{");
for(int element: array)
{
if(element > 0)
System.out.print(element + " ");
}
System.out.print("}");
}
Look at this, not full tested. But I think it implements what #ajb said:
private static int[] computeModes(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
return modes;
}
This will return an array int[] with the modes. It will contain a lot of 0s, because the result array (modes[]) has to be initialized with the same length of the array passed. Since it is possible that every element appears just one time.
When calling it at the main method:
public static void main(String args[])
{
int[] nums = new int[300];
for (int counter = 0; counter < nums.length; counter++)
nums[counter] = (int) (Math.random() * 300);
int[] modes = computeModes(nums);
for (int i : modes)
if (i != 0) // Discard 0's
System.out.println(i);
}
Your first approach is promising, you can expand it as follows:
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
// Now counts holds the number of occurrences of any number x in counts[x]
// We want to find all modes: all x such that counts[x] == maxCounts
// First, we have to determine how many modes there are
int nModes = 0;
for (int i = 0; i < counts.length; i++)
{
// increase nModes if counts[i] == maxCounts
}
// Now we can create an array that has an entry for every mode:
int[] result = new int[nModes];
// And then fill it with all modes, e.g:
int modeCounter = 0;
for (int i = 0; i < counts.length; i++)
{
// if this is a mode, set result[modeCounter] = i and increase modeCounter
}
return result;
THIS USES AN ARRAYLIST but I thought I should answer this question anyways so that maybe you can use my thought process and remove the ArrayList usage yourself. That, and this could help another viewer.
Here's something that I came up with. I don't really have an explanation for it, but I might as well share my progress:
Method to take in an int array, and return that array with no duplicates ints:
public static int[] noDups(int[] myArray)
{
// create an Integer list for adding the unique numbers to
List<Integer> list = new ArrayList<Integer>();
list.add(myArray[0]); // first number in array will always be first
// number in list (loop starts at second number)
for (int i = 1; i < myArray.length; i++)
{
// if number in array after current number in array is different
if (myArray[i] != myArray[i - 1])
list.add(myArray[i]); // add it to the list
}
int[] returnArr = new int[list.size()]; // create the final return array
int count = 0;
for (int x : list) // for every Integer in the list of unique numbers
{
returnArr[count] = list.get(count); // add the list value to the array
count++; // move to the next element in the list and array
}
return returnArr; // return the ordered, unique array
}
Method to find the mode:
public static String findMode(int[] intSet)
{
Arrays.sort(intSet); // needs to be sorted
int[] noDupSet = noDups(intSet);
int[] modePositions = new int[noDupSet.length];
String modes = "modes: no modes."; boolean isMode = false;
int pos = 0;
for (int i = 0; i < intSet.length-1; i++)
{
if (intSet[i] != intSet[i + 1]) {
modePositions[pos]++;
pos++;
}
else {
modePositions[pos]++;
}
}
modePositions[pos]++;
for (int modeNum = 0; modeNum < modePositions.length; modeNum++)
{
if (modePositions[modeNum] > 1 && modePositions[modeNum] != intSet.length)
isMode = true;
}
List<Integer> MODES = new ArrayList<Integer>();
int maxModePos = 0;
if (isMode) {
for (int i = 0; i< modePositions.length;i++)
{
if (modePositions[maxModePos] < modePositions[i]) {
maxModePos = i;
}
}
MODES.add(maxModePos);
for (int i = 0; i < modePositions.length;i++)
{
if (modePositions[i] == modePositions[maxModePos] && i != maxModePos)
MODES.add(i);
}
// THIS LIMITS THERE TO BE ONLY TWO MODES
// TAKE THIS IF STATEMENT OUT IF YOU WANT MORE
if (MODES.size() > 2) {
modes = "modes: no modes.";
}
else {
modes = "mode(s): ";
for (int m : MODES)
{
modes += noDupSet[m] + ", ";
}
}
}
return modes.substring(0,modes.length() - 2);
}
Testing the methods:
public static void main(String args[])
{
int[] set = {4, 4, 5, 4, 3, 3, 3};
int[] set2 = {4, 4, 5, 4, 3, 3};
System.out.println(findMode(set)); // mode(s): 3, 4
System.out.println(findMode(set2)); // mode(s): 4
}
There is a logic error in the last part of constructing the modes array. The original code reads modes[j++] = array[i];. Instead, it should be modes[j++] = i. In other words, we need to add that number to the modes whose occurrence count is equal to the maximum occurrence count

Categories

Resources