Using the Reverse Method/ Arrays- How to Print out the Reverse - java

public static void main(String[] args) {
int[] HwArray = new int[10];
int count = 0;
String separate = "";
for (int i = 0; i < HwArray.length; i++) {
System.out.print(separate);
//Generate random numbers
HwArray[i] = (int) (100 + Math.random() * 100);
System.out.println("HwArray[" + i + "]=" + HwArray[i]);
}
int location = linearSearch(HwArray, 150);
System.out.println("\nLinear Search Result: " + location);
}
// Reverse the order of all elements, then print HwArray.
public static int[] reverse(int[] list) {
int[] result = new int[list.length];
for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
result[j] = list[i];
System.out.println("HwArray[" + i + "]=" + result[j]);
}
return result;
}
public static int linearSearch(int[] list, int key) {
for (int i = 0; i < list.length; i++) {
if (list[i] == key)
return i; //return the index location
}
return -1; //return if number is not found in the index
}
I'm trying to print out the elements in Reverse, but It will only print out the elements. I'm not sure what's wrong.

Please research a little more before asking questions, maybe google "java reverse array". That's what I did, and found that this person asked the same thing. Reversing an Array in Java
The solution is simple:
List<Integer> lst = Arrays.asList(list); //Converts the int "list" into a list.
Collections.reverse(lst); //Reverses the list.
result = list.toArray(lst);

Related

Java set/setElementAt not setting the right value

I need to find all the permutations for a given n(user input) without backtracking.
What i tried is:
import java.util.Scanner;
import java.util.Vector;
class Main {
private static int n;
private static Vector<Vector<Integer>> permutations = new Vector<>();
private static void get_n() {
Scanner user = new Scanner(System.in);
System.out.print("n = ");
n = user.nextInt();
}
private static void display(Vector<Vector<Integer>> permutations) {
for (int i = 0; i < factorial(n) - 1; ++i) {
for (int j = 0; j < n; ++j) {
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
}
System.out.println();
}
}
private static int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}
private static int max(Vector<Integer> permutation) {
int max = permutation.elementAt(0);
for (int i = 1; i < permutation.size(); ++i)
if (permutation.elementAt(i) > max)
max = permutation.elementAt(i);
return max;
}
// CHECKS FOR ELEMENT COUNT AND 0 - (n-1) APPARITION
public static int validate_permutation(Vector<Integer> permutation) {
// GOOD NUMBER OF ELEMENTS
if (max(permutation) != permutation.size() - 1)
return 0;
// PROPER ELEMENTS APPEAR
for (int i = 0; i < permutation.size(); ++i)
if (!permutation.contains(i))
return 0;
return 1;
}
private static Vector<Integer> next_permutation(Vector<Integer> permutation) {
int i;
do {
i = 1;
// INCREMENT LAST ELEMENT
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
// IN A P(n-1) PERMUTATION FOUND n. "OVERFLOW"
while (permutation.elementAt(permutation.size() - i) == permutation.size()) {
// RESET CURRENT POSITION
permutation.set(permutation.size() - i, 0);
// INCREMENT THE NEXT ONE
++i;
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
}
} while (validate_permutation(permutation) == 0);
// OUTPUT
System.out.print("output of next_permutation:\t\t");
for (int j = 0; j < permutation.size(); ++j)
System.out.print(permutation.elementAt(j) + " ");
System.out.println();
return permutation;
}
private static Vector<Vector<Integer>> permutations_of(int n) {
Vector<Vector<Integer>> permutations = new Vector<>();
// INITIALIZE PERMUTATION SET WITH 0
for (int i = 0; i < factorial(n); ++i) {
permutations.addElement(new Vector<>());
for(int j = 0; j < n; ++j)
permutations.elementAt(i).addElement(0);
}
for (int i = 0; i < n; ++i)
permutations.elementAt(0).set(i, i);
for (int i = 1; i < factorial(n); ++i) {
// ADD THE NEXT PERMUTATION TO THE SET
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
System.out.print("values set by permutations_of:\t");
for (int j = 0; j < permutations.elementAt(i).size(); ++j)
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
System.out.println("\n");
}
System.out.print("\nFinal output of permutations_of:\n\n");
display(permutations);
return permutations;
}
public static void main(String[] args) {
get_n();
permutations.addAll(permutations_of(n));
}
}
Now, the problem is obvious when running the code. next_permutation outputs the correct permutations when called, the values are set correctly to the corresponding the vector of permutations, but the end result is a mass copy of the last permutation, which leads me to believe that every time a new permutation is outputted by next_permutation and set into the permutations vector, somehow that permutation is also copied over all of the other permutations. And I can't figure out why for the life of me.
I tried both set, setElementAt, and an implementation where I don't initialize the permutations vector fist, but add the permutations as they are outputted by next_permutation with add() and I hit the exact same problem. Is there some weird way in which Java handles memory? Or what would be the cause of this?
Thank you in advance!
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
This is literally setting the vector at permutations(i) to be the same object as permutations[i-1]. Not the same value - the exact same object. I think this the source of your problems. You instead need to copy the values in the vector.

