I want to generate all subsets of a set from 0 to n.
My code works successfully in c++, but in Java I've got different result
My code in c++:
#include <bits/stdc++.h>
using namespace std;
vector <vector<int>> v;
vector <int> u;
int n,i,j;
void f(vector <int> m,int k){
if(k==n+1){v.push_back(m);return;}
f(m,k+1);
m.push_back(k);
f(m,k+1);
}
int main() {
cin>>n;
f(u,0);
for(i=0;i<v.size();i++){
for(j=0;j<v[i].size();j++)cout<<v[i][j]<<' ';
cout<<endl;
}
}
input in c++: 2
output:
2
1
1 2
0
0 2
0 1
0 1 2
and my code in Java:
import java.util.*;
public class Main {
public static int c=0,j,i,n,l,r,x;
public static Vector <Vector<Integer>> v = new Vector();
public static void f(Vector <Integer> m,int k){
if (k==n+1) {v.add(m);return;}
f(m,k+1);
m.add(k);
f(m,k+1);
}
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
n=scan.nextInt();
Vector<Integer> u = new Vector<Integer>();
f(u,0);
for(i=0;i<v.size();i++){
for(int j:v.get(i))System.out.print(j+" ");
System.out.print("\n");
}
}
}
input in Java: 2
output:
2 1 2 0 2 1 2
2 1 2 0 2 1 2
2 1 2 0 2 1 2
2 1 2 0 2 1 2
2 1 2 0 2 1 2
2 1 2 0 2 1 2
2 1 2 0 2 1 2
2 1 2 0 2 1 2
As you see code in java is based on same logic but I cannot understand why java version gives me wrong result.
As you see code in java is based on same logic but I cannot Understand Why java code gives me wrong result
There is a big difference between C++ and Java here. In C++, unless you explicitly use vector<int> & v to use the same vector, it will automatically make a copy while in Java you have to explicitly do the copy yourself. Java uses pass-by-value mechanism and you only created one vector and then use it all the way which actually using the same vector.
Your problem lies: using the same vector to collect the elements all the way through.
To solve this problem, you should create a new vector to store the elements when passing in the method as:
public class HelloWorld {
public static int c = 0, j, i, n, l, r, x;
public static Vector<Vector<Integer>> v = new Vector();
// each combination of the elements should have an independent vector;
public static void f(Vector<Integer> m, int k) {
if (k == n + 1) {
v.add(m);
return;
} // the unique vector;
f(new Vector<>(m), k + 1); // create a new vector to store the elements;
m.add(k);
f(new Vector<>(m), k + 1); // same logic applied here;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
n = scan.nextInt();
Vector<Integer> u = new Vector<Integer>();
f(new Vector<>(), 0);
for (i = 0; i < v.size(); i++) {
for (int j : v.get(i)) System.out.print(j + " ");
System.out.print("\n");
}
}
}
Output can be:
3
3
2
2 3
1
1 3
1 2
1 2 3
0
0 3
0 2
0 2 3
0 1
0 1 3
0 1 2
0 1 2 3
Related
I'm working on the following problem:
Given an array of integers and a sum B, find all unique combinations in the array where the sum is equal to B. The same number may be chosen from the array any number of times to make B.
Note:
All numbers will be positive integers.
Elements in a combination (a1, a2, …, ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
The combinations themselves must be sorted in ascending order. Example:
Input:
N = 4
arr[] = {7,2,6,5}
B = 16
Output:
(2 2 2 2 2 2 2 2)
(2 2 2 2 2 6)
(2 2 2 5 5)
(2 2 5 7)
(2 2 6 6)
(2 7 7)
(5 5 6)
The problem is for the input arr[] = {8, 1, 8, 6, 8}, B = 12
I am getting (1 1 1 1 1 1 1 1 1 1 1 1)(1 1 1 1 1 1 6)(1 1 1 1 8)(1 1 1 1 8)(1 1 1 1 8)(6 6) as output but the correct output is (1 1 1 1 1 1 1 1 1 1 1 1)(1 1 1 1 1 1 6)(1 1 1 1 8)(6 6)
My code:
static void findCombination(int idx, int target, int[] arr, ArrayList<ArrayList<Integer>> ans, List<Integer> ds){
//base case
if(idx == arr.length){
if(target == 0){
ans.add(new ArrayList<>(ds));
}
return;
}
//recursion
if(arr[idx] <= target){
ds.add(arr[idx]);
findCombination(idx,target-arr[idx],arr,ans,ds); //function call
ds.remove(ds.size()-1); //backtracking step
}
findCombination(idx+1,target,arr,ans,ds);
}
//Function to return a list of indexes denoting the required
//combinations whose sum is equal to given number.
static ArrayList<ArrayList<Integer>> combinationSum(ArrayList<Integer> A, int B)
{
// add your code here
ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
int[] arr = new int[A.size()];
int i = 0;
for(int val : A){
arr[i++] = val;
}
Arrays.sort(arr);
findCombination(0, B, arr, ans, new ArrayList<>());
return ans;
}
}
You should be dealing with unique values.
static ArrayList<ArrayList<Integer>> combinationSum(ArrayList<Integer> A, int B) {
ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
findCombination(0, B,
A.stream().mapToInt(Integer::intValue).distinct().sorted().toArray(),
ans, new ArrayList<>());
return ans;
}
You can use a Set or Hashset instead of the ArrayList. It will provide you with unique results only.
can someone please check my code as to why the last index is not working as intended? Any advice on how to improve this is much appreciated.
import java.io.*;
import java.util.*;
public class Solution {
public static void insertionSortPart2(int[] ar) {
int key;
int seen;
for (int i = 0 ; i < ar.length-1; i++){
key = ar[i];
seen = i;
while (seen <ar.length-1 && ar[seen+1]<key){
ar[seen]= ar[seen+1];
seen = seen+1;
}
ar[seen]=key;
printArray(ar);
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int s = in.nextInt();
int[] ar = new int[s];
for(int i=0;i<s;i++){
ar[i]=in.nextInt();
}
insertionSortPart2(ar);
}
private static void printArray(int[] ar) {
for(int n: ar){
System.out.print(n+" ");
}
System.out.println("");
}
}
Input (stdin) 6 1 4 3 5 6 2
Your Output (stdout) 1 4 3 5 6 2 1 3 4 5 6 2 1 3 4 5 6 2 1 3 4 5 6 2 1 3 4 5 2 6
Expected Output 1 4 3 5 6 2 1 3 4 5 6 2 1 3 4 5 6 2 1 3 4 5 6 2 1 2 3 4 5 6 Compiler Message Wrong Answer
You are doing it in wrong way. Read the part 1 again.
Assume that first element is sorted. Then try to insert element one by one in sorted list.
Try this:
public static void insertionSortPart2(int[] ar) {
int key;
int seen;
for (int i = 1 ; i < ar.length; i++){
key = ar[i];
seen = i;
while (seen > 0 && ar[seen-1] > key) {
ar[seen] = ar[seen-1];
seen = seen - 1;
}
ar[seen]=key;
printArray(ar);
}
}
Im trying to take a number and print it's odd number like this:
if i take 5 as a number it should give this:
1 3 5
3 5
5
and if i take 9 it should do the same thing:
1 3 5 7 9
3 5 7 9
5 7 9
7 9
9
This is what i have so far and i am stuck. i can't get the 5 to print after the 3 and to end it with 5 for the triangle:
public class first{
static void afficher(int a){
for(int i=1;i<=a;i++){
if(i%2!=0){
System.out.printf("%d",i);
}
}
System.out.println();
for(int j=3;j<=a-2;j++){
if(j%2!=0){
System.out.printf("%d",j);
}
}
}
public static void main(String[]args){
afficher(5);
}
}
This prints:
1 3 5
3
If you print a surface (2d thus), one expects that the algorithm runs in O(n^2) time complexity. Thus two nested fors:
public class first{
static void afficher(int a){
for(int i = 1; i <= a; i += 2) {
for(int j = i; j <= a; j += 2){
System.out.print(j);
System.out.print(' ');
}
System.out.println();
}
}
}
One can optimize the algorithm a bit by not checking if the number is odd, but taking steps of 2.
See demo.
You have to use nested for-loops to resolve this problem. Go through the following code
public class OddNumberLoop {
public static void main(String[] args) {
Scanner inpupt = new Scanner(System.in);
System.out.print("Input the starting number : ");
int start = inpupt.nextInt();
for(int i = 1 ; i <= start; i += 2){
for(int x = i; x <= start; x += 2) System.out.print(x+ " ");
System.out.println();
}
}
}
The reason it is printing as follows because:
1 3 5 -> your i loop runs here (from 1 to 5)
3 -> your j loop runs here (from 3 to (less than OR equal to 5))
So I suggest the following:
Use 2 nested loops (for universal values):
i running from 1 to the input number increasing by 2
j running from i to the input number increasing by 2 also ending with line change'/n'
Keep a check whether the input number is odd or not.
For the following question I implemented both recursive and recursive dynamic solution, however I am interested in an iterative solution ( not recursive). Can anyone help me with that?
Question:
A cat is jumping up a staircase with n steps, and can hop either 1 step, 2 steps, or 3 steps at a
time. Implement a method to count how many possible ways the cat can jump up the stairs.
For iterative solution what I know is that we essentially have to count the leaves of the trinary tree below with value 0
Dynamic and recursive solutions:
import java.util.ArrayList;
public class Question1 {
public static int countAndDisply(int n, ArrayList<Integer> hop) {
if (n<0){
return 0;
}else{
if (n==0) {
for(int i:hop){
System.out.print(i+",");
}
System.out.println();
return 1;
}else{
ArrayList<Integer> hop1 = new ArrayList<>(hop);
hop1.add(1);
ArrayList<Integer> hop2 = new ArrayList<>(hop);
hop2.add(2);
ArrayList<Integer> hop3 = new ArrayList<>(hop);
hop3.add(3);
return countAndDisply(n-1, hop1)+countAndDisply(n-2, hop2)+countAndDisply(n-3, hop3);
}
}
}
/**
* Faster by using dynamic programming techniques to improve speed
* We dont want to calculate the count(n) multiple times!
* #param n
* #param path
* #return
*/
public static int countFast(int n, int[] map){
if (n<0){
return 0;
}else{
if (n==0) {
return 1;
}else{
if (map[n]>0){
return map[n];
}else {
return countFast(n-1, map) + countFast(n-2, map) + countFast(n-3, map);
}
}
}
}
public static int count(int n){
if (n<0){
return 0;
}else{
if (n==0) {
return 1;
}else{
return count(n-1) + count(n-2) + count(n-3);
}
}
}
public static void main(String[] args) {
int n=10;
int [] map = new int[n+1];
long startTime = System.nanoTime();
System.out.println("Total number of possiblilities:"+Question1.countFast(n,map));
long totalTime = System.nanoTime()-startTime;
System.out.println("Time needed for dynamic recursive approach was(ns):"+totalTime);
//System.out.println("Total number of possiblilities:"+Question1.AndDisply(n,new ArrayList<Integer>()));
System.out.println("Total number of possiblilities:"+Question1.count(n));
totalTime = System.nanoTime()-startTime;
System.out.println("Time needed for pure recursive was(ns):"+totalTime);
}
}
and here are outputs:
Total number of possiblilities:274
Time needed for dynamic recursive approach was(ns):249311
Total number of possiblilities:274
Time needed for pure recursive was(ns):351088
If you want to do it iterative, the best way is to start from 0, not from n.
An example:
i i-1 i-2 i-3 sum
0 || -1 -2 -3 | 0 # does not contain any solution
1 || 0 -1 -2 | 1 # contains one solution (0)
2 || 1 0 -1 | 2 # contains two solutions (0,1) - (-1,-2)
3 || 2 1 0 | 4 # contains three solutions(0,1,2)
# 2 (2) ,1(1) +1 (0) => 2+1+1 = 4
4 || 3 2 1 | 7 # 3 (4) ,2(2) 1 (1) => 4+2+1 = 7
5 || 4 3 2 | 13 # and so on
6 || 5 4 3 | 24
7 || 6 5 4 | 44
8 || 7 6 5 | 81
9 || 8 7 6 | 149
10 || 9 8 7 | 274
The code is extremely simple:
public static int solve(int n) {
int[] map=new int[n+1];
map[0]=1;
map[1]=1;
map[2]=2;
for (int i = 3; i < map.length; i++) {
map[i]+=map[i-1];
map[i]+=map[i-2];
map[i]+=map[i-3];
}
return map[n];
}
And much faster, of course.
I ran into a StackOverflowError when running a solution I wrote to an assignment.
These are the exact instructions from the book Java Methods: A & AB:
Write a program in which Cookie Monster finds the optimal path from the upper left corner (0,0) to the lower right corner(SIZE-1,SIZE-1) in a cookie grid (a 2-D array). The elements of the grid contain cookies (a non-negative number) or barrels (-1). On each step, Cookie Monster can only go down or to the right. He is not allowed to step on barrels. The optimal path contains the largest number of cookies.
The program reads the cookie grid from a file and reports the number of cookies on the optimal path. (The path itself is not reported.) A sample data file is provided in JM\Ch19\Exercises\cookies.dat.
Hint: Use a stack. If there is only one way to proceed from the current position, then go there and update the total accumulated number of cookies. If there are two ways to proceed, save one of the possible two points (and its total) on the stack and proceed to the other point. If you have reached the lower-right corner, update the maximum. If there is nowhere to go, examine the stack: pop a saved point, if any, and resume from there.
The goal is to give my teacher the best possible path (the one with the most "cookies" on it).
Okay. so the mentioned cookie map file is this:
1 3 0 5 -1 7 -1 -1 0 4 2 1
-1 3 2 1 -1 4 -1 5 3 -1 1 0
5 4 8 -1 3 2 2 -1 4 -1 0 0
2 1 0 4 1 -1 8 0 2 -1 2 5
1 4 0 1 -1 0 3 2 2 4 1 4
0 1 4 1 1 6 1 4 5 2 1 0
3 2 5 2 0 7 -1 2 1 0 -1 3
0 -1 4 -1 -1 3 5 1 4 2 1 2
5 4 8 -1 3 2 2 -1 4 -1 0 0
2 1 0 4 1 -1 8 0 2 -1 2 5
1 3 0 5 -1 7 -1 -1 0 4 2 1
0 0 3 1 5 2 1 5 4 1 3 3
And this is the class I use to get a 2-D array of the numbers (I know this part works.) Using A BlueJ debugger, the 2-D array seems to be what I want it to be.
import java.util.*;
import java.io.*;
public class MapReader
{
public static int[][] grid;
public static Scanner gridscanner = null;
public static int[][] getMap()
{
File file = new File("cookies.dat");
try
{
gridscanner = new Scanner(file);
}
catch (FileNotFoundException ex)
{
System.out.println("*** Cannot open cookis.dat ***");
System.exit(1);
}
int row = 12;
grid = new int[row][row];
for(int r = 0; r < row; r++)
{
for(int c = 0; c < row; c++)
{
grid[r][c] = gridscanner.nextInt();
}
}
return grid;
}
}
And here is a class I use to keep track of saved positions, their values, and their locations for when I'm traversing this "cookie map":
import java.util.*;
public class Point
{
int row;
int col;
int total;
public Point(int r, int c, int t)
{
row = r;
col = c;
total = t;
}
public int getRow() { return row; }
public int getCol() { return col; }
public int getValue() { return MapReader.getMap()[row][col]; }
public int getTotal() { return total; }
}
And finally, here is the class that I use to recursively travel through the 2D array. You'll notice that I prefer to go right when two paths are available but then go down when I pop a Point from the "saved" Stack. The problem lies in this class as far as I know: How can I make the method end its recursion and reach a maximum?
import java.util.*;
public class CookieMonster
{
private static int[][] map = MapReader.getMap();
private static int max = 11;
private static int total, maximum;
private static Stack<Point> saved = new Stack<Point>();
public static void main(String[] args)
{
System.out.println(move(0,0));
}
public static int move(int r, int c)
{
int right = 0;
int down = 0;
boolean isright = true;
boolean isdown = true;
if (c < max)
{
right = map[r][c + 1];
}
else
isright = false;
if (r < max)
{
down = map[r + 1][c];
}
else
isdown = false;
if (right == -1)
isright = false;
if (down == -1)
isdown = false;
if (isright && isdown)
{
saved.push(new Point(r + 1, c, total + down));
total += right;
move(r, c + 1);
}
else if (isright)
{
total += right;
move(r, c + 1);
}
else if (isdown)
{
total += down;
move(r + 1, c);
}
else
{
if (r == max && c == max)
{
if (maximum < total)
maximum = total;
}
if (!saved.isEmpty())
{
Point sd = saved.pop();
total = sd.getTotal();
move(sd.getRow(), sd.getCol());
}
}
return maximum;
}
}
I know the hint suggests to use a stack, but this problem can be solved much more efficiently using dynamic programming. It is basically recursion with a memory of previously visited paths to avoid recomputation.
Assuming you index the matrix starting at 1, Your cost function should be as follows:
c(i, j) = -INF if i == 0 or j == 0 or data(i, j) < 0
data(1, 1) if i == 1 and j == 1
data(i, j) + min(c(i, j - 1), c(i - 1, j))
You can iterate in the usual nested i-j loop from left to right and up to down.
c(n, n) will give you the result of the optimal path.
This seems np-complete. Using a stack and writing the logic to return to a former path if you run into a dead-end seems like wasted effort. You are going to have to use a lot of brute force even with the stack and logic. It seems easier to just use a primitive to store the number of cookies and just write some logic to move down and right at random. If you hit a dead end, just throw that result out and start over. If you hit the end, save that value and check to see if it is larger than a previous path. It if it is, keep it until you find a larger one. If you run it enough times, you will find the best path. I can't imagine it would take more than a few seconds to find the most cookies.