I'm trying to convert a PHP-Script to Java.
But somehow I don't get it working..
<?php
$karten = array(12, 10, 8, 14, 9, 11, 13);
for ($i = 1; $i <= count($karten); $i++) {
print_r($karten);
echo '<br>';
if ($karten[$i] > $Karten[$i - 1]) {
for ($a = 0; $a < count($karten); $a++) {
if ($karten[$a] > $karten[$i]) {
//Karten vorne dran setzen
$karte = $karten[$i];
unset($karten[$i]);
array_splice($karten, $a, 0, array($karte));
break;
}
}
}
}
?>
We have to use Eclipse in School, so not the latest version of Java
Here is what i got so far:
Main.java:
import java.util.Arrays;
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
KartenAlgo ka = new KartenAlgo();
int[] stapel = new int[7];
int[] sStapel = new int[stapel.length];
stapel[0] = 12;
stapel[1] = 10;
stapel[2] = 8;
stapel[3] = 14;
stapel[4] = 9;
stapel[5] = 11;
stapel[6] = 13;
sStapel = ka.sortiereKarten(stapel);
}
}
algorithm.java:
import java.util.*;
public class KartenAlgo {
public int[] sortiereKarten(int[] array) {
int[] returnArr = new int[array.length];
for (int i = 1; i < array.length; i++) {
if (array[i] > array[i - 1]) {
for (int a = 0; a < array.length; a++) {
if (array[a] > array[i]) {
int karte = array[i];
array = this.unset(array, i);
array = this.array_insert(array, a, karte);
break;
}
}
}
}
return returnArr;
}
private int[] unset(int[] array, int index) {
int[] returnArr = new int[array.length];
for (int i = 0; i < array.length; i++) {
if (i != index) {
if (i < index) {
returnArr[i] = array[i];
} else if (i == array.length - 1) {
returnArr[i] = -1;
} else {
returnArr[i] = array[i - 1];
}
}
}
return returnArr;
}
private int[] array_insert(int[] array, int pos, int insert) {
int[] returnArr = new int[array.length];
for (int i = 0; i < returnArr.length; i++) {
if (i < pos) {
returnArr[i] = array[i];
} else if (i == pos) {
returnArr[i] = insert;
} else {
returnArr[i] = array[i - 1];
}
}
System.out.println(Arrays.toString(array));
return returnArr;
}
}
I tried to rebuild PHP's unset and a simple variant of array_splice in Java, but I dont get it working.
In PHP unset work like this:
(unset remove/delete elemen in array and you get shorter array)
private static int[] unset(int[] arrIn, int index)
{
int i;
// new array is shorter
int[] arrOut = new int[arrIn.length-1];
// copy element "before" arrIn[index]
for(i = 0; i < index ; i++) {
arrOut[i] = arrIn[i];
}
// copy element "after" arrIn[index]
for(i = index; i < arrOut.length ; i++) {
arrOut[i] = arrIn[i+1];
}
return arrOut;
}
array_insert inserts elemen into array and you get longer array.
private static int[] array_insert(int[] arrIn, int pos, int value)
{
int i;
// new array is longer
int[] arrOut = new int[arrIn.length+1];
// copy element "before" arrIn[pos]
for(i = 0; i < pos ; i++) {
arrOut[i] = arrIn[i];
}
// put element in arrOut[pos]
arrOut[pos] = value;
// copy element "from" arrIn[pos] "to" end of arrIn[]
for(i = pos; i < arrIn.length ; i++) {
arrOut[i+1] = arrIn[i];
}
return arrOut;
}
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
}
}
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;
}
}
Write a method that takes an array of integers and returns the length of its longest subarray with distinct integers.
e.g. with [1,2,3,4,2,3] it should return 4.
I used a HashSet to keep track of all elements from index i to index j and kept a counter while traversing through the list. Linear runtime and space:
public static int longestSubarray(int[] arr) {
int i = 0, j = 1, max = 0, currLength = 1;
max = Math.max(max, currLength);
HashSet<Integer> set = new HashSet<Integer>();
set.add(arr[0]);
while (i < arr.length - 1 && j < arr.length) {
if (!set.contains(arr[j])) {
currLength++;
set.add(arr[j++]);
}
else {
set.remove(arr[i++]);
currLength--;
}
}
return Math.max(currLength, max);
}
public int[] getLargestSubArray(int[] array) {
int length = array.length;
Set<Integer> set = new HashSet<>();
int longest = 0;
int start = 0;
int longestCurrent = 0;
int startCurrent = 0;
int j = 0;
while (j < length) {
if (!set.contains(array[j])) {
set.add(array[j]);
longestCurrent++;
if (longestCurrent > longest) {
longest = longestCurrent;
start = startCurrent;
}
j++;
} else {
while (startCurrent < j) {
longestCurrent--;
if (array[startCurrent++] == (array[j])) {
break;
}
}
set.remove(array[j]);
}
}
int[] longestSubSequence = new int[longest];
System.arraycopy(array, start, longestSubSequence, 0, longest);
return longestSubSequence;
}
public static int sizeOfLongestDistinctSubArrayO1(int[] arr) {
int max = 0;
Map<Integer, Integer> counts = new HashMap<>();
int cur = 0;
int prev = 0;
for (int i = 0, len = arr.length; i < len; i++) {
if (counts.containsKey(arr[i])) {
int j = counts.get(arr[i]);
max = Math.max(max, cur);
prev = Math.max(j, prev);
cur = i - prev;
counts.put(arr[i], i);
} else {
cur++;
counts.put(arr[i], i);
}
}
return Math.max(max, cur);
}
python version
#!/usr/bin/env python3
input = [1,2,3,4,2,3,4,5,6,7,3,4]
tmp_list = []
max = 0
for i in input:
if i not in tmp_list:
tmp_list.append(i)
else:
max = len(tmp_list) if len(tmp_list) > max else max
tmp_list = [i]
print (max if max >= len(tmp_list) else len(tmp_list))
public int lengthOfLongestSubarray(int[] arr) {
int max = 0; // Maximum length of subarray with unique elements
Map<Integer,Integer> map = new HashMap<>();
// let longest subarray starts at i and ends at j
for(int i = -1,j = 0; j < arr.length;j++) {
if(map.containsKey(arr[j])) {
i = Math.max(i,map.get(arr[j]));
}
max = Math.max(max,j-i);
map.put(arr[j],j);
}
return max;
}
C# Version
Core Logic:
private static int Solve(string s) {
var dict = new Dictionary < string,int > ();
var arr = s.Split(" ", StringSplitOptions.RemoveEmptyEntries);
var start = 0;
var substrLen = 0;
for (var i = 0; i < arr.Length; i++) {
if (dict.ContainsKey(arr[i])) {
substrLen = substrLen < i - start ? i - start: substrLen;
var tempStart = dict[arr[i]] + 1;
for (var j = dict[arr[i]]; j > start; j--) {
dict.Remove(arr[i]);
}
start = tempStart;
dict[arr[i]] = i;
}
else {
dict.Add(arr[i], i);
}
}
return dict.Count;
}
Complete code here
import java.util.*;
class GFG{
static int largest_subarray(int a[], int n)
{
HashSet<Integer> set = new HashSet<Integer>();
int ans = 0;
int counter = 0;
for(int i = 0; i < n; i++)
{
if(set.contains(a[i])){
set.clear();
counter =0;
}
set.add(a[i]);
counter++;
ans = Math.max(ans, counter);
}
// Return final ans
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 2, 4, 4, 5, 6, 7, 8, 3, 4, 5, 3, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4
};
int n = arr.length;
System.out.print(largest_subarray(arr, n));
}
}
I have just written up this code an have been trying for ages to try and find out why it is not printing the sorted list. It is running and there are no bugs, except it just does not print out the sorted list. Can you please help me find whats wrong?
public class Merging {
public static void main(String[] args) {
int[] a = new int[10];
populate(a);
printA(a);
a = merge_sort(a);
printA(a);
}
public static int[] merge_sort(int[] B) {
if (B.length <= 1) {
return B;
}
int midpoint = B.length / 2;
int[] left = new int[midpoint];
int[] right= new int[B.length-midpoint];
int[] result;
for (int i = 0; i < midpoint; i++) {
left[i] = B[i];
}
int x = 0;
for (int j = midpoint; j < B.length; j++) {
if (x < right.length) {
right[x] = B[j];
x++;
}
}
left = merge_sort(left);
right = merge_sort(right);
result = merge(left, right);
return result;
}
public static int[] merge(int[] left, int[] right) {
int lengthResult = left.length + right.length;
int[] result = new int[lengthResult];
int indexL = 0;
int indexR = 0;
int indexRes = 0;
while (indexL < left.length || indexR < right.length) {
if (indexL < left.length && indexR < right.length) {
if (left[indexL] <= right[indexR]) {
result[indexRes] = left[indexL];
indexL++;
indexRes++;
} else {
result[indexRes] = right[indexR];
indexR++;
indexRes++;
}
} else if (indexL < left.length) {
result[indexRes] = left[indexL];
indexL++;
indexRes++;
}
}
return result;
}
public static void printA(int[] B) {
for (int i = 0; i < B.length; i++) {
System.out.print(B[i] + " ");
}
}
public static int[] populate(int[] B) {
for (int i = 0; i < B.length; i++) {
B[i] = (int) (Math.random() * 100);
}
return B;
}
}
imagine the case in your loop, where indexL < left.length == false but indexR < right.length == true, you never increase indexR and the loop will never terminate
I'm trying to make a method that creates a new array containing the index of every occurrence of a target value. I have to use 2 loops for this. The first counts how many times the target occurs. Then create the new array, to hold this many indexes. Then the second loop puts the indexes into the new array.
I've written the code below, but it throws java lang Array Out Of Bound Exception:5, on the line result [ i ] = f [ i ] ;
public class FindAll {
public FindAll() {
int a[] = {7, 8, 9, 9, 8, 7};
print(findAll(a, 7));
print(findAll(a, 2));
}
public void print(int p[]) {
System.out.print("{");
int i;
for (i = 0; i < p.length - 1; ++i) {
System.out.print(p[i] + ", ");
}
System.out.print(p[i]);
System.out.print("}");
}
public int[] findAll(int f[], int target) {
int count = 0;
for (int i = 0; i < f.length; ++i) {
if (f[i] == target) {
count++;
}
}
int result[] = new int[count];
for (int i = 0; i < f.length; ++i) {
if (f[i] == target) {
result[i] = f[i];
}
}
return result;
}
}
Try this
int result[] = new int[count];
int index = 0;
for (int i = 0; i < f.length; i++)
{
if (f[i] == target){
result[index] = f[i];
index++;
}
}
Replace the findAll function with this
public int[] findAll(int f[], int target) {
int count = 0;
for (int i = 0; i < f.length; ++i) {
if (f[i] == target)
count++;
}
if(count == 0) return null;
int result[] = new int[count];
for (int i = 0, curr = 0; i < f.length; ++i) {
if (f[i] == target)
result[curr++] = i;
// Here you have to store the index not the value
}
return result;
}
Add these lines to print method to avoid an exception when the array is null
if(p == null || p.length == 0){
System.out.println("P is null or empty");
return;
}
It will work fine!
The result array you are creating is the size of the number of occurrences of the target, not the size of the original array.
public int[] findAll(int f[], int target)
{
int count = 0;
for (int i = 0; i < f.length; ++i)
{
if (f[i] == target)
count++;
}
int result[] = new int[count]; // This is the size of number of occurrences of target
for (int i = 0; i < f.length; ++i) // 'i' will go up to size of original array
{
if (f[i] == target)
result[i] = f[i]; // You are trying to put the element of the original array in to the same index of your result!?
}
return result;
}
Instead, you need to be adding, for each target element, it's index:
int resultIndex = 0;
for (int i = 0; i < f.length; i++) {
if ( f[i] == target ) {
result[n] = i;
n++;
}
}