i'm trying to create a program about KNN method and now I'm stuck in loop for determining the class. Here's my coding :
public static void main(String[] args) {
int titikx, titiky, k;
int[] titikxl = new int[]{1, 1, 3, 2, 4, 6}; //first feature
int[] titiky1 = new int[]{1, 3, 1, 5, 3, 2}; //second feature
ArrayList<Double> nx = new ArrayList<Double>(), ny = new ArrayList<Double>(),
fn = new ArrayList<Double>(), arclass1 = new ArrayList<Double>(),
arclass2 = new ArrayList<Double>();
//input hew data's features and k
Scanner input = new Scanner(System.in);
System.out.println("Input first feature : ");
titikx = input.nextInt();
System.out.println("Input second feature : ");
titiky = input.nextInt();
System.out.println("Input k : ");
k = input.nextInt();
//count distance between new data and training data
int i = 0, j = 0;
while(i < titikxl.length || j <titiky1.length){
nx.add(Math.pow(titikx - titikxl[i], 2));
ny.add(Math.pow(titiky - titiky1[j], 2));
i++;
j++;
}
System.out.println(nx);
System.out.println(ny);
//convert arraylist to array
Double[] nxarray = nx.toArray(new Double[nx.size()]);
Double[] nyarray = ny.toArray(new Double[ny.size()]);
//sum the array of distance first feature and second feature to get result
int ii = 0, jj = 0;
while (ii < nxarray.length || jj < nyarray.length){
fn.add(Math.sqrt(nxarray[ii] + nyarray[jj]));
ii++;
jj++;
}
System.out.println(fn);
Double[] fnarray = fn.toArray(new Double[fn.size()]);
Double[] oldfnarray = fnarray; //array result before sort ascending
//ascending array
for(int id1 = 0; id1 < fnarray.length; id1++){
for(int id2 = id1 + 1; id2 < fnarray.length; id2++){
if(fnarray[id1]>fnarray[id2]){
double temp = fnarray[id2];
fnarray[id2] = fnarray[id1];
fnarray[id1] = temp;
}
}
}
for(int id = 0; id < fnarray.length; id++){
System.out.print(fnarray[id] + " ");
}
System.out.println();
double[] classa = new double[]{oldfnarray[0], oldfnarray[1], oldfnarray[2]};
double[] classb = new double[]{oldfnarray[3], oldfnarray[4], oldfnarray[5]};
//determining what class the new data belongs
for(int idb = 0; idb < classa.length; idb++){
for(int idc = 0; idc < classb.length; idc++){
for(int ida = 0; ida < fnarray.length; ida++){
while(ida < k){
if (classa[idb] == fnarray[ida]){
arclass1.add(fnarray[ida]);
}
if (classb[idc] == fnarray[ida]){
arclass2.add(fnarray[ida]);
}
}
}
}
}
if(arclass1.size() < arclass2.size()){
System.out.println("The Class is B");
} else{
System.out.println("The Class is A");
}
}
And the result is :
Input first feature : 2
Input second feature : 3
Input k : 3
[1.0, 1.0, 1.0, 0.0, 4.0, 16.0] //distance feature x
[4.0, 0.0, 4.0, 4.0, 0.0, 1.0] //distance feature y
[2.23606797749979, 1.0, 2.23606797749979, 2.0, 2.0, 4.123105625617661] //result
1.0 2.0 2.0 2.23606797749979 2.23606797749979 4.123105625617661 //ascended result
//looping forever
BUILD STOPPED (total time: 35 seconds)
As you can see, in the section determining class, when enter the loop the program seems doing the last loop forever. I try to modified it as capable as I could, yet still there's no result but error and running forever. Please help. Thank you most kindly.
The problem is the endless while loop - ida's value never changes. I suggest modifying the entire code block because it is more complicated than it needs to be.
Before coming up with a solution, let's determine what we already know:
the nearest k-neighbors (the sorted distances array, with indexes smaller than k)
which neighbors belong to which class
It becomes obvious that in order to determine the class, we need to:
check for every neighbor (outer loop) whether it is in class A (we need a first inner loop) or class B (we need second inner loop)
if neighbor is found to be in class A, we increase counter for class A, otherwise we do that for class B
compare counters: if counter for class A is greater, then the feature belongs in class A, otherwise in class B
To better understand what is going on, the k-NN classification algorithm is described comprehensively in this tutorial.
Code (same structure as yours, though I renamed variables and simplified some parts for readability):
import java.util.Arrays;
import java.util.Scanner;
public class KNN {
public static void main(String[] args) {
int[] feature1 = new int[] { 1, 1, 3, 2, 4, 6 };
int[] feature2 = new int[] { 1, 3, 1, 5, 3, 2 };
//input hew data's features and k
Scanner input = new Scanner(System.in);
System.out.println("Input first feature : ");
int newFeature1 = input.nextInt();
System.out.println("Input second feature : ");
int newFeature2 = input.nextInt();
System.out.println("Input k : ");
int k = input.nextInt();
input.close();
//count distance between new data and training data
double[] distances1 = new double[feature1.length];
double[] distances2 = new double[feature2.length];
for (int i = 0; i < distances1.length; i++) {
distances1[i] = Math.pow(newFeature1 - feature1[i], 2);
}
for (int i = 0; i < distances2.length; i++) {
distances2[i] = Math.pow(newFeature2 - feature2[i], 2);
}
System.out.println("Distance between first feature and first feature training data: " + Arrays.toString(distances1));
System.out.println("Distance between second feature and second feature training data: " + Arrays.toString(distances2));
//sum the array of distance first feature and second feature to get result
double[] distanceSums = new double[distances1.length];
for (int i = 0; i < distances1.length; i++) {
distanceSums[i] = Math.sqrt(distances1[i] + distances2[i]);
}
System.out.println("Distance sums: " + Arrays.toString(distanceSums));
// sort array ascending
double[] distanceSumsSorted = new double[distanceSums.length];
System.arraycopy(distanceSums, 0, distanceSumsSorted, 0, distanceSums.length);
Arrays.sort(distanceSumsSorted);
System.out.println("Sorted distance sums: " + Arrays.toString(distanceSumsSorted));
double[] classAMembers = new double[] { distanceSums[0], distanceSums[1], distanceSums[2] };
double[] classBMembers = new double[] { distanceSums[3], distanceSums[4], distanceSums[5] };
//determining what class the new data belongs
int classACounts = 0;
int classBCounts = 0;
for (int i = 0; i < k; i++) {
// check if nearest neighbor belongs to class A
for (int j = 0; j < classAMembers.length; j++) {
if (distanceSumsSorted[i] == classAMembers[j]) {
classACounts++;
break;
}
}
// check if nearest neighbor belongs to class B
for (int j = 0; j < classBMembers.length; j++) {
if (distanceSumsSorted[i] == classBMembers[j]) {
classBCounts++;
break;
}
}
}
System.out.println("Class A members: " + Arrays.toString(classAMembers));
System.out.println("Class B members: " + Arrays.toString(classBMembers));
System.out.println("Counts for class A: " + classACounts);
System.out.println("Counts for class B: " + classBCounts);
if (classACounts < classBCounts){
System.out.println("The Class is B.");
}
else {
System.out.println("The Class is A.");
}
}
}
For your example data the program outputs:
Input first feature : 2
Input second feature : 3
Input k : 3
Distance between first feature and first feature training data: [1.0, 1.0, 1.0, 0.0, 4.0, 16.0]
Distance between second feature and second feature training data: [4.0, 0.0, 4.0, 4.0, 0.0, 1.0]
Distance sums: [2.23606797749979, 1.0, 2.23606797749979, 2.0, 2.0, 4.123105625617661]
Sorted distance sums: [1.0, 2.0, 2.0, 2.23606797749979, 2.23606797749979, 4.123105625617661]
Class A members: [2.23606797749979, 1.0, 2.23606797749979]
Class B members: [2.0, 2.0, 4.123105625617661]
Counts for class A: 1
Counts for class B: 2
The Class is B.
Related
I want to write a program that matches n men [0,1,2,...,n-1] to n women [0,1,2,...,n-1] according to their preferences. These preferences are represented by n x n-matrices, one for the men and one for the women.
[ 0 2 1 ]
E.g. men: [ 1 0 2 ]. The rows represent each man from 0 to 2, and per row we see a man's 'top 3'.
[ 1 2 0 ]
In this example: man 0 prefers woman 0 over woman 2; woman 1 is both man1's and man2's most prefered partner.
Now, I want to make sure that the matchings are as ideal as possible. This can be done by using the Gale-Shapley Algorithm.
I have two questions:
Suppose that m0 and m1 both have w0 as their first pick. Then, we'll have to look at w0's preferences: suppose that m0 is ranked higher, then (m0,w0) is a (temporary) matching. What should I do next? Do I first match m2 to his first pick, or - since m1 is still free - do I match m1 to his second pick?
I've already implemented an algorithm that looks like this:
Basically, the input consists of the preference matrices of both men and women. The result should be an array like res = [2,0,1], meaning man 2 is matched to woman 0, m0 with w1 and m1 with w2.
public int[] match(int[][] men, int[][] women) {
int n = men.length;
boolean[] menFree = new boolean[n];
Arrays.fill(menFree, true);
int[] res = new int[n];
Arrays.fill(res, -1);
int free = n;
int m = 0;
while (free > 0 && m<n) {
for (int i = 0; i < n; i++) {
if(menFree[i]){
int w = men[i][m];
if(res[w]==-1){
res[w]=i;
menFree[i]=false;
free--;
} else {
int c = res[w];
int colI = 0;
int colC = 0;
for(int j=0;j<n;j++){
if(women[w][j]==i){
colI = j;
} else if(women[w][j]==c){
colC = j;
}
}
if(colI<colC){
res[w]=i;
menFree[c]=true;
menFree[i]=false;
} else {
//do nothing or change column here, depending on answer to my first question.
}
}
}
}
m++;
}
return res;
}
As you can see I'm not sure what to do with the else-part when the position of a man's (=M's) competitor is higher then the position of M himself. Also, if it turns out that I should at that point look for M's second pick, how can I do this? There's still a possibility that I'll have to return to the first pick of the man after M.
Thanks for helping me out.
I read the wiki. And I implement myself.I think I understand it but my program is not beautiful.Just for communication.
package algorithm;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class GaleShapley {
public static void main(String[] args) {
int[][] men = {{1, 2, 0}, {0, 1, 2}, {2, 1, 0}};
int[][] women = {{1, 2, 0}, {0, 1, 2}, {2, 1, 0}};
int[] res = match(men, women);
for (int i : res)
System.out.println(i);
}
static int[] match(int[][] men, int[][] women) {
Map<Integer, Integer> temp = new HashMap<>();
int size = men.length;
boolean[] menFree = new boolean[size];
boolean[] womenFree = new boolean[size];
Arrays.fill(menFree, true);
Arrays.fill(womenFree, true);
ArrayList<Integer> stillFree = new ArrayList<>();
while (stillFree.size() + temp.size() < size) {
for (int i = 0, j = 0; i < size; i++, j = 0) {
if (menFree[i]) {
for (; j < size; j++) {
//if the woman is free,make them a pair
if (womenFree[men[i][j]]) {
// make woman and man i pair, the woman's index is men[i][j]
temp.put(men[i][j], i);
menFree[i] = false;
womenFree[men[i][j]] = false;
break;
} else {
// the woman is not free,check her pair is whether stable
int pairMan = temp.get(men[i][j]);
boolean stable = checkStable(pairMan, i, men[i][j], women);
// not stable break them and make new pair
if (!stable) {
temp.put(men[i][j], i);
menFree[i] = false;
menFree[pairMan] = true;
break;
}
}
}
// if man i is still free , it means that he can't find a woman
if (menFree[i])
stillFree.add(i);
}
}
}
int[] stablePair = new int[2 * temp.size()];
int i = 0;
for (Map.Entry<Integer, Integer> entry : temp.entrySet()) {
stablePair[i] = entry.getValue();
i++;
stablePair[i] = entry.getKey();
i++;
}
return stablePair;
}
static boolean checkStable(int pairMan, int currentMan, int woman, int[][] women) {
// index of pairMan and currentMan
int p = 0, c = 0;
for (int i = 0; i < women.length; i++) {
if (women[woman][i] == pairMan)
p = i;
else if (women[woman][i] == currentMan)
c = i;
}
// p<c : the woman love p more than c, they are stable
return p < c;
}
}
I have this array :
int[][] multi = new int[][]{
{ 3, 4, 2},
{ 2, 2, 5 },
{ 1, 2 }
};
I would like to print the produce of each cells. It's pretty hard to explain so lets see some example :
For my table i need to print :
6 //(3*2*1)
12 //(3*2*2)
6 //(3*2*1)
12 //(3*2*2)
15 //(3*5*1)
30 //(3*5*2)
8 //(4*2*1)
16 //(4*2*2)
8 //(4*2*1)
16 //(4*2*2)
20 //(4*5*1)
40 //(4*5*2)
...
Size of table can change, i need a generic things.
Here is my start but it's not doing what i need. This is looping line by line...
for (int i = 0; i<multi[0].length; i++) {
for (int k = 0; k < multi.length; k++) {
for (int l = 0; l < multi[k].length; l++ ) {
System.err.println(multi[k][l]);
}
}
}
I thing you have to do that recursively if your dimensions of array is not fixed..
I came up the code for dynamic dimension of 2D array
public class HelloWorld{
static int[][] multi = new int[][]{
{ 3, 4, 2},
{ 2, 2, 5 },
{ 1, 2 }
};
static public void pattern(int row,int multip) {
if(row >= multi.length) {
System.out.println(multip);
return ;
}
for(int i = 0; i<multi[row].length;i++) {
multip*=multi[row][i];
row+=1;
pattern(row,multip);
row-=1;
multip/=multi[row][i];
}
}
public static void main(String []args){
pattern(0,1);
}
}
If your dimensions are fixed then you can also do that using above logic but for that if you want to do iterative then you have to repeatedly create loops inside loop.
It's not hard to explain if you use mathematics terms and what you need is simply a Cartesian product of the sets (i.e. each row) in your bidimensional array.
It could be a bit longer to explain here the theory about Cartesian product (X is the operator) but in practice you have to calculate the result of:
((multi[0] X multi[1]) X ...) X multi[n]
And you ends with a bidimensional array with a number of rows which is the product of all the cardinality of each set and each row has a number of elements which is the number of the sets (because each tupla has an element from each set).
Another thing is that the tuple are ordered i.e. the element of a set will be in the same position in all the tuples e.g. each tupla in position 0 will have an element of multi[0].
Knowing these properties is possible to create the product with a construction algorithm which puts the elements of the first set in the first column of the resulting set repeating them the necessary amount of time and then go on with the next set/next column.
At the end when you have your Cartesian product you can do anything you want e.g. calculate the product of the elements of each row.
public class CartesianProductProduct {
public int[][] product(int[][] sets) {
int cardinality = 1;
for (int is = 0; is < sets.length; is++) cardinality *= sets[is].length;
int[][] cartesianProduct = new int[cardinality][sets.length];
int curCardinality = 1;
for (int is = 0; is < sets.length; is++) {
curCardinality *= sets[is].length;
int repetition = cardinality / curCardinality;
int ie = 0;
for (int ic = 0; ic < cardinality; ic++) {
cartesianProduct[ic][is] = sets[is][ie];
if (repetition == 1) {
ie++;
} else if ((ic + 1) % repetition == 0) {
ie++;
}
ie = ie == sets[is].length ? 0 : ie;
}
}
return cartesianProduct;
}
public static void main(String[] args) {
int[][] multi = new int[][]{
{3, 4, 2},
{2, 2, 5},
{1, 2}
};
int[][] cartesianProduct = new CartesianProductProduct().product(multi);
for (int i = 0; i < cartesianProduct.length; i++) {
int prod = 1;
String s = "";
String sep = "";
for (int k = 0; k < cartesianProduct[i].length; k++) {
prod *= cartesianProduct[i][k];
s = s + sep + cartesianProduct[i][k];
sep = "*";
}
System.out.printf("%s //(%s)\n", prod, s);
}
}
}
Score Finder (100 Marks)
Praveen is finding a job as a Computer Science teacher in school.
He has been rejected many times by different schools but this time he is determined to get the job.
He goes to the principal of the school St. Mary.
The principal says that in his school there is Grading and Credit system.
There are N subjects and each subject has a credit Ci attached to it (1 <= i <= N).
Each student gets a particular grade in each subject and each grade has a point value which are:
A = 10,
A(minus) = 9,
B = 8,
B(minus) = 7,
C = 6,
C(minus) = 5
Now if there are 3 subjects of credits 4, 3 and 2 respectively and a particular student scores A(minus),
B and C in these 3 subjects respectively then his score would be calculated as follows:
Total Score=Summation of product of Grade point and corresponding credit for each subject.
= ( (9*4) + (3*8) + (2*6) ) = 72.
He wants Praveen to tell total distinct Scores that are possible
to be given to a student given credits of N subjects by assigning different grades to each subject.
Input Format
Your function contains a single argument- a one-dimensional Integer Array A of N elements where each represents Credit of that subject.
The first line of input contains an Integer N denoting the size of the array.
Next N lines of input each containing an Integer denoting the credit Ci of ith subject
Constraints
1 <= N <= 100
1 <= Ci <= 5
Output Format
You must return a single integer denoting the total number of scores that are possible to be given.
Sample TestCase 1
Input
2
1
2
Output
16
now I am writing code like this
package javaapplication1;
import java.util.Scanner;
public class CandidateCode {
private static void possibleCombination(int input) {
int i=0;
int[] a=new int[Grades.length];
a[i]=input;
System.out.println("the a is "+a[i]);
}
private static final int[] Grades = new int[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
public static void main(String[] args) {
int i=0,j,totalSummation=0;
Scanner uInput = new Scanner(System.in);
System.out.println("Enter length of Array:");
int index = uInput.nextInt();
int[] Credit = new int[index];
for (i = 0; i <= Credit.length-1; i++) {
Credit[i] = uInput.nextInt();
System.out.println("credit is" + Credit[i]);
for ( j = 0; j <= Grades.length - 1; j++) {
totalSummation = +(Grades[j] * Credit[i]);
possibleCombination(totalSummation);
// System.out.println("total sum is " + totalSummation);
}
}
}
}
Now I want to store the values calculated in each iteration...
Meaning for
iteration first the values are 10,9,8,7,6,5,4,3,2,1
itertion second the values are 20,18,16,14,10,8,6,4,2
i want to sum each value of 1st iteration with all the values of 2nd iteration.
i,e 10+20, 10+18, 10+16, 10+14, 10+10, 10+8, 10+6, 10+4, 10+2
similarly for 9,8,7,6,5,4,3,2,1
To achieve this I need to store the values per iteration but I am stuck here, please guys help me to get rid of this problem thank you in advance.
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
public class Sample {
public static void main(String args[] ) throws Exception {
Scanner scan = new Scanner(System.in);
int nValue = scan.nextInt();
if(nValue<1 || nValue>100){
System.out.println("Array Value cannot be less than 1 or greater than 100");
}
int[] inputCredits = new int[nValue];
for( int i=0 ; i < nValue ; i++){
inputCredits[i]=scan.nextInt();
if(inputCredits[i]<1 || inputCredits[i]>5){
System.out.println("Credit Value cannot be less than 1 or greater than 5");
}
}
List<Integer> list1 = Arrays.stream(inputCredits).boxed().collect(Collectors.toList());
List<Integer> list2 = Arrays.asList(5,6,7,8,9,10);
//checked for basic constraints up till this point
//Next what we multiply all the inputted Credits with the possible grades and
// store in the list where x input Credits will produce a list of x*6 entries
// where first six entries are the possibilities for the first Credit, next 6
// entries for the 2nd credit and so on, having this knowledge we loop through // the list to get all the possible scores
List<Integer> permutedList = list1.stream().flatMap(i -> list2.stream().map(j -> i*j)).collect(Collectors.toList());
List<Integer> listForDistinctSet= new ArrayList<Integer>();
for(int i=0; i<6 ; i++){
listForDistinctSet.add(permutedList.get(i));
}
Set<Integer> distinctSet = new HashSet<Integer>();
for(int j=6,k=j+6;k<=permutedList.size();j=k,k=k+6){
Set<Integer> newSet = new HashSet<Integer>();
for(int i=0; i<listForDistinctSet.size(); i++){
for(; j<k ; j++){
int sum = listForDistinctSet.get(i) + permutedList.get(j);
newSet.add(sum);
}
j=k-6;
}
distinctSet=newSet;
listForDistinctSet = new ArrayList<>(distinctSet);
}
System.out.println(distinctSet.size());
}
}
If you don't want to store in a multi-dimensional array then you need to store each iteration in single dimensional array as below. But this code will work only for two credits.
public class CandidateCode {
private static int possibleCombination(int input)
{ int i=0;
int[] a=new int[Grades.length];
a[i]=input;
return a[i];
}
private static final int[] Grades = new int[]{10, 9, 8, 7, 6, 5, 4,
3, 2, 1};
public static void main(String[] args) {
int i=0,j,totalSummation=0;
Scanner uInput = new Scanner(System.in);
System.out.println("Enter length of Array:");
int index = uInput.nextInt();
int[] Credit = new int[index];
int[] creditarr = new int[10];
int[] credit1 = new int[10];
int[] credit2 = new int[10];
for (i = 0; i <= Credit.length-1; i++) {
Credit[i] = uInput.nextInt();
System.out.println("credit is" + Credit[i]);
for ( j = 0; j <= Grades.length - 1; j++) {
totalSummation = +(Grades[j] * Credit[i]);
creditarr[j]=possibleCombination(totalSummation);
if(Credit[i]==1) {
credit1[j]=creditarr[j];
}
if(Credit[i]==2){
credit2[j]=creditarr[j];
}
}
}
for(int k=0;k<credit1.length;k++) {
for(int l=0;l<credit2.length;l++) {
int final_no=credit1[k]+credit2[l];
System.out.println("final_no :" +final_no);
}
}
}
}
Is this what you want?
I guess the below code would be the best solution.This code will work for the no of credits you mention.
public class Candidate {
private static final int[] Grades = new int[]{10, 9, 8, 7, 6, 5};
public static void main(String[] args) {
// TODO Auto-generated method stub
int i=0,score=0,totalsummation=0;
Scanner uInput = new Scanner(System.in);
System.out.println("Enter length of Array:");
int arraylength = uInput.nextInt();
int[] credits= new int[arraylength];
ArrayList<Integer> combination = new ArrayList<Integer>();
for (i = 0; i <credits.length; i++) {
credits[i] = uInput.nextInt();
}
switch(credits.length) {
case 1:
for(int c1=10;c1>=5;c1--) {
totalsummation = c1*credits[0];
combination.add(totalsummation);
}
break;
case 2:
for(int g:Grades) {
for(int c2=10;c2>=5;c2--) {
totalsummation=g*credits[0]+c2*credits[1];
combination.add(totalsummation);
}
}
break;
case 3:
for(int g:Grades) {
for(int c3=10;c3>=5;c3--) {
totalsummation=g*credits[0]+c3*credits[1]+c3*credits[2];
combination.add(totalsummation);
}
}
break;
case 4:
for(int g:Grades) {
for(int c4=10;c4>=5;c4--) {
totalsummation=g*credits[0]+c4*credits[1]+c4*credits[2]+c4*credits[3];
combination.add(totalsummation);
}
}
break;
case 5:
for(int g:Grades) {
for(int c5=10;c5>=5;c5--) {
totalsummation=g*credits[0]+c5*credits[1]+c5*credits[2]+c5*credits[3]+c5*credits[4];
combination.add(totalsummation);
}
}
break;
default:
System.out.println("Invalid Input");
}
ArrayList<Integer> distinctnos =(ArrayList<Integer>) combination.stream().distinct().collect(Collectors.toList());
System.out.println(distinctnos.size()); }
}
Hope this answers your question.
Ok, following our discussion in comments: you don't need two for loops.
for i = 0; i < array.size(); i++ {
sum += grade[i]*credit[i]
}
Sorry for the generic coding style. Is it what you want?
After researching the Coin Change problem I tried my best to implement the solution. The code I have so far prints the minimum number of coins needed for a given sum. However, it does not print out the number of each coin denomination needed. This is what my code currently looks like:
public class Coins {
static int minCoins(int coinValues[], int m, int target) {
int[] totalCoins = new int[target + 1];
int[][] numOfCoins = new int[target + 1][m];
totalCoins[0] = 0;
for (int i = 1; i <= target; i++) {
totalCoins[i] = Integer.MAX_VALUE;
}
for (int i = 1; i <= target; i++) {
for (int j = 0; j < m; j++) {
if (coinValues[j] <= i) {
int previous = totalCoins[i - coinValues[j]];
if (previous != Integer.MAX_VALUE && previous + 1 < totalCoins[i]) {
totalCoins[i] = previous + 1;
}
}
}
}
return totalCoins[target];
}
public static void main(String args[]) {
int coinValues[] = {1, 5, 10, 20};
int m = coinValues.length;
int target = 26;
System.out.println("Minimum coins required is "+ minCoins(coinValues, m, target) );
}
}
I'm just very confused how/where I should populate numOfCoins[][].
Solution that I implemented in Groovy using Euro denominations
class coinage {
def denoms = [1, 2, 5, 10, 20, 50, 100, 200]
def resultArray = []
def remainder
def largest
def newResult
def calculate(int amt) {
def value = denoms.findAll({ element -> element <= amt})
largest = value.last()
resultArray.add(largest)
remainder = amt - largest
if (remainder == 0 || remainder == amt) {
newResult = resultArray.size()
println("Minimum number of coins required for this is: $newResult")
} else
calculate(remainder)
}
}
And to call it:
coins = new coinage()
coins.calculate(305)
#user1523236 provides the greedy method which does not solve the general case. For example, if one removes the 1 denomination and calculates the change for 8.
Please take a look at, for example, 4.12. Dynamic Programming, or The dynamic programming alogorithm for CMP (change making problem). Both references provide general dynamic programming algorithms.
I was trying out a programming challenge I found, you can find it here if you want to know exactly what the requirements are, but what i'm basically trying to do is to get the lowest possible multiple of a Fibonacci Sequence that contains a given number. So input 13 would output [0, 1, 1, 2, 3, 5, 8, 13]. Input 6 would output [0, 2, 2, 4, 6].
My code works fine for any number in the regular Fibonacci Sequence but for any multiple it just outputs, for exmple if the input is 16, [0, 16] and I can't quite figure out why. Any help would be massively appreciated.
import java.util.Scanner;
import java.util.ArrayList;
public class FibonacciMultiples{
public static void main(String args[]){
int target;
ArrayList<Integer> x = new ArrayList<Integer>();
x.add(0);
Scanner input;
input = new Scanner(System.in);
System.out.println("Please enter target: ");
target = input.nextInt();
int i = 0;
int j = 1;
int k = 1;
while(x.get(i) != target){
x.add((j*k) + x.get(i));
i++;
j = x.get(i-1);
if(x.get(i) > target){
x.clear();
x.add(0);
i=0;
j=1;
k++;
}
};
System.out.println(x);
}
}
The problem is here :
j = x.get(i-1);
You take the j for the next iteration from the list, which means it's already multiplied by k.
Then you multiply it again by k here :
x.add((j*k) + x.get(i));
One way to fix it is change
j = x.get(i-1);
to
j = x.get(i-1)/k;
EDIT :
A much more elegant solution with no multiplications or divisions :
while(x.get(i) != target){
x.add(j + x.get(i));
i++;
j = x.get(i-1);
if(x.get(i) > target){
x.clear();
x.add(0);
i=0;
j=k; // this is the key
k++;
}
};
Now the first elements in the sequence are initialized to 0 and k, which means each element will be k times larger than the corresponding element in the original sequence.
Output for 16 :
[0, 2, 2, 4, 6, 10, 16]
an even more elegant solution (IMO) is this:
public static void main(String[] args)
{
int target;
Scanner input;
input = new Scanner(System.in);
System.out.println("Please enter target: ");
target = input.nextInt();
List<Integer> fibonacciList = new ArrayList<>();
int f1 = 1; // f1 starts at 1 and is increased until found a match
do {
fibonacciList = fibonacci(f1++, target);
} while (fibonacciList.get(fibonacciList.size()-1) != target);
System.out.println(fibonacciList);
}
// calculate fibonacci with given f(1) value until
// target is reached (or passed)
public static List<Integer> fibonacci(int f1, int target)
{
List<Integer> fibonacciList = new ArrayList<>();
// seed the list with given arg
fibonacciList.add(0);
fibonacciList.add(f1);
while (fibonacciList.get(fibonacciList.size()-1) < target) {
// build the list by adding last two items
fibonacciList.add(
fibonacciList.get(fibonacciList.size()-2) +
fibonacciList.get(fibonacciList.size()-1));
}
return fibonacciList;
}