Change data in an array with N range steps, for instance, every 2 steps.
int data = new int[8];
result:
[0],[0], [0],[0], [0],[0], [0],[0];
expected:
The first two items should change to 1 and the next two will stay in 0 and so on...
[1],[1] ,[0],[0], [1],[1], [0],[0];
I know the trick with
if(position % 2 == 0)
for changing every 2 items but its changes only the first item.
any idea how to solve it?
int bars =2;
int beats = 4;
int[] pattern = new int[bars * beats];
for (int i = 0; i < pattern.length; i++) {
if(i % bars == 0 ){
pattern[i] = 0;
}else{
pattern[i] = 1;
}
}
Not the most elegant solution but works
static int[] data;
public static void main(String[] args) {
int bars = 7;
int beats = 2;
data = new int[bars * beats];
int minVal;
if(bars > beats){
minVal = Math.min(bars, beats);
}else{
minVal = Math.max(bars, beats);
}
step(minVal, 1);
for (int i = 0; i < data.length; i++) {
if(i % minVal == 0){
System.out.print("|"+ data[i]);
}else{
System.out.print(data[i]);
}
}
}
public static void step(int interval, int value) {
for (int index = 0; index < data.length; index += interval) {
for (int stepIndex = index; stepIndex < index + interval; stepIndex++) {
if (stepIndex > data.length - 1) {
return;
}
data[stepIndex] = value;
}
index += interval;
}
}
static int[] data;
public static void main(String[] args) {
int bars = 7;
int beats = 2;
data = new int[bars * beats];
int minVal;
if(bars > beats){
minVal = Math.min(bars, beats);
}else{
minVal = Math.max(bars, beats);
}
step(minVal, 1);
for (int i = 0; i < data.length; i++) {
if(i % minVal == 0){
System.out.print("|"+ data[i]);
}else{
System.out.print(data[i]);
}
}
}
public static void step(int interval, int value) {
for (int index = 0; index < data.length; index += interval) {
for (int stepIndex = index; stepIndex < index + interval; stepIndex++) {
if (stepIndex > data.length - 1) {
return;
}
data[stepIndex] = value;
}
index += interval;
}
}
Try this
int bars = 2;
int beats = 4;
int[] pattern = new int[bars * beats];
for (int i = 0; i < pattern.length; i++) {
if(i % beats < bars ){
pattern[i] = 1;
} else {
pattern[i] = 0;
}
}
This is 1 of many ways how you can achieve this. We loop through the array, incrementing by the defined interval, which you want to be 2 for example. We create another for-loop starting at the current index and end at current index + interval which will allow us to assign the value, in your case, 1, to those indices. We also check to see if the current index we're looping through is greater than the data length - 1 to ensure no array index out of bonds for non-even array sizes.
public class ChangeArrayNSteps {
public static void main(String[] args) {
ChangeArrayNSteps cans = new ChangeArrayNSteps(8);
cans.step(2, 1);
System.out.println("Data: " + Arrays.toString(cans.data));
}
private final int[] data;
public ChangeArrayNSteps(int size) {
this.data = new int[size];
}
public void step(int interval, int value) {
for (int index = 0; index < data.length; index += interval) {
for (int stepIndex = index; stepIndex < index + interval; stepIndex++) {
if (stepIndex > data.length - 1) {
return;
}
data[stepIndex] = value;
}
index += interval;
}
}
}
Output:
Data: [1, 1, 0, 0, 1, 1, 0, 0]
Related
I am working on sorting algorithms and I am trying to improve mergeSort by locating already sorted subArrays.
public static void mergeSort(int[] array)
{
if(array == null)
{
return;
}
if(array.length > 1)
{
int mid = array.length / 2;
// left
int[] left = new int[mid];
for(int i = 0; i < mid; i++)
{
left[i] = array[i];
}
//right
int[] right = new int[array.length - mid];
for(int i = mid; i < array.length; i++)
{
right[i - mid] = array[i];
}
//recursively calls
mergeSort(left);
mergeSort(right);
int i = 0;
int j = 0;
int k = 0;
// left and right merged
while(i < left.length && j < right.length)
{
if(left[i] < right[j])
{
array[k] = left[i];
i++;
}
else
{
array[k] = right[j];
j++;
}
k++;
}
// left overs
while(i < left.length)
{
array[k] = left[i];
i++;
k++;
}
while(j < right.length)
{
array[k] = right[j];
j++;
k++;
}
}
}
What you are looking for is called natural merge sort. Before you start with sorting the dataset you will do one run to identify all the presorted data. The mergesort itself stays the same.
I found some example code for you at: happycoders
package eu.happycoders.sort.method.mergesort;
import eu.happycoders.sort.method.Counters;
import eu.happycoders.sort.method.SortAlgorithm;
/**
* Natural merge sort implementation for performance tests.
*
* #author Sven Woltmann
*/
public class NaturalMergeSort implements SortAlgorithm {
#Override
public void sort(int[] elements) {
int numElements = elements.length;
int[] tmp = new int[numElements];
int[] starts = new int[numElements + 1];
// Step 1: identify runs
int runCount = 0;
starts[0] = 0;
for (int i = 1; i <= numElements; i++) {
if (i == numElements || elements[i] < elements[i - 1]) {
starts[++runCount] = i;
}
}
// Step 2: merge runs, until only 1 run is left
int[] from = elements;
int[] to = tmp;
while (runCount > 1) {
int newRunCount = 0;
// Merge two runs each
for (int i = 0; i < runCount - 1; i += 2) {
merge(from, to, starts[i], starts[i + 1], starts[i + 2]);
starts[newRunCount++] = starts[i];
}
// Odd number of runs? Copy the last one
if (runCount % 2 == 1) {
int lastStart = starts[runCount - 1];
System.arraycopy(from, lastStart, to, lastStart,
numElements - lastStart);
starts[newRunCount++] = lastStart;
}
// Prepare for next round...
starts[newRunCount] = numElements;
runCount = newRunCount;
// Swap "from" and "to" arrays
int[] help = from;
from = to;
to = help;
}
// If final run is not in "elements", copy it there
if (from != elements) {
System.arraycopy(from, 0, elements, 0, numElements);
}
}
private void merge(int[] source, int[] target, int startLeft,
int startRight, int endRight) {
int leftPos = startLeft;
int rightPos = startRight;
int targetPos = startLeft;
// As long as both arrays contain elements...
while (leftPos < startRight && rightPos < endRight) {
// Which one is smaller?
int leftValue = source[leftPos];
int rightValue = source[rightPos];
if (leftValue <= rightValue) {
target[targetPos++] = leftValue;
leftPos++;
} else {
target[targetPos++] = rightValue;
rightPos++;
}
}
// Copy the rest
while (leftPos < startRight) {
target[targetPos++] = source[leftPos++];
}
while (rightPos < endRight) {
target[targetPos++] = source[rightPos++];
}
}
#Override
public void sort(int[] elements, Counters counters) {
// Not implemented
}
}
I am trying to get an output of [4,6,6,7] with length 4 where arr[i] <= arr[i+1] where it is non-decreasing and it is contiguous. I know what i have to do but i dont know how to do it. my code prints out [3,4,6,6,7]. I am just having trouble on the contiguous part, any help? im not allowed to use extra arrays.
public static void ascentLength(int arr[], int size) {
int length = 0;
int index = 0;
int count = 1;
for (int i = 0; i < size-1; i++) {
index = i;
if (arr[0] <= arr[i+1] && count >0) {
System.out.println(arr[i]+ " index:" + index);
length++;
count++;
}
if (arr[0] >= arr[i+1]) {
}
}
System.out.println("length: " + length);
}
/* Driver program to test above function */
public static void main(String[] args) {
int arr[] = {5, 3, 6, 4, 6, 6, 7, 5};
int n = arr.length;
ascentLength(arr, n);
}
Here is my solution, it would be easier, if you could work with List, but this works for arrays:
public static void ascentLength(int arr[], int size) {
if(size == 1) System.out.println("length: 1");
// variables keeping longest values
int longestStartingIndex = 0;
int longestLength = 1;
// variables keeping current values
int currentStartingIndex = 0;
int currentCount = 1;
for (int i = 1; i < size; i++) {
if (arr[i-1] <= arr[i]) {
currentCount++;
} else {
// check if current count is the longest
if(currentCount > longestLength) {
longestLength = currentCount;
longestStartingIndex = currentStartingIndex;
}
currentStartingIndex = i;
currentCount = 1;
}
}
if(currentCount > longestLength) {
longestLength = currentCount;
longestStartingIndex = currentStartingIndex;
}
}
My task: The input is a one-dimensional array. It is necessary to find the range of maximum width, the elements of which are positive (greater than 0).
As a response, there should be an array of 2 elements, where:
- Element number 0 - the index element of the left border of the segment;
- Element №1 - the index of the element of the right border of the segment.
If there are several such segments, return the RIGHT. If there is no such segment in the array (all numbers are negative), return an empty array.
I don't understand what i do wrong. There's my code:
public class ArrayUtils {
public static int[] lookFor(int[] array) {
int[] result = new int[2];
int firstIndex = 0;
int lastIndex = 0;
int sequenceLength = 0;
int currentSequenceLength = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] > 0) {
if ( currentSequenceLength == 0 ) {
firstIndex = i;
}
currentSequenceLength += 1;
lastIndex = i;
} else {
if (currentSequenceLength > sequenceLength) {
sequenceLength = currentSequenceLength;
result[0] = firstIndex;
result[1] = lastIndex;
}
currentSequenceLength = 0;
}
}
if (sequenceLength == 0) {
return new int[0];
}
return result;
}
}
I see two issues:
if there are several such segments, return the RIGHT - this means you should replace the previous longest sequence with the current one even if they have the same length. i.e. if (currentSequenceLength > sequenceLength) should be if (currentSequenceLength >= sequenceLength).
You ignore any sequence that ends at the last index of the array. You should handle it after the loop by adding:
if (currentSequenceLength >= sequenceLength) {
sequenceLength = currentSequenceLength;
result[0] = firstIndex;
result[1] = lastIndex;
}
To summarize, your method should look like this:
public static int[] lookFor(int[] array) {
int[] result = new int[2];
int firstIndex = 0;
int lastIndex = 0;
int sequenceLength = 0;
int currentSequenceLength = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] > 0) {
if ( currentSequenceLength == 0 ) {
firstIndex = i;
}
currentSequenceLength += 1;
lastIndex = i;
} else {
if (currentSequenceLength >= sequenceLength) {
sequenceLength = currentSequenceLength;
result[0] = firstIndex;
result[1] = lastIndex;
}
currentSequenceLength = 0;
}
}
if (currentSequenceLength >= sequenceLength) {
sequenceLength = currentSequenceLength;
result[0] = firstIndex;
result[1] = lastIndex;
}
if (sequenceLength == 0) {
return new int[0];
}
return result;
}
Check if there exists a Palindrome Number in the list.
If found return its size, else return -1.
public class Program{
public static boolean palindrome(String list){
String reversedString = "";
for (int i = list.length() -1; i >=0; i--){
reveresedString += list.charAt(i)
}
return list.equals(revereseString);
}
}
sample input: [3,5,2,6,3,6,2,1]
palindrome number found: [2,6,3,6,2]
sample output: 5
Here is a pseudo code.
output = -1;
for (i = 0; i < list.length; i++){
num = list[i];
indices[] = \\ get all the indices which the "num" value appears, only include those indices that are greater than "i"
for (j = 0; j < indices.length; j++){
flag = true;
k = i;
for (l = indices[j]; l >= k; l--, k++){
if (list[k] != list[l]) {
flag = false;
break;
}
}
if (flag){
length = (indices[j] - i) + 1;
if (length != 1 && length > output) { // checking of length != 1 will exclude those palindromes of length 2
output = length;
}
}
}
}
return output;
Here is the full code.
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
int[] list = { 3, 5, 2, 2, 6, 3, 6, 3, 6, 3, 6, 2, 2, 1 };
System.out.print(palindrome(list));
}
public static int palindrome(int[] list) {
int output = -1;
for (int i = 0; i < list.length; i++) {
int num = list[i];
ArrayList<Integer> indices = getIndices(list, i, num);
for (int j = 0; j < indices.size(); j++) {
boolean flag = true;
int k = i;
for (int l = indices.get(j); l >= k; l--, k++) {
if (list[k] != list[l]) {
flag = false;
break;
}
}
if (flag) {
int length = (indices.get(j) - i) + 1;
if (length != 1 && length > output) {
output = length;
}
}
}
}
return output;
}
public static ArrayList<Integer> getIndices(int[] list, int start, int num) {
ArrayList<Integer> result = new ArrayList<Integer>();
for (int i = start + 1; i < list.length; i++) {
if (list[i] == num) {
result.add(i);
}
}
return result;
}
}
I'm trying to execute this so that it prints out the longest sequence of the same number. The error I get is that it's telling me that a class or enum is expected. Here's my code:
public class D4 {
private static int getLongestRun(int[] array) {
int count = 1;
int max = 1;
for (int i = 1; i < array.length; i++) {
if (array[i] == array[i - 1]) {
count++;
}
else {
count = 1;
}
if (count > max) {
max = count;
}
}
}
public static void main(String[] args) {
int[] array = new int[]{5, 6, 6, 45, 2, 2, 2};
System.out.println(getLongestRun(array));
}
}
This belongs as a comment, but I will give you full code so that it is clear. Just return max at the end of your getLongestRun() method:
private static int getLongestRun(int[] array) {
int count = 1;
int max = 1;
for (int i = 1; i < array.length; i++) {
if (array[i] == array[i - 1]) {
count++;
}
else {
count = 1;
}
if (count > max) {
max = count;
}
}
// you forgot to return the length of the longest sequence to the caller
return max;
}
function getLongestRun() is missing return max; statement.