Coin change algorithm always returning one - java

/**
*
* #param d
* currency divisions
* #param p
* target
* #return number of coins
*/
public static int change(int[] d, int p) {
int[] tempArray = new int[p*2]; // tempArray to store set
// of coins forming
// answer
for (int i = 1; i <= p; i++) { // cycling up to the wanted value
int min = Integer.MAX_VALUE; //assigning current minimum number of coints
for (int value : d) {//cycling through possible values
if (value <= i) {
if (1 + tempArray[i - value] < min) { //if current value is less than min
min = 1 + tempArray[1 - value];//assign it
}
}
}
tempArray[i] = min; //assign min value to array of coins
}
return tempArray[p];
}
Can anyone help me see why this is not working please? The method is meant to be given an input of values representing coins, it has an infinite number of these coints with which to form the integer p, the method is to return the minimum number of coins used to get to p.

tempArray is initialized to 0 on all indices.
using tempArray[1-value] is basically giving you 0.
So, all indices from 1 to p has the value 1 + tempArray[1-value]
This is 1. Also, tempArray[1-value] is a negetive index. I think you meant tempArray[i-value]

Related

Temporal cost and Spatial cost analysis problem

Hi I'm new to this and I don't know how to continue analyzing this algorithm that I have done myself, the conclusion I have right now is:
T(n) ϵ Ω(2n+1)
ϵ O(2n+max)
S(n) ϵ Θ(max)
'max' -> Maximum integer value in the array.
'n' -> Is the input size which is the length of the array.
Is this analysis correct?, 'max' will make it linear? and how can I express this better?
Thanks for the help.
Code
/**
* Method findUnique2
*
* Finds the unique number inside an array of integers
* in which there are always 1 unique number and the rest
* are repeated exactly twice.
*
* NOTE:
* This implementation only works with positive integer numbers.
*
* #param v -> Array with the integer numbers.
* #return The unique number.
*/
public static int findUnique2(int[] v)
{
int max = getMax(v); // Get the maximum number
int[] repetitions = new int[max+1];
boolean found = false;
// +1 to every position
for(int i=0; i<v.length; i++)
repetitions[v[i]]++;
/*
* Finally traversing the array an the position with
* a 1 is the unique number the rest can be either 0
* of not used or 2 which is a repeated number.
*/
int i = -1;
while(!found)
{
i++;
if(repetitions[i] == 1)
found = true;
}
return i;
}
/**
* Method getMax
*
* Traverse an array of integers and returns the maximum
* number stored inside it.
*
* #param v An array of integers
* #return the maximum number among the given array.
*/
public static int getMax(int[] v)
{
int max = v[0];
for(int i=1; i<v.length; i++)
if (max < v[i])
max = v[i];
return max;
}

How to remove value, determine minimum of remaining values

