I am working on a Merge-sort algorithm, and I am currently trying to test if it works.
It should be controlled through stdin with the input format:
array length
element values (separated by " ")
However, when typing in:
3
17 10 3
Nothing happens, and hitting enter, just get me to the next line in the console.
I get no error message (unless I type in wrong input), and so I have a hard time figuring out why the script is not prompted to run with the input given.
(Code is copied below)
package merge;
import java.io.*;
import java.util.*;
public class MergeSort
{
// This method takes two sorted arrays of integers as input parameters
// and it should return one sorted array of integers.
public int[] merge(int[] A1, int[] A2) {
int[] C = new int[A1.length + A2.length];
int i = 0, j = 0, k = 0;
while (i < A1.length && j < A2.length)
C[k++] = A1[i] < A2[j] ? A1[i++] : A2[j++];
while (i < A1.length)
C[k++] = A1[i++];
while (j < A2.length)
C[k++] = A2[j++];
return C;
}
// This method takes an array of integers as input parameter,
// and it should then return the integers sorted
// in ascending order using the MergeSort algorithm.
private int[] sort(int[] numbers) {
//pointers
int i = 0, j = 0, k = 0;
// reference values
int half = numbers.length / 2;
int[] sorted = new int[numbers.length];
if (numbers.length <= 1){
return numbers;
}
//left part of 'numbers'
int[] left = new int[half];
int[] right;
//right part of 'numbers'
if (numbers.length % 2 != 0){
right = new int[half+1];
j = half + 1;
}
else{
right = new int[half];
j = half;
}
//fills out left half of array with values from input array
while (i < half)
left[i] = numbers[i];
i++;
//fills out right half of array with values from input array
while (j < numbers.length)
right[j] = numbers[k];
j++; k++;
left = sort(left);
right = sort(right);
merge(left,right);
return sorted;
}
// ##################################################
// # Stdin part. #
// ##################################################
public static void main(String[] args) throws IOException {
new MergeSort().run();
}
private void run() throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int[] numbers = readIntArray(in);
numbers = sort(numbers);
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + " ");
}
}
private int[] readIntArray(BufferedReader in) throws IOException {
int length = Integer.parseInt(in.readLine());
int[] array = new int[length];
StringTokenizer st = new StringTokenizer(in.readLine());
for (int i = 0; i < length; i++) {
array[i] = Integer.parseInt(st.nextToken());
}
return array;
}
}
You call readLine() two times, resulting in an attempt to read two lines on the standard input.
Related
Problem : You have L, a list containing some digits (0 to 9). Write a function solution(L) which finds the largest number that can be made from some or all of these digits and is divisible by 3. If it is not possible to make such a number, return 0 as the solution. L will contain anywhere from 1 to 9 digits. The same digit may appear multiple times in the list, but each element in the list may only be used once.
Test Cases :
Input:
Solution.solution({3, 1, 4, 1})
Output: 4311
Input:
Solution.solution({3, 1, 4, 1, 5, 9})
Output: 94311
My Program :
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
public class Solution {
static ArrayList<Integer> al = new ArrayList<Integer>();
static ArrayList<Integer> largest = new ArrayList<Integer>();
static int o = 1;
static int po = 0;
static void combinations(String[] digits, String[] data, int start, int end, int index, int r)
{
if (index == r)
{
String temp = "0";
for (int j = 0; j < r; j++)
{
temp = temp + data[j];
// System.out.print(data[j]);
}
Integer d = Integer.parseInt(temp);
al.add(d);
// System.out.println(al);
}
for (int i = start; i <= end && ((end - i + 1) >= (r - index)); i++)
{
data[index] = digits[i];
combinations(digits, data, i + 1, end, index + 1, r);
}
}
static void printCombinations(String[] sequence, int N)
{
String[] data = new String[N];
for (int r = 0; r < sequence.length; r++)
combinations(sequence, data, 0, N - 1, 0, r);
}
static String[] convert(int[] x)
{
String c[] = new String[x.length];
for(int i=0; i < x.length; i++)
{
Integer k = x[i];
if(k==0)
{
o = o * 10;
continue;
}
c[i] = k.toString();
}
// System.out.println(o);
c = Arrays.stream(c).filter(s -> (s != null && s.length() > 0)).toArray(String[]::new);
po = c.length;
// System.out.println("Come"+ Arrays.asList(c));
return c;
}
public static int solution(int[] l) {
if(l.length==0)
return 0;
if(IntStream.of(l).sum()%3==0)
{
String x = "";
Arrays.sort(l);
for (int i = l.length - 1; i >= 0; i--) {
x = x + l[i];
}
return Integer.parseInt(x);
}
printCombinations(convert(l),po);
al.sort(Comparator.reverseOrder());
al.remove(al.size()-1);
al.removeIf( num -> num%3!=0);
if(al.isEmpty())
return 0;
for(int i=0; i< al.size(); i++)
{
Integer n = al.get(i);
printMaxNum(n);
}
// System.out.println(al);
// System.out.println(largest);
return largest.get(0)*o;
}
static void printMaxNum(int num)
{
// hashed array to store count of digits
int count[] = new int[10];
// Converting given number to string
String str = Integer.toString(num);
// Updating the count array
for(int i=0; i < str.length(); i++)
count[str.charAt(i)-'0']++;
// result is to store the final number
int result = 0, multiplier = 1;
// Traversing the count array
// to calculate the maximum number
for (int i = 0; i <= 9; i++)
{
while (count[i] > 0)
{
result = result + (i * multiplier);
count[i]--;
multiplier = multiplier * 10;
}
}
// return the result
largest.add(result);
}
public static void main(String[] args) {
System.out.println(solution(new int[]{9,8,2,3}));
}
}
My Code passes both given test cases and 3 other hidden test cases except one. I tried all possible input combinations but couldn't get to the exact failure. The return type by default is given as int and therefore they would not pass values which give output that does not fit in int. Any other scenario where my code fails?
I have a problem with an exercise trying to solve it. Here is the task:
Write a program that moves that rotates a list several times (the first element becomes last).
list = 1,2,3,4,5 and N = 2 -> result = 3,4,5,1,2
Note that N could be larger than the length of the list, in which case you will rotate the list several times.
list = 1,2,3,4,5 and N = 6 -> result = 2,3,4,5,1
Input
On the first line you will receive the list of numbers.
On the second line you will receive N
Output
On the only line of output, print the numbers separated by a space.
Here are the TEST:
TEST 1:
Input 5,3,2,1 2
Output 2,1,5,3
TEST 2:
Input 2,1,3,4 5
Output 1,3,4,2
Here is my code so far:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] elements = input.split(",");
int[] array = new int[elements.length];
for (int i = 0; i < elements.length; i++) {
array[i] = Integer.parseInt(elements[i]);
}
int a = scanner.nextInt();
int[] rotated = new int[elements.length];
for (int x = 0; x <= array.length - 1; x++) {
rotated[(x + a) % array.length] = array[x];
}
for (int i = 0; i < rotated.length; i++) {
if (i > 0) {
System.out.print(",");
}
System.out.print(rotated[i]);
}
}
}
The first TEST is passed. But the second test is not passed and my program gives me wrong output: 4,2,1,3 instead of the right one: 1,3,4,2.
I cant figure it out where is the problem.
Thank you in advance for any help.
Your logic can be simplified to :
public static void shiftLeft(int shiftBy, int arr[]) {
for (int j = 0; j < shiftBy; j++) {
int a = arr[0]; // storing the first index
int i;
for (i = 0; i < arr.length - 1; i++) { // shifting the array left
arr[i] = arr[i + 1];
}
arr[i] = a; // placing first index at the end
}
}
Now call it :
public static void main(String[] args) {
// Fetch all data from user as you have done
int arr[] = { 1, 2, 3, 4, 5 };
shiftLeft(n % arr.length, arr);
// print out the array
}
Notice that if the number n is greater than the length of the array, you don't have to actually shift it that many times. Instead you just need to shift it n % arr.length times.
In this code I am having some problem as I have marked using a loop which is printing some values. I am storing them in an array as mentioned and am trying to print the values in another function. But even after using the global array the value of the array is changing.
I am not able to figure out the problem. Please help me out.
import java.io.*;
import java.util.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
// Java program to print all permutations of a
// given string.
public class test3
{
static int[] val = new int[100] ; //array declaration as global
public static void main(String[] args)
{
System.out.println("An incremented value");
for(int i=2;i<=2;i++) {
String p="";
for(int j=0;j<=i;j++) {
for(int m=0;m<j;m++) {
p=p+"&";
}
for(int m=0;m<i-j;m++) {
p=p+"|";
}
printAllPermutations(p);
p="";
}
}
System.out.println();
for(int xy=0;xy<32;xy++)
System.out.print("["+xy+"]"+"="+val[xy]+" "); //trying to print the array
}
static void print(char[] temp) {
String a="";
System.out.println();
for (int i = 0; i < temp.length; i++)
{ System.out.print(temp[i]);
a=a+temp[i];}
System.out.print(" "+"opr:"+temp.length+" ");
final int N = temp.length+1;
/*===================CODE PROBLEM PART START=======================*/
for (int i = 0; i < (1 << N); i++) {
// System.out.println(zeroPad(Integer.toBinaryString(i), N));
String b=zeroPad(Integer.toBinaryString(i), N)+"";
// System.out.println("a: "+a+" b:"+b);
char[] arrayA = b.toCharArray();
char[] arrayB = a.toCharArray();
StringBuilder sb = new StringBuilder();
int ii = 0;
while( ii < arrayA.length && ii < arrayB.length){
sb.append(arrayA[ii]).append(arrayB[ii]);
++ii;
}
for(int j = ii; j < arrayA.length; ++j){
sb.append(arrayA[j]);
}
for(int j = ii; j < arrayB.length; ++j){
sb.append(arrayB[j]);
}
//System.out.println(sb.toString());
try {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine se = sem.getEngineByName("JavaScript");
String myExpression = sb.toString();
// System.out.print(se.eval(myExpression));
val[i]=(int)(se.eval(myExpression)); //inserting array value
System.out.print(val[i]); //NEED TO HAVE THESE VALUES IN THE 1-D ARRAY
// System.out.print(val[i]);
} catch (ScriptException e) {
System.out.println("Invalid Expression");
e.printStackTrace();}
}
/*===================CODE PROBLEM PART END========================*/
//
}
//unchangable = rest of the function
static int factorial(int n) {
int f = 1;
for (int i = 1; i <= n; i++)
f = f * i;
return f;
}
static int calculateTotal(char[] temp, int n) {
int f = factorial(n);
// Building HashMap to store frequencies of
// all characters.
HashMap<Character, Integer> hm =
new HashMap<Character, Integer>();
for (int i = 0; i < temp.length; i++) {
if (hm.containsKey(temp[i]))
hm.put(temp[i], hm.get(temp[i]) + 1);
else
hm.put(temp[i], 1);
}
// Traversing hashmap and finding duplicate elements.
for (Map.Entry e : hm.entrySet()) {
Integer x = (Integer)e.getValue();
if (x > 1) {
int temp5 = factorial(x);
f = f / temp5;
}
}
return f;
}
static void nextPermutation(char[] temp) {
// Start traversing from the end and
// find position 'i-1' of the first character
// which is greater than its successor.
int i;
for (i = temp.length - 1; i > 0; i--)
if (temp[i] > temp[i - 1])
break;
// Finding smallest character after 'i-1' and
// greater than temp[i-1]
int min = i;
int j, x = temp[i - 1];
for (j = i + 1; j < temp.length; j++)
if ((temp[j] < temp[min]) && (temp[j] > x))
min = j;
// Swapping the above found characters.
char temp_to_swap;
temp_to_swap = temp[i - 1];
temp[i - 1] = temp[min];
temp[min] = temp_to_swap;
// Sort all digits from position next to 'i-1'
// to end of the string.
Arrays.sort(temp, i, temp.length);
// Print the String
print(temp);
}
static void printAllPermutations(String s) {
// Sorting String
char temp[] = s.toCharArray();
Arrays.sort(temp);
// Print first permutation
print(temp);
// Finding the total permutations
int total = calculateTotal(temp, temp.length);
for (int i = 1; i < total; i++)
nextPermutation(temp);
}
static String zero(int L) {
return (L <= 0 ? "" : String.format("%0" + L + "d", 0));
}
static String zeroPad(String s, int L) {
return zero(L - s.length()) + s;
}
}
The output that I am getting is
An incremented value
|| opr:2 01111111 //WANT TO STORE THESE 32 VALUES IN 1 D ARRAY
&| opr:2 01010111 // AND PRINT THEM OUT
|& opr:2 00011111
&& opr:2 00000001
[0]=0 [1]=0 [2]=0 [3]=0 [4]=0 [5]=0 [6]=0 [7]=1 [8]=0 [9]=0 [10]=0 [11]=0 [12]=0 [13]=0 [14]=0 [15]=0 [16]=0 [17]=0 [18]=0 [19]=0 [20]=0 [21]=0 [22]=0 [23]=0 [24]=0 [25]=0 [26]=0 [27]=0 [28]=0 [29]=0 [30]=0 [31]=0
what I need to do is to store those 32 values in 1 D array for further operation but while doing it all the array values displays 0 only except [7]. I dont know whats going on here.
Reference types are not bound to local scopes, just because your array is static to the class it does not mean that changing the values in one function will not change the values in the actual array. The reference to your array as a parameter will be a copy, but the reference is still "pointing" on an actual object, which is not a copy bound to your local scope.
If you want to save two different states of the array, you will have to save them yourself.
I am currently creating a program where the user inputs an array of integers. The program has to find the longest increasing sequence of consecutive elements. So if the user enters "3,2,1,2,4,6,7,8,1,2" the program will output "1,2,4,5,6,7,8". However, I keep running into 2 errors.
The first error is that when xs = 1000,97777,487,8274,972837. The program will output "1000,97777" instead of "487,8274,972837". Logically this is wrong since the first output is not the "LONGEST" increasing sequence of consecutive element.
The second error is that when xs = 2,7. It seems to output an empty array instead of "2,7". I'm assuming it's because there aren't enough elements perhaps?
static int[] increasing(int[] xs){
ArrayList<Integer> current_array = new ArrayList<Integer>();
ArrayList<Integer> list = new ArrayList<Integer>();
int c_counter = 0;
for (int i = 0; i<(xs.length); i++){
if (i==0){
if (xs[i+1] > xs[i]){
current_array.add(xs[i]);
c_counter++; //keeps track of how many elements have been added
}
}
else if ((xs[i] > xs[i-1])){
if (c_counter==0){
current_array.add(xs[i-1]); //makes sure the smaller number gets added too
current_array.add(xs[i]);
c_counter = c_counter + 2;
} else{
current_array.add(xs[i]);
c_counter++;
}
} else {
if (current_array.size()>list.size()){ //compares sizes to find the longest sequence
list.clear();
for (int k=0; k<(current_array.size()); k++){
if (current_array.get(k) != 0){ //removes any null values
list.add(current_array.get(k));
}
}
current_array.clear(); //clears it to restart and find any longer sequences
c_counter = 0;
}
}
}
int[] out_array = list.stream().mapToInt(i->i).toArray(); //converts from arraylist to int[] as that's the format it must output
out_array = list.stream().filter(i->i != null).mapToInt(i->i).toArray();
return out_array;
}
public static int[] increasing(int[] xs){
int start = 0;
int end = 0;
int temp = 0;
for (int i = 0; i < xs.length; i++) {
if(i==0 || xs[i]<xs[i-1]){
temp = i;
}
else if(i-temp > end-start){
start = temp;
end = i;
}
}
return Arrays.copyOfRange(xs, start, end+1);
}
It takes too long time to understand your code. Try this out:
List<Integer> test = new ArrayList<Integer>();
test.add(3);
test.add(2);
test.add(1);
test.add(2);
// test.add(4);
// test.add(6);
// test.add(7);
// test.add(8);
test.add(1);
test.add(2);
test.add(1000);
test.add(97777);
test.add(487);
test.add(8274);
test.add(972837);
List<Integer> output = new ArrayList<Integer>();
List<Integer> temp = new ArrayList<Integer>();
for(int i = 0; i < test.size(); i++) {
int current = test.get(i);
int next = Integer.MIN_VALUE;
if(i + 1 < test.size()) next = test.get(i + 1);
if(current > next) {
if(output.size() <= temp.size()) {
temp.add(current);
output = new ArrayList<Integer>(temp);
}
temp.clear();
} else {
temp.add(current);
}
}
output.forEach(i -> System.out.print(i + ", "));
If you want the longest decreasing output, change int next = Integer.MAX_VALUE; and if(current > next) to if(current < next)
Below is my code for the merge sort algorithm in java. It takes a string and an int array because I need to sort a string array with the int array. This implementation also counts inversions. My issue is that it's counting inversions fine, but when I print out the arrays themselves, it hasn't been changed at all.
the main method is me testing a 6 long array and printing out the inversions and arrays. when i run this test i get the following printed out.
4
1, 3, 4, 6, 2, 5
1, 3, 4, 6, 2, 5
public class Test {
private static int[] intSorted;
private static String[] stringSorted;
public static void main(String[] args) {
//Creates new string to sort
String[] string3 = {"1","3","4","6","2","5"};
//Creates new int to sort
int[] intt3 = {1,3,4,6,2,5};
//Calls sortAndCount on int and prints the number of inversions
System.out.println(sortAndCount(intt3, string3));
//Turns the int array into a string to print
StringBuilder intBuild = new StringBuilder();
for(int i = 0; i < intSorted.length; i++){
if(i+1 == intSorted.length){
intBuild.append(intSorted[i]);
}
else{
intBuild.append(intSorted[i] + ", ");
}
}
//Turns the string array into a string to print
StringBuilder stringBuild = new StringBuilder();
for(int i = 0; i < stringSorted.length; i++){
if(i+1 == stringSorted.length){
stringBuild.append(stringSorted[i]);
}
else{
stringBuild.append(stringSorted[i] + ", ");
}
}
System.out.println(intBuild);
System.out.println(stringBuild);
}
private static int sortAndCount(int intToSort[], String stringToSort[]){
int inversionsLeft;
int inversionsRight;
int inversionsMerged;
if(intToSort.length == 1){
return 0;
}
int m = intToSort.length/2;
int[] intLeft = new int[m];
String[] stringLeft = new String[m];
int[] intRight = new int[intToSort.length-m];
String[] stringRight = new String[intToSort.length-m];
for (int i=0; i < m; i++){
intLeft[i] = intToSort[i];
stringLeft[i] = stringToSort[i];
}
for (int i = 0;i < intRight.length; i++){
intRight[i] = intToSort[m+i];
stringRight[i] = stringToSort[m+i];
}
inversionsLeft = sortAndCount(intLeft, stringLeft);
inversionsRight = sortAndCount(intRight, stringRight);
intSorted = new int[intToSort.length];
stringSorted = new String[stringToSort.length];
inversionsMerged = mergeAndCount(intLeft, intRight, stringLeft, stringRight);
return(inversionsLeft + inversionsRight + inversionsMerged);
}
private static int mergeAndCount(int[] intLeft, int[] intRight, String[] stringLeft, String[] stringRight){
int count = 0;
int i = 0;
int j = 0;
int k = 0;
while(i < intLeft.length && j < intRight.length){
if(intLeft[i] < intRight[j]){
intSorted[k] = intLeft[i];
stringSorted[k] = stringLeft[i];
i++;
}
else{
intSorted[k] = intRight[j];
stringSorted[k] = stringRight[j];
count += intLeft.length - i + 1;
j++;
}
k++;
}
while (i < intLeft.length)
{
intSorted[k] = intLeft[i];
stringSorted[k] = stringLeft[i];
k++;
i++;
}
while (j < intRight.length)
{
intSorted[k] = intRight[j];
stringSorted[k] = stringRight[j];
j++;
k++;
}
return count;
}
I think the problem is here (comments added by me):
// Create some arrays into which we write the result of merging the
// arrays intLeft, intRight, stringLeft, stringRight.
intSorted = new int[intToSort.length];
stringSorted = new String[stringToSort.length];
// Do the merging into intSorted and stringSorted.
inversionsMerged = mergeAndCount(intLeft, intRight, stringLeft, stringRight);
// Oops... we haven't updated intToSort and stringToSort!
// We need to copy the sorted values from intSorted and stringSorted
// back into intToSort and stringToSort before we return.
return(inversionsLeft + inversionsRight + inversionsMerged);
I'll leave it up to you to fill in the gap.
I took your code, filled in the gap myself, and ran it. It seemed to work; this was the output I got:
7
1, 2, 3, 4, 5, 6
1, 2, 3, 4, 5, 6
Good luck!
Well the reason that your arrays don't get sorted is that your recursive algorithm keeps recreating the intSorted [] and stringSorted [] with each invocation.
Also your recursive method just returns an int (the number of inversions performed). In order of the recursive approach to work each sortAndCount must return it's piece of the array sorted. This makes it difficult to attempt to sort two different arrays in the same algorithm.
I have made a few minor tweaks to your code and now it sorts the int[] correctly.
If you want to count inversions at the same time that you sort, I would suggest adding a passByReference to a Counter object that does nothing but count inversions (like a visitor pattern).
Here is my code:
public class Test {
private static int[] intSorted;
public static void main(String[] args) {
//Creates new string to sort
//Creates new int to sort
int[] intt3 = {1,3,4,6,2,5};
//Calls sortAndCount on int and prints the number of inversions
System.out.println(sortAndCount(intt3));
//Turns the int array into a string to print
StringBuilder intBuild = new StringBuilder();
for(int i = 0; i < intSorted.length; i++){
if(i+1 == intSorted.length){
intBuild.append(intSorted[i]);
}
else{
intBuild.append(intSorted[i] + ", ");
}
}
//Turns the string array into a string to print
System.out.println(intBuild);
}
private static int[] sortAndCount(int intToSort[]){
int inversionsLeft;
int inversionsRight;
int inversionsMerged;
if(intToSort.length == 1){
return intToSort;
}
int m = intToSort.length/2;
int[] intLeft = new int[m];
String[] stringLeft = new String[m];
int[] intRight = new int[intToSort.length-m];
String[] stringRight = new String[intToSort.length-m];
for (int i=0; i < m; i++){
intLeft[i] = intToSort[i];
}
for (int i = 0;i < intRight.length; i++){
intRight[i] = intToSort[m+i];
}
intLeft = sortAndCount(intLeft);
intRight = sortAndCount(intRight);
intSorted = new int[intToSort.length];
intSorted = mergeAndCount(intLeft, intRight);
return intSorted;
}
private static int[] mergeAndCount(int[] intLeft, int[] intRight){
int count = 0;
int i = 0;
int j = 0;
int k = 0;
while(i < intLeft.length && j < intRight.length){
if(intLeft[i] < intRight[j]){
intSorted[k] = intLeft[i];
i++;
}
else{
intSorted[k] = intRight[j];
count += intLeft.length - i + 1;
j++;
}
k++;
}
while (i < intLeft.length)
{
intSorted[k] = intLeft[i];
k++;
i++;
}
while (j < intRight.length)
{
intSorted[k] = intRight[j];
j++;
k++;
}
return intSorted;
}
}