Divide array into two subarray so that difference between array's sum is minimum?

Input is[4,13,14,15,16]. Output should be [16,15] and [14,13,4].
I can think of the following algorithm where
I sort the array in descending order
Take first two elements in two list
Now add the element in list who sum is minimum
public class TestMinDiff {
public static void main(String[] args) {
Integer[] array = {4,13,14,15,16};
Arrays.sort(array, Collections.reverseOrder());
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new ArrayList<Integer>();
int list1Sum = 0;
int list2Sum = 0;
for(int i: array) {
if(list1Sum<=list2Sum) {
list1Sum = list1Sum + i;
list1.add(i);
} else {
list2Sum = list2Sum + i;
list2.add(i);
}
}
}
}
Output is
List 1 is [16,13,4].
List 2 is [15,14].
Looks like my algorithm needs to be improved further. To me it looks like it is an NP problem. But I am not able to think of an algorithm here which gives me the output
[16,15] and [14,13,4].
This is the knapsack problem. It is NP-complete in the general case, but for small integers it can be solved effectively.
Let's take your example array of [4,13,14,15,16]. The total is 62. We rephrase this into a knapsack problem where we have this set of items, but the knapsack capacity is 62÷2 = 31. If we select items that total to the largest number no greater than 31, then this solves your problem of minimizing the difference between the two divided lists.
There is a standard algorithm for solving the knapsack problem, which I won't explain here.
I understand your question this: you want divide array to two array that sum of each array minimum.
you should compare list1Sum and list2Sum after add i, so:
if(list1Sum + i <= list2Sum){
list1Sum= list1Sum +i;
list1.add(i);
}else{
list2Sum= list2Sum +i;
list2.add(i);
}
I agree with Nayuki algorithm. Its knapsack problem with one dimension where you can consider value for all inputs same as inputs(or weights).
Now find two sub arrays whose is sum is less than equal to 31
import java.util.ArrayList;
import java.util.List;
public class Knapsack {
public static void main(String[] args) {
int[] weight = {4,13,14,15};
int[] value = {4,13,14,15};
int targetSum = 31;
knapsack(weight, value, targetSum);
}
public static void knapsack(int[] weight, int[] value, int targetSum) {
int[][] weightValMatrix = new int[weight.length + 1][targetSum + 1];
for (int i = 0; i < weight.length; i++) {
for (int k = 0; k < targetSum + 1; k++) {
weightValMatrix[i][k] = 0;
}
}
for (int i = 1; i < weight.length + 1; i++) {
for (int k = 1; k < targetSum + 1; k++) {
if (k < weight[i - 1]) {
weightValMatrix[i][k] = weightValMatrix[i - 1][k];
} else {
int valueInclusiveCurrentWeight = value[i - 1];
if ((k - weight[i - 1]) > 0) {
valueInclusiveCurrentWeight = valueInclusiveCurrentWeight
+ weightValMatrix[i - 1][k - weight[i - 1]];
}
int valueExcludingCurrentWeight = weightValMatrix[i - 1][k];
weightValMatrix[i][k] = valueInclusiveCurrentWeight >= valueExcludingCurrentWeight ? valueInclusiveCurrentWeight
: valueExcludingCurrentWeight;
}
}
}
for (int i = 1; i < weight.length + 1; i++) {
for (int k = 1; k < targetSum + 1; k++) {
System.out.print(weightValMatrix[i][k]);
if(k == targetSum){
System.out.println("");
}
}
}
System.out.println("final value is " + weightValMatrix[weight.length][targetSum]);
List<Integer> finallySelectedWeightIndex = new ArrayList<Integer>();
findActualWeightIndex(weightValMatrix, weight.length, targetSum, finallySelectedWeightIndex, weight);
for(int index:finallySelectedWeightIndex){
System.out.println("weight is " + weight[index-1] + " value is "+ value[index-1]);
}
}
public static void findActualWeightIndex(int[][] weightValMatrix, int row, int column,
List<Integer> finallySelectedWeightIndex, int[] weight) {
if(row==0 || column==0){
return;
}
if(weightValMatrix[row][column]==weightValMatrix[row-1][column]){
findActualWeightIndex(weightValMatrix, row-1, column, finallySelectedWeightIndex, weight);
}else{
finallySelectedWeightIndex.add(row);
findActualWeightIndex(weightValMatrix, row-1, column - weight[row-1] , finallySelectedWeightIndex, weight);
}
}
}

Java - (Print distinct numbers)

I'm trying to solve this problem:
"Write a program that reads in ten numbers and displays the number of distinct numbers and the distinct numbers separated by exactly one space."
My code at the moment does not save all distinct numbers and at time repeatedly display 0. If anyone can see where my logic has gone wrong, any tip will be helpful. Thank you!
public class PracticeProject
{
public static void main(String args[])
{
int[] number = new int[10];
int[] counter = new int[10];
int numcounter = 0;
numGen(number);
numcounter = distNum(number, counter, numcounter);
dispDist(counter, numcounter);
}
public static void numGen(int[] number)
{
Random rand = new Random();
for (int i = 0; i < number.length; i++)
{
number[i] = rand.nextInt(10);
System.out.print(number[i] + " ");
}
System.out.println();
}
public static int distNum(int[] number, int[] counter, int numcounter)
{
for (int i = 0; i < number.length; i++)
{
for (int j = 0; j <= i; j++)
{
if (counter[j] == number[i])
{
break;
}
if (j == i)
{
counter[j] = number[i];
numcounter++;
}
}
}
return numcounter;
}
public static void dispDist(int[] counter, int numcounter)
{
for (int i = 0; i < numcounter; i++)
{
System.out.print(counter[i] + " ");
}
}
}
The problem is with the logic in your distNum() method, which was not correctly removing all duplicates from the output array. Try using this version instead:
public static int distNum(int[] number, int[] counter, int numcounter) {
for (int i = 0; i < number.length; i++) {
boolean isUnique = true;
for (int j = 0; j < numcounter; j++) {
if (counter[j] == number[i]) {
isUnique = false;
break;
}
}
if (isUnique) {
counter[numcounter] = number[i];
numcounter++;
}
}
return numcounter;
}
I walk through the array of random numbers, and for each one I scan counter to see if the value has already been encountered. If it be a duplicate, then it does not get added to the unique list.
This method was tested along with the rest of your original code using IntelliJ, and it appears to be working correctly.
If you use array to store your counters, you need to set default value, otherwise if your array have multiple 0, it distinguish by equaling. because the int array default values is 0.
and you can use list or vector to store your counters.
public static void main(String args[]) {
int[] number = new int[10];
int[] counter = new int[10];
List<Integer> counters = new ArrayList<Integer>();
int numcounter = 0;
numGen(number);
numcounter = distNum(number, counters, numcounter);
dispDist(counters, numcounter);
}
public static void numGen(int[] number) {
Random rand = new Random();
for (int i = 0; i < number.length; i++) {
number[i] = rand.nextInt(10);
System.out.print(number[i] + " ");
}
System.out.println();
}
public static int distNum(int[] number, List<Integer> counters, int numcounter) {
for (int i : number) {
if (!counters.contains(i)){
counters.add(i);
}
}
return numcounter;
}
public static void dispDist(List<Integer> counter, int numcounter) {
for (Integer i : counter) {
System.out.print(i + " ");
}
}
Try put below function .... using Hashmap... Key will be no. and value will be the disctinct time it occured.
public void duplicate(int[] a) {
HashMap<Integer, Integer> h = new HashMap<Integer, Integer>();
for (int i = 0; i < a.length; i++) {
Integer j = (int) h.put(a[i], 1);
if (j != null) { // checking if already in hashmap
h.put(a[i], j + 1); // if there then incrementing value
}
}
Iterator it = h.entrySet().iterator(); // displaying value you can have you logic here
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}

Creating an Array with the same numbers from an old one but without repetitions

So I created an array with random numbers, i printed and counted the repeated numbers, now I just have to create a new array with the same numbers from the first array but without any repetitions. Can't use ArrayList by the way.
What I have is.
public static void main(String[] args) {
Random generator = new Random();
int aR[]= new int[20];
for(int i=0;i<aR.length;i++){
int number=generator.nextInt(51);
aR[i]=number;
System.out.print(aR[i]+" ");
}
System.out.println();
System.out.println();
int countRep=0;
for(int i=0;i<aR.length;i++){
for(int j=i+1;j<aR.length-1;j++){
if(aR[i]==aR[j]){
countRep++;
System.out.println(aR[i]+" "+aR[j]);
break;
}
}
}
System.out.println();
System.out.println("Repeated numbers: "+countRep);
int newaR[]= new int[aR.length - countRep];
}
Can someone help?
EDIT: Can't really use HashSet either. Also the new array needs to have the correct size.
Using Java 8 and streams you can do the following:
int[] array = new int[1024];
//fill array
int[] arrayWithoutDuplicates = Arrays.stream(array)
.distinct()
.toArray();
This will:
Turn your int[] into an IntStream.
Filter out all duplicates, so retaining distinct elements.
Save it in a new array of type int[].
Try:
Set<Integer> insertedNumbers = new HashSet<>(newaR.length);
int index = 0;
for(int i = 0 ; i < aR.length ; ++i) {
if(!insertedNumbers.contains(aR[i])) {
newaR[index++] = aR[i];
}
insertedNumbers.add(aR[i]);
}
One possible approach is to walk through the array, and for each value, compute the index at which it again occurs in the array (which is -1 if the number does not occur again). The number of values which do not occur again is the number of unique values. Then collect all values from the array for which the corresponding index is -1.
import java.util.Arrays;
import java.util.Random;
public class UniqueIntTest
{
public static void main(String[] args)
{
int array[] = createRandomArray(20, 0, 51);
System.out.println("Array " + Arrays.toString(array));
int result[] = computeUnique(array);
System.out.println("Result " + Arrays.toString(result));
}
private static int[] createRandomArray(int size, int min, int max)
{
Random random = new Random(1);
int array[] = new int[size];
for (int i = 0; i < size; i++)
{
array[i] = min + random.nextInt(max - min);
}
return array;
}
private static int[] computeUnique(int array[])
{
int indices[] = new int[array.length];
int unique = computeIndices(array, indices);
int result[] = new int[unique];
int index = 0;
for (int i = 0; i < array.length; i++)
{
if (indices[i] == -1)
{
result[index] = array[i];
index++;
}
}
return result;
}
private static int computeIndices(int array[], int indices[])
{
int unique = 0;
for (int i = 0; i < array.length; i++)
{
int value = array[i];
int index = indexOf(array, value, i + 1);
if (index == -1)
{
unique++;
}
indices[i] = index;
}
return unique;
}
private static int indexOf(int array[], int value, int offset)
{
for (int i = offset; i < array.length; i++)
{
if (array[i] == value)
{
return i;
}
}
return -1;
}
}
This sounds like a homework question, and if it is, the technique that you should pick up on is to sort the array first.
Once the array is sorted, duplicate entries will be adjacent to each other, so they are trivial to find:
int[] numbers = //obtain this however you normally would
java.util.Arrays.sort(numbers);
//find out how big the array is
int sizeWithoutDuplicates = 1; //there will be at least one entry
int lastValue = numbers[0];
//a number in the array is unique (or a first duplicate)
//if it's not equal to the number before it
for(int i = 1; i < numbers.length; i++) {
if (numbers[i] != lastValue) {
lastValue = i;
sizeWithoutDuplicates++;
}
}
//now we know how many results we have, and we can allocate the result array
int[] result = new int[sizeWithoutDuplicates];
//fill the result array
int positionInResult = 1; //there will be at least one entry
result[0] = numbers[0];
lastValue = numbers[0];
for(int i = 1; i < numbers.length; i++) {
if (numbers[i] != lastValue) {
lastValue = i;
result[positionInResult] = i;
positionInResult++;
}
}
//result contains the unique numbers
Not being able to use a list means that we have to figure out how big the array is going to be in a separate pass — if we could use an ArrayList to collect the results we would have only needed a single loop through the array of numbers.
This approach is faster (O(n log n) vs O (n^2)) than a doubly-nested loop through the array to find duplicates. Using a HashSet would be faster still, at O(n).

Number of Comparisons between selection sort and bubble sort keep coming up the same

I have written this program to compare the number of operations needed to sort a random numbers using both selection and bubble sort. However, these numbers keep coming up the same and I can't figure out where my code went wrong.
static int num_comps;
public static void main(String[] args)
{
Random rnd = new Random();
// max size of array
// number of N inputs
int array_size = 32768;
int num_datasets = 12;
// allocate array once to the max size
int[] vals = new int[array_size];
// temp array with allocated array to max size
int[] tvals = new int[array_size];
// array to hold operation counts
int[] op_counts = new int[num_datasets];
int[] op_counts2 = new int[num_datasets];
// array to hold the size of each array
//
int[] arraySizes = new int[num_datasets];
int i;
int j;
int sz;
for (i = 0, sz = 16; i < num_datasets; i++, sz *= 2)
arraySizes[i] = sz;
for (int iter = 0; iter < num_datasets; iter++)
{
int curr_size = arraySizes[iter];
// load array with random values
//
for (i = 0; i < curr_size; i++)
vals[i] = rnd.nextInt(4999);
for (i = 0; i < curr_size; i++)
tvals[i] = vals[i];
// run the bubble sort algorithm
//
num_comps = 0;
bubbleSort(tvals, curr_size);
op_counts[iter] = num_comps;
//System.out.println("Num comps at " + iter + " is " + num_comps);
// run the selection-sort algorithm
num_comps = 0;
selectionSort(tvals, curr_size);
op_counts2[iter] = num_comps;
//System.out.println("Num comps at " + iter + " is " + num_comps);
}
System.out.println("Operation Counts (N vs. op Count): ");
for (int k = 0; k < num_datasets; k++)
System.out.println(arraySizes[k] + "\t\t" + op_counts[k] + "\t\t" + op_counts2[k]);
}
static void bubbleSort(int vals[], int curr_size)
{
int temp;
for (int i = 0; i < curr_size - 1; i++)
{
for (int j = 0; j < curr_size - i - 1; j++)
{
// swap
num_comps = num_comps + 1;
if (vals[j+1] < vals[j])
{
temp = vals[j];
vals[j] = vals[j+1];
vals[j+1] = temp;
}
}
}
}
static void selectionSort(int vals[], int curr_size)
{
int temp;
for(int i=0; i<curr_size - 1; i++)
{
for(int j=i+1; j<curr_size; j++)
{
num_comps = num_comps + 1;
if(vals[i] > vals[j] )
{
temp = vals[j];
vals[j] = vals[i];
vals[i] = temp;
}
}
}
}
Your selection sort algorithm does not search for the lowest value in the list. And swapping it afterwards with the index of the outer loop.
You should do something like this:
static void selectionSort(int vals[], int curr_size)
{
int temp;
for(int i=0; i<curr_size - 1; i++)
{
int lowest = i;
for(int j=i+1; j<curr_size; j++)
{
num_comps = num_comps + 1;
if(vals[lowest] > vals[j] )
{
lowest = j;
}
}
// swap lowest with current index
temp = vals[lowest];
vals[lowest] = vals[i];
vals[i] = temp;
}
}
(of course this can be optimized further)
The strength of this algorithm is not the amount of of comparisons, but this amount of swaps (which is at a minimum, I suppose).
Your bubble sort algorithm seems ok to me.
Both have the same two loops, so comparing the counts of the current implementations indeed result in the same values. But, I think you can optimize the bubble sort, to stop earlier (when no swaps were found). Again, the strength of sorting algorithms depends on the used ones, and are not necessarily the least amount of comparisons. So Using the correct algorithm for your specific task, and thereby circumventing the task-specific high cost operations, is important!

Categories