I need to determine the minimum value after removing the first value.
For instance is these are the numbers 0.5 70 80 90 10
I need to remove 0.5, the determine the minimum value in the remaining numbers. calweightAvg is my focus ...
The final output should be “The weighted average of the numbers is 40, when using the data 0.5 70 80 90 10, where 0.5 is the weight, and the average is computed after dropping the lowest of the rest of the values.”
EDIT: Everything seems to be working, EXCEPT during the final out put. "The weighted average of the numbers is 40.0, when using the data 70.0, 80.0, 90.0, 10.0, where 70.0 (should be 0.5) is the weight, and the average is computed after dropping the lowest of the rest of the values."
So the math is right, the output is not.
EDIT: While using a class static double weight=0.5;to establish the weight, if the user were to change the values in the input file, that would not work. How can I change the class?
/*
*
*/
package calcweightedavg;
import java.util.Scanner;
import java.util.ArrayList;
import java.io.File;
import java.io.PrintWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
public class CalcWeightedAvg {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
//System.out.println(System.getProperty("user.dir"));
ArrayList<Double> inputValues = getData(); // User entered integers.
double weightedAvg = calcWeightedAvg(inputValues); // User entered weight.
printResults(inputValues, weightedAvg); //Weighted average of integers.
}
public class CalcWeightedAvg {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
//System.out.println(System.getProperty("user.dir"));
ArrayList<Double> inputValues = getData(); // User entered integers.
double weightedAvg = calcWeightedAvg(inputValues); // User entered weight.
printResults(inputValues, weightedAvg); //Weighted average of integers.
}
public static ArrayList<Double> getData() throws FileNotFoundException {
// Get input file name.
Scanner console = new Scanner(System.in);
System.out.print("Input File: ");
String inputFileName = console.next();
File inputFile = new File(inputFileName);
//
Scanner in = new Scanner(inputFile);
String inputString = in.nextLine();
//
String[] strArray = inputString.split("\\s+"); //LEFT OFF HERE
// Create arraylist with integers.
ArrayList<Double> doubleArrayList = new ArrayList<>();
for (String strElement : strArray) {
doubleArrayList.add(Double.parseDouble(strElement));
}
in.close();
return doubleArrayList;
}
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
Double weight = inputValues.get(0);
inputValues.remove(0);
//Sum and find min.
double min = Double.MAX_VALUE;
double sum = 0;
for (Double d : inputValues) {
if (d < min) min = d;
sum += d;
}
// Calculate weighted average.
return (sum-min)/(inputValues.size()-1) * weight;
}
public static void printResults(ArrayList<Double> inputValues, double weightedAvg) throws IOException {
Scanner console = new Scanner(System.in);
System.out.print("Output File: ");
String outputFileName = console.next();
PrintWriter out = new PrintWriter(outputFileName);
System.out.println("Your output is in the file " + outputFileName);
out.print("The weighted average of the numbers is " + weightedAvg + ", ");
out.print("when using the data ");
for (int i=0; i<inputValues.size(); i++) {
out.print(inputValues.get(i) + ", ");
}
out.print("\n where " + inputValues.get(0) + " is the weight, ");
out.print("and the average is computed after dropping the lowest of the rest of the values.\n");
out.close();
}
}
to do this task in a complexity of O(n) isn't a hard task.
you can use ArrayList's .get(0) to Save weight in a temp variable, then use .remove(0) function which removes the first value (in this case 0.5)
then you should use a For Each loop for (Double d : list) to sum AND find the minimal value
afterwards subtract the minimum value from the sum. and apply weight to the sum (in this case you'll end up with 240*0.5 = 120; 120\3 = 40;
finally, you can use ArrayList's .size()-1 function to determine the divisor.
The problem in your code:
in your implementation you've removed the weight item from list. then multiplied by the first item in the list even though it's no longer the weight:
return (sum-min)/(inputValues.size()-1) * inputValues.get(0);
your calculation than was: ((70+80+90+10)-10)/(4-1) * (70) = 5600
if(inputValues.size() <= 1){
inputValues.remove(0);
}
this size safeguard will not remove weight from the list. perhaps you've meant to use >=1
even if that was your intention this will not result in a correct computation of your algorithm in the edge cases where size==0\1\2 I would recommend that you re-think this.
the full steps that need to be taken in abstract code:
ArrayList<Double> list = new ArrayList();
// get and remove weight
Double weight = list.get(0);
list.remove(0);
// sum and find min
double min=Double.MAX_VALUE;
double sum=0;
for (Double d : list) {
if (d<min) min = d;
sum+=d;
}
// subtract min value from sum
sum-=min;
// apply weight
sum*=weight;
// calc weighted avg
double avg = sum/list.size()-1;
// viola!
do take notice that you can now safely add weight back into the array list after its use via ArrayList's .add(int index, T value) function. also, the code is very abstract and safeguards regarding size should be implemented.
Regarding your Edit:
it appears you're outputting the wrong variable.
out.print("\n where " + inputValues.get(0) + " is the weight, ");
the weight variable was already removed from the list at this stage, so the first item in the list is indeed 70. either add back the weight variable into the list after you've computed the result or save it in a class variable and input it directly.
following are the implementation of both solutions. you should only use one of them not both.
1) add weight back into list solution:
change this function to add weight back to list:
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
Double weight = inputValues.get(0);
inputValues.remove(0);
//Sum and find min.
double min = Double.MAX_VALUE;
double sum = 0;
for (Double d : inputValues) {
if (d < min) min = d;
sum += d;
}
// Calculate weighted average.
double returnVal = (sum-min)/(inputValues.size()-1) * weight;
// add weight back to list
inputValues.add(0,weight);
return returnVal;
}
2) class variable solution:
change for class:
public class CalcWeightedAvg {
static double weight=0;
//...
}
change for function:
public static double calcWeightedAvg(ArrayList<Double> inputValues){
//Get and remove weight.
weight = inputValues.get(0); // changed to class variable
//...
}
change for output:
out.print("\n where " + weight + " is the weight, ");
Since you're using an ArrayList, this should be a piece of cake.
To remove a value from an ArrayList, just find the index of the value and call
myList.remove(index);
If 0.5 is the first element in the list, remove it with
inputValues.remove(0);
If you want to find the minimum value in an ArrayList of doubles, just use this algorithm to find both the minimum value and its index:
double minVal = Double.MAX_VALUE;
int minIndex = -1;
for(int i = 0; i < myList.size(); i++) {
if(myList.get(i) < minVal) {
minVal = myList.get(i);
minIndex = i;
}
}
Hope this helps!
If you want to remove the first element from ArrayList and calculate the minimum in the remaining you should do:
if(inputValues.size() <= 1) //no point in calculation of one element
return;
inputValues.remove(0);
double min = inputValues.get(0);
for (int i = 1; i < inputValues.size(); i++) {
if (inputValues.get(i) < min)
min = inputValues.get(i);
}
I am a little unclear about your goal here. If you are required to make frequent calls to check the minimum value, a min heap would be a very good choice.
A min heap has the property that it offers constant time access to the minimum value. This [implementation] uses an ArrayList. So, you can add to the ArrayList using the add() method, and minValue() gives constant time access to the minimum value of the list since it ensures that the minimum value is always at index 0. The list is modified accordingly when the least value is removed, or a new value is added (called heapify).
I am not adding any code here since the link should make that part clear. If you would like some clarification, I would be more than glad to be of help.
Edit.
public class HelloWorld {
private static ArrayList<Double> values;
private static Double sum = 0.0D;
/**
* Identifies the minimum value stored in the heap
* #return the minimum value
*/
public static Double minValue() {
if (values.size() == 0) {
throw new NoSuchElementException();
}
return values.get(0);
}
/**
* Adds a new value to the heap.
* #param newValue the value to be added
*/
public static void add(Double newValue) {
values.add(newValue);
int pos = values.size()-1;
while (pos > 0) {
if (newValue.compareTo(values.get((pos-1)/2)) < 0) {
values.set(pos, values.get((pos-1)/2));
pos = (pos-1)/2;
}
else {
break;
}
}
values.set(pos, newValue);
// update global sum
sum += newValue;
}
/**
* Removes the minimum value from the heap.
*/
public static void remove() {
Double newValue = values.remove(values.size()-1);
int pos = 0;
if (values.size() > 0) {
while (2*pos+1 < values.size()) {
int minChild = 2*pos+1;
if (2*pos+2 < values.size() &&
values.get(2*pos+2).compareTo(values.get(2*pos+1)) < 0) {
minChild = 2*pos+2;
}
if (newValue.compareTo(values.get(minChild)) > 0) {
values.set(pos, values.get(minChild));
pos = minChild;
}
else {
break;
}
}
values.set(pos, newValue);
}
// update global sum
sum -= newValue;
}
/**
* NEEDS EDIT Computes the average of the list, leaving out the minimum value.
* #param newValue the value to be added
*/
public static double calcWeightedAvg() {
double minValue = minValue();
// the running total of the sum took this into account
// so, we have to remove this from the sum to get the effective sum
double effectiveSum = (sum - minValue);
return effectiveSum * minValue;
}
public static void main(String []args) {
values = new ArrayList<Double>();
// add values to the arraylist -> order is intentionally ruined
double[] arr = new double[]{10,70,90,80,0.5};
for(double val: arr)
add(val);
System.out.println("Present minimum in the list: " + minValue()); // 0.5
System.out.println("CalcWeightedAvg: " + calcWeightedAvg()); // 125.0
}
}

Illegal Start of Expression

** Problem statement:
You are given a list of N people who are attending ACM-ICPC World Finals. Each of them are either well versed in a topic or they are not. Find out the maximum number of topics a 2-person team can know. And also find out how many teams can know that maximum number of topics.
Note Suppose a, b, and c are three different people, then (a,b) and (b,c) are counted as two different teams.
Input Format
The first line contains two integers, N and M, separated by a single space, where N represents the number of people, and M represents the number of topics. N lines follow.
Each line contains a binary string of length M. If the ith line's jth character is 1, then the ith person knows the jth topic; otherwise, he doesn't know the topic.
Constraints
2≤N≤500
1≤M≤500
Output Format
On the first line, print the maximum number of topics a 2-person team can know.
On the second line, print the number of 2-person teams that can know the maximum number of topics.
** Problem:
I have 2 errors ("illegal start of expression" and " ';' expected") when I want to declare the 2 numbers maxTopic and numTeam as:
public static int maxTopic = 0;
public static int numTeam = 0;
** Code:
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner in = new Scanner(System.in);
int ppl = in.nextInt(); // Number of people
int topic = in.nextInt(); // Number of topics
int A[]; // Array A to store information about topics known by everyone
public static int maxTopic = 0; // Maximum number of topics known
public static int numTeam = 0; // Maximum number of teams that know maxTopic
/* Read the information about topics
and save it to the array A */
for (int i = 0; i < ppl; i++)
A[i] = in.nextInt();
/* Now call the method addCheck() to check each pair of people */
for (int i = 0; i < ppl; i++)
for (int j = i + 1; j < ppl; j++)
Solution.addCheck(A[i], A[j], topic);
System.out.println(maxTopic);
System.out.println(numTeam);
}
/**
* Method used to add up 2 given numbers, check their sum,
* and update the values of maxTopic and numTeam (if possible)
* #param a First number
* #param b Second number
* #param digit Number of digits for a and b
*/
public void addCheck(int a, int b, int digit) {
int sum = a + b; // Calculate the sum of a and b
int numTopic = 0; // Number of topics known for a and b
boolean update = false; // True if the current pair has been used to update numTeam
for (int i = 1; i <= digit; i++) {
if (Solution.getNthDigit(sum, i) != 0)
numTopic++;
if (numTopic > maxTopic)
maxTopic = numTopic;
if ((update == false) && (maxTopic == numTopic)) {
numTeam++;
update = true;
}
}
}
/**
* Get the nth digit of an integer
* #param number The number being considered
* #param n The digit (starting from 1, counted from right to left)
* #return int The value of the nth digit
* Example: getNthDigit(123, 10, 1) produces 3
*/
public int getNthDigit(int number, int n) {
return (int) ((number / Math.pow(10, n - 1)) % 10);
}
}
You can't use public static modifiers within a method. Those are used for class-level declarations only. Since you use the variables in other methods, declare them in the class. Note, your addCheck method should be declared static.

Code sometimes returns Integer.MAX_VALUE.Cannot figure out why

I am trying to write code to return the lowest number of coins needed to make up a given number. The inputs to my method are an array of valid coins, and the number I try to make.
public static int change(int[] d, int p) {
int[] tempArray = new int[p + 1]; // tempArray to store set
// of coins forming
// answer
for (int i = 1; i <= p; i++) { // cycling up to the wanted value
int min = Integer.MAX_VALUE; // assigning current minimum number of
// coins
for (int value : d) {// cycling through possible values
if (value <= i) {
if (1 + tempArray[i - value] < min) { // if current value is
// less than min
min = 1 + tempArray[i - value];// assign it
}
}
}
tempArray[i] = min; // assign min value to array of coins
}
return tempArray[p];
}
This works for most cases, however, when I fill in the following :
int[] test = {2,3,4};
System.out.println("answer = " + change(test, 6));
The answer should be 2, right? But it prints out :
-2147483647
What have I missed?
Because, during the first iteration tempArray[i] = min; tempArray[i] is assigned to MAX, and during subsequent iteration[s], min = 1 + tempArray[i - value]; would try to increment MAX by one, which basically shifts the bits and forms a negative counterpart.

How do I "glue" the sorted partition back to a sorted one? (Quick Sort Java Implementation)

I have tested that my partitioning algorithm works well, but when it comes time in the implementation to make use of it, I get an array that is not sorted. Since this is for a class, there's a certain I need to write the class itself so that I can return the answer as string. My problem is most likely in the qkSort() method. Here's the code:
private static int splitterElement;
public static void main (String[] args){
System.out.println(myMethod());
}
public static String myMethod() {
String result = "";
int[] testArray = null;
testArray = populateArray(testArray, 7, 10);
result += "Before sort: \n" + printArray(testArray);
testArray = qkSort(testArray,1,testArray.length);
result += "After sort: \n" + printArray(testArray);
return result;
}
//Method to continually call the partition() method
public static int[] qkSort(int[] x, int left, int right){
if (right - left >= 1) {
//after running this method, the global variable splitterElement is assigned.
x = partition(x,left,right);
qkSort(x,left,splitterElement-1);
qkSort(x,splitterElement + 1,right);
}
//base case. if right-left = 0, then the array length is 1,
//and that is already sorted
return x;
}
/**
* Populates an integer array with random integers. Should be used only with
* non-itialized integer arrays.
*
* #param x an uninitialized array of integers and will be returned once it is populated.
* #param sizeOfArray The size that array x will be initialized to.
* #param rangeOfValues The range of values that that each element can be. This value should
* not surpass the maximum value for integers, but no error-checking is performed.
* #return
*/
public static int[] populateArray (int[] x, int sizeOfArray, int rangeOfValues){
x = new int[sizeOfArray];
for (int i = 0; i < sizeOfArray; i++){
x[i] = (int)(Math.random() * rangeOfValues); //place a random number from 0 to rangeOfValues into array.
}
return x;
}
/**
*
* #param x An integer array. It is assumed that x is initialized when the method is called.
* #param left
* #param right The length of the array can be used for the right int.
* #see #populateArray(int[], int, int)
* #return
*/
public static int[] partition (int[] x, int left, int right){
//element of the splitter
int l = (int) (Math.random() * x.length);
splitterElement = l;
x = swap (x,left,l);
//value of the splitter
int t = x[left];
int i = left;
for (int j = left + 1; j < right; j++){
if (x[j] < t){
i++;
x = swap (x,i,j);
}
}
x = swap(x,left,i);
return x;
}
/**
* Places the value at index1 in index2, and places the value at index2 in index1.
*
* #param array The array that will be worked on.
* #param index1 The first place we will switch values.
* #param index2 The second place we will switch values.
* #return
*/
public static int[] swap (int[] array, int index1, int index2){
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
return array;
}
/**
* A simple print method that prints an array.
* #param array Input.
*/
public static String printArray (int[] array){
String result = "";
for (int i = 0; i < array.length; i++){
result += array[i] + " ";
}
result += "\n";
return result;
}
}
Output:
Before sort:
8 9 7 3 4 2 6
After sort:
8 6 3 9 7 2 4
Thanks for any ideas on what my problem is!
I see several issues in your code:
1) the methods don't need to return the array, you could find a better use for the return value
2) using a global variable splitterElement doesn't work because its value can change during the first recursive call to qkSort. Method partition could return its value instead of returning the array, which is useless.
3) the first line of the partition method:
int l = (int) (Math.random() * x.length);
should be:
int l = left + (int) (Math.random() * (right - left));
because youre partitionning the range between left and right, not the whole array.

Categories

Resources