I'm trying to show all combinations possible without using recursion.
I was trying it with a loop but it isn't working.
Without recursion(Not Working):
import java.util.Arrays;
public class Combination {
public static void main(String[] args) {
String[] arr = {"A","B","C","D","E","F"};
String[] result = new String[3];
int i = 0, len = 3;
while(len != 0 || i <= arr.length-len)
{
result[result.length - len] = arr[i];
len--;
i++;
}
if (len == 0){
System.out.println(Arrays.toString(result));
return;
}
}
}
With recursion(Working):
import java.util.Arrays;
public class Combination {
public static void main(String[] args){
String[] arr = {"A","B","C","D","E","F"};
combinations2(arr, 3, 0, new String[3]);
}
static void combinations2(String[] arr, int len, int startPosition, String[] result){
if (len == 0){
System.out.println(Arrays.toString(result));
return;
}
for (int i = startPosition; i <= arr.length-len; i++){
result[result.length - len] = arr[i];
combinations2(arr, len-1, i+1, result);
}
}
}
What am I doing wrong?
It is not clear what is the answer you are trying to get. The question should be set with example data to specify exactly what is it that you want to get. Given the part of the program you provided. I guess what you are looking for is all possible subsets.
the following code will get you all the possible subsets. You can easily modify this program to give you all possible subsets of a specific size (Try it to make sure you understand how it works).
static void subsets(String[]arr) {
int len = arr.length;
for (int i = 0; i < (1 << len); i++) { // 1 << len means 2 ^ len there are 2 ^ n subsets for a set of size n
/*
* We will use the bits of the integer i to represent which elements are taken
* a bit of value 1 means this element is included in the current subset
* a bit of value 0 means that we do not take the element in the given position
*/
String res = "[";
for(int j = 0; j < len; j++) { //loop over the bits of i from 0 to len -1
if ( (i & (1 << j)) != 0) {
//the jth bit is 1 in the integer i as such the jth
//element is taken in the current subset
res += (arr[j]+", ");
}
}
res += "]";
int lastCommaPosition = res.lastIndexOf(',');
if (res.lastIndexOf(',') != -1) { // a comma exists
res = res.substring(0, lastCommaPosition)+ "]";//remove the extra comma and space
}
System.out.println(res);
}
}
You can modify the method above to take an integer size for example, count the number of bits of value 1 (the number of elements taken) if this count is equal to the size you print it otherwise you don't. Feel free to modify the question if this is not the answer you wanted or ask in the comments if there is something you don't understand.
Here is how you can get the exact output without recursion. I am using for loops though:
for(int i = 0; i < arr.length - 2; i ++) {
for(int j = i + 1; j < arr.length - 1; j++ ) {
for(int k = j + 1; k < arr.length ; k++ ) {
System.out.println(arr[i] + ", " + arr[j] + ", " + arr[k]);
}
}
}
Related
Note-You can not use Collection or Map
I have tried this but this is not having complexity O(n)
class RepeatElement
{
void printRepeating(int arr[], int size)
{
int i, j;
System.out.println("Repeated Elements are :");
for (i = 0; i < size; i++)
{
for (j = i + 1; j < size; j++)
{
if (arr[i] == arr[j])
System.out.print(arr[i] + " ");
}
}
}
public static void main(String[] args)
{
RepeatElement repeat = new RepeatElement();
int arr[] = {4, 2, 4, 5, 2, 3, 1};
int arr_size = arr.length;
repeat.printRepeating(arr, arr_size);
}
}
Is any one having solution for solving,to find a duplicate array without using Collection or Map and using only single for loop
If the elements in an array with size n are in a range of 0 ~ n-1 ( or 1 ~ n).
We can try to sort the array by putting a[i] to index i for every a[i] != i, and if we find that there is already an a[i] at index i, it means that there is another element with value a[i].
for (int i = 0; i < a.length; i++){
while (a[i] != i) {
if (a[i] == a[a[i]]) {
System.out.print(a[i]);
break;
} else {
int temp = a[i]; // Putting a[i] to index i by swapping them
a[i] = a[a[i]];
a[temp] = temp;
}
}
}
Since after every swap, one of the elements will be in the right position, so there will be at most n swap operations.
Time complexity O(n)
Space complexity O(1)
As these are ints, you could use a BitSet:
void printRepeating(int arr[], int size) {
BitSet bits = new BitSet();
BitSet repeated = new BitSet();
//to deal with negative ints:
BitSet negativeBits = new BitSet();
BitSet negativeRepeatedBits = new BitSet();
for(int i : arr) {
if(i<0) {
i = -i; //use the absolute value
if(negativeBits.get(i)) {
//this is a repeat
negativeRepeatedBits.set(i);
}
negativeBits.set(i);
} else {
if(bits.get(i)) {
//this is a repeat
repeated.set(i);
}
bits.set(i);
}
}
System.out.println(
IntStream.concat(negativeRepeatedBits.stream().map(i -> -i), repeated.stream())
.mapToObj(String::valueOf)
.collect(Collectors.joining(", ", "Repated Elements are : ", ""))
);
}
Note that (as per comment) negative values need to be treated separately, as otherwise you could be faced with IndexOutOfBoundsException.
Ok, so you have a constant memory requirement for an array of type int?
No problem, just let's use a large (but constant) byte array:
byte[] seen = new byte[536870912];
byte[] dups = new byte[536870912];
for (int i : arr) {
int idx = i / 8 + 268435456;
int mask = 1 << (i % 8);
if ((seen[idx] & mask) != 0) {
if ((dups[idx] & mask) == 0) {
System.out.print(i + " ");
dups[idx] |= mask;
}
} else {
seen[idx] |= mask;
}
}
As we only iterate once over the array, we have a time complexity of O(n) (where n is the number of elements in the array).
And because we always use the same amount of space we have a memory complexity of O(1), that is independent of anything.
Just one for loop, i will increment when j is at the end of the array, the current arr[i] is found earlier of a new duplicate element is found
void printRepeatingSingleLoop(int arr[], int size)
{
int i, j, k;
System.out.println("Repeated Elements are :");
for (i = 0, j = 1, k = 0; i < size; )
{
if (k < i ) {
if (arr[i] == arr[k]) {
i++;
j = i+1;
k = 0;
} else {
k++;
}
} else {
if (j == size) {
i++;
j = i + 1;
k = 0;
} else {
if (arr[i] == arr[j]) {
System.out.print(arr[i] + " ");
i++;
j = i + 1;
k = 0;
} else {
j++;
}
}
}
}
System.out.println();
}
For this particular problem I am attempting to remove redundant elements in an sorted array and replace them all with 0s at the end of the array. For example, if I had an array consisting of the int elements
1,3,3,4,4,5,6,6,7
My output array should be
1,3,4,5,6,7,0,0,0
My first attempt at the problem was to create a swapper in order to push all the 0s to the end of the list after removing the elements, but it won't seem to push the zeros to the end of the list. Here is my code.
public void implode(int[] ary)
{
int swapper = -1;
int[] newARY = new int[ary.length];
int current = -1;
for (int i = 0; i < ary.length; i++)
{
if (current != ary[i])
{
newARY[i] = ary[i];
current = ary[i];
}
}
for (int i = 0; i < ary.length; i++)
{
if (ary[i] == 0)
{
if (ary[i + 1] != 0)
{
swapper = ary[i + 1];
ary[i] = swapper;
ary[i + 1] = 0;
}
}
}
ary = newARY;
for (int i = 0; i < newARY.length; i++)
{
System.out.print(newARY[i] + " ");
}
}
The array im testing it with is,
int[] aryIn2 = {1, 1, 2, 3, 4, 4, 5, 6};
However, when outputting the imploded array, I receive this one.
1 0 2 3 4 0 5 6
Is there something I am missing?
Thanks in advance.
not an answer to your problem, but using (if possible) java streams can shorten your way:
int[] arr = {1,3,3,4,4,5,6,6,7};
// distinct
List<Integer> list = Arrays.stream(arr).distinct().boxed().collect(Collectors.toList());
// pad with zero's
while(list.size() < arr.length) {
list.add(0);
}
// display
System.out.println(list.stream().map(String::valueOf).collect(Collectors.joining(",")));
will output
1,3,4,5,6,7,0,0,0
Two issue with you code that I observed.
1) Your swapper logic is performing swapping on a different array than the one in which you had done modification earlier
2) You need to have this logic in a bubble-sort way, i.e. loop inside a loop
Below is a working modified sample code of your method. I have modified only the second for-loop logic
public void implode(int[] ary) {
int swapper = -1;
int[] newARY = new int[ary.length];
int current = -1;
for (int i = 0; i < ary.length; i++) {
if (current != ary[i]) {
newARY[i] = ary[i];
current = ary[i];
}
}
for (int i = 0; i < newARY.length - 1; i++) {
if (newARY[i] == 0 && newARY[i + 1] != 0) {
for (int j = i; (j + 1) < newARY.length; j++) {
swapper = newARY[j + 1];
newARY[j] = swapper;
newARY[j + 1] = 0;
}
}
}
for (int i = 0; i < newARY.length; i++) {
System.out.print(newARY[i] + " ");
}
}
In this first loop:
for (int i = 0; i < ary.length; i++) {
if (current != ary[i]) {
newARY[i] = ary[i];
current = ary[i];
}
}
You fill newARY with elements in ary with duplicated value turns to 0:
newARY: 1 0 2 3 4 0 5 6
However, in the second loop:
for (int i = 0; i < ary.length; i++)
{
if (ary[i] == 0)
{
if (ary[i + 1] != 0)
{
swapper = ary[i + 1];
ary[i] = swapper;
ary[i + 1] = 0;
}
}
}
You're modifying your original ary array. So the newARY is not updated.
However, your attempt to push 0 to the end of array also fail if there are more than two 0s consecutive. And it is also vulnerable to ArrayOutOfBoundIndexException since you try to read ary[i+1] without restriction on i
One simple and straight forward way to push 0s to the end of the array is to create new array with non-0s elements and fill 0s later:
int[] result = new int[ary.lenght];
int resultIndex = 0;
for (int i = 0; i < newARY.length; i++) {
if (newARY[i] != 0) {
result[resultIndex++] = newAry[i];
}
}
for (int i = resultIndex; i < newARY.length; i++) {
result[i] = 0;
}
// Print result array
Hint: Using above strategy, you can simplify your code. No need to create immediate array newARY. Just loop over the original array, push unique elements to the result array, then fill any slot left with 0s.
I want only one loop to archive this output
input={1,2,3,4,5,6,7,8,9} output={1,3,5,7,9,8,6,4,2}
public static void printOddEven(int[] arr) {
int newArray[] = new int[10];
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 != 0) {
newArray[i] = arr[i];
System.out.print(newArray[i] + " ");
}
}
for (int i = arr.length - 1; i > 0; i--) {
if (arr[i] % 2 == 0) {
newArray[i] = arr[i];
System.out.print(newArray[i] + " ");
}
}
}
If you want to use an array:
int [] result = new int[arr.length];
int counterFront = 0;
int counterBack = arr.length - 1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 != 0) {
result[counterFront++] = arr[i];
}
if (arr[i] % 2 == 0) {
result[counterBack--] = arr[i];
}
}
return result;
EDIT: Thanks to a comment, found out it had a ArrayIndexOutOfBounds.
int newArray[] = new int[9];
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 != 0)
newArray[i/2] = arr[i];
else
newArray[8-(i/2)] = arr[i];
}
System.out.println (java.util.Arrays.toString (newArray));
Just use a descendant index from the right
Why do you use Arrays at all? Is it homework? Note that you get an off-by-one-error, because your newArray is too large, when using int[10] for 9 elements, a typical problem with Arrays.
I reckon this is more of a maths problem than a programming problem. It's about knowing there is a simple arithmetic relationship between an incrementing index and a decrementing index.
int[] arr = {1,2,3,4,5,6,7,8,9};
public static void printOddEven(int[] arr) {
int[] odds = new int[5]; // arr.length == 9
int[] even = new int[4];
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
// This is where the magic happens
// It is filling the array from the back
even[even.length - (i / 2) - 1] = arr[i];
} else {
odds[(i / 2)] = arr[i];
}
}
System.out.println(java.util.Arrays.toString(odds));
System.out.println(java.util.Arrays.toString(even));
}
EDIT:
Just for #CoderinoJavarino, here is a version where the output is a single array. The core logic and maths is identical, so take your pick which is easier to understand.
The use of Arrays.toString() is not there as part of the algorithm solution. It is there simply so that you can see the output. I could equally send the output to a file, or to a web socket.
The output is not the printing, the output is the array or arrays. It could equally have been a List, or a special class just for sorting odd/even numbers. Who cares?
In industrial programming (ie, non-academic) this is how code gets divided up: for ease of understanding, not cleverness. And in the business world there is no concept of "cheating": Nobody worries about the internals of, say, a JSP, rendering your array to a browser.
int[] arr = {1,2,3,4,5,6,7,8,9};
public static int[] SORTOddEven(int[] arr) {
int[] output = new int[arr.length]; // arr.length == 9
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
// This is where the magic happens
// It is filling the array from the back
output[output.length - (i / 2) - 1] = arr[i];
} else {
output[(i / 2)] = arr[i];
}
}
return output;
}
System.out.println(java.util.Arrays.toString(SORTOddEven(arr)));
public static void printOddEven(int[] arr) {
int newArray[] = new int[9];
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 != 0)
newArray[i/2] = arr[i];
else
newArray[arr.length - i/2 - 1] = arr[i];
}
System.out.println(java.util.Arrays.toString(newArray));
}
Live on Ideone.
This only works for 123456789 to print 135798642:
public class Sample {
public static void main(String[] args) throws Exception {
int j=0;
int p=2;
int newArray[]= {1,2,3,4,5,6,7,8,9};
for(int i=0;i<=newArray.length-1;i++)
{
if(i<=4)
{
System.out.print(newArray[i]+j);
j++;
}
else
{
System.err.print(newArray[i]+p);
p=p-3;
}
}
}
}
I need for homework to get the most "popular" number in an array (the number in the highest frequency), and if there are several numbers with the same number of shows, get some number randomly.
After more then three hours of trying, and either searching the web, this is what I got:
public int getPopularNumber(){
int count = 1, tempCount;
int popular = array[0];
int temp = 0;
for ( int i = 0; i < (array.length - 1); i++ ){
if ( _buses[i] != null )
temp = array[i];
tempCount = 0;
for ( int j = 1; j < _buses.length; j++ ){
if ( array[j] != null && temp == array[j] )
tempCount++;
}
if ( tempCount > count ){
popular = temp;
count = tempCount;
}
}
return popular;
}
This code work, but don't take into account an important case- if there is more than one number with the same count of shows. Then it just get the first one.
for example: int[]a = {1, 2, 3, 4, 4, ,5 ,4 ,5 ,5}; The code will grab 4 since it shown first, and it's not random as it should be.
Another thing- since it's homework I can't use ArrayList/maps and stuff that we still didn't learn.
Any help would be appreciated.
Since they didn't give you any time complexity boundary, you can "brute force" the problem by scanning the the array N^2 times. (disclaimer, this is the most intuitive way of doing it, not the fastest or the most efficient in terms of memory and cpu).
Here is some psuedo-code:
Create another array with the same size as the original array, this will be the "occurrence array"
Zero its elements
For each index i in the original array, iterate the original array, and increment the element in the occurrence array at i each time the scan finds duplicates of the value stored in i in the original array.
Find the maximum in the occurrence array
Return the value stored in that index in the original array
This way you mimic the use of maps with just another array.
If you are not allowed to use collection then you can try below code :
public int getPopularNumber(){
int inputArr[] = {1, 2, 3, 4, 4, 5 ,4 ,5 ,5}; // given input array
int[] tempArr = new int[inputArr.length];
int[] maxValArr = new int[inputArr.length];
// tempArr will have number as index and count as no of occurrence
for( int i = 0 ; i < inputArr.length ; i++){
tempArr[inputArr[i]]++;
}
int maValue = 0;
// find out max count of occurrence (in this case 3 for value 4 and 5)
for( int j = 0 ; j < tempArr.length ; j++){
maValue = Math.max(maValue, tempArr[j]);
}
int l =0;
// maxValArr contains all value having maximum occurrence (in this case 4 and 5)
for( int k = 0 ; k < tempArr.length ; k++){
if(tempArr[k] == maValue){
maxValArr[l] = k;
l++;
}
}
return maxValArr[(int)(Math.random() * getArraySize(maxValArr))];
}
private int getArraySize(int[] arr) {
int size = 0;
for( int i =0; i < arr.length ; i++){
if(arr[i] == 0){
break;
}
size++;
}
return size;
}
that's hard as hell :D
After some trying, I guess I have it (If there will be 2 numbers with same frequency, it will return first found):
int mostPopNumber =0;
int tmpLastCount =0;
for (int i = 0; i < array.length-1; i++) {
int tmpActual = array[i];
int tmpCount=0;
for (int j = 0; j < array.length; j++) {
if(tmpActual == array[j]){
tmpCount++;
}
}
// >= for the last one
if(tmpCount > tmpLastCount){
tmpLastCount = tmpCount;
mostPopNumber = tmpActual;
}
}
return mostPopNumber;
--
Hah your code give me idea- you cant just remember last most popular number, btw I've found it solved there Find the most popular element in int[] array
:)
EDIT- after many, and many years :D, that works well :)
I've used 2D int and Integer array - you can also use just int array, but you will have to make more length array and copy actual values, Integer has default value null, so that's faster
Enjoy
public static void main(String[] args) {
//income array
int[] array= {1,1,1,1,50,10,20,20,2,2,2,2,20,20};
//associated unique numbers with frequency
int[][] uniQFreqArr = getUniqValues(array);
//print uniq numbers with it's frequency
for (int i = 0; i < uniQFreqArr.length; i++) {
System.out.println("Number: " + uniQFreqArr[i][0] + " found : " + uniQFreqArr[i][1]);
}
//get just most frequency founded numbers
int[][] maxFreqArray = getMaxFreqArray(uniQFreqArr);
//print just most frequency founded numbers
System.out.println("Most freq. values");
for (int i = 0; i < maxFreqArray.length; i++) {
System.out.println("Number: " + maxFreqArray[i][0] + " found : " + maxFreqArray[i][1]);
}
//get some of found values and print
int[] result = getRandomResult(maxFreqArray);
System.out.println("Found most frequency number: " + result[0] + " with count: " + result[1]);
}
//get associated array with unique numbers and it's frequency
static int[][] getUniqValues(int[] inArray){
//first time sort array
Arrays.sort(inArray);
//default value is null, not zero as in int (used bellow)
Integer[][] uniqArr = new Integer[inArray.length][2];
//counter and temp variable
int currUniqNumbers=1;
int actualNum = inArray[currUniqNumbers-1];
uniqArr[currUniqNumbers-1][0]=currUniqNumbers;
uniqArr[currUniqNumbers-1][1]=1;
for (int i = 1; i < inArray.length; i++) {
if(actualNum != inArray[i]){
uniqArr[currUniqNumbers][0]=inArray[i];
uniqArr[currUniqNumbers][1]=1;
actualNum = inArray[i];
currUniqNumbers++;
}else{
uniqArr[currUniqNumbers-1][1]++;
}
}
//get correctly lengthed array
int[][] ret = new int[currUniqNumbers][2];
for (int i = 0; i < uniqArr.length; i++) {
if(uniqArr[i][0] != null){
ret[i][0] = uniqArr[i][0];
ret[i][1] = uniqArr[i][1];
}else{
break;
}
}
return ret;
}
//found and return most frequency numbers
static int[][] getMaxFreqArray(int[][] inArray){
int maxFreq =0;
int foundedMaxValues = 0;
//filter- used sorted array, so you can decision about actual and next value from array
for (int i = 0; i < inArray.length; i++) {
if(inArray[i][1] > maxFreq){
maxFreq = inArray[i][1];
foundedMaxValues=1;
}else if(inArray[i][1] == maxFreq){
foundedMaxValues++;
}
}
//and again copy to correctly lengthed array
int[][] mostFreqArr = new int[foundedMaxValues][2];
int inArr= 0;
for (int i = 0; i < inArray.length; i++) {
if(inArray[i][1] == maxFreq){
mostFreqArr[inArr][0] = inArray[i][0];
mostFreqArr[inArr][1] = inArray[i][1];
inArr++;
}
}
return mostFreqArr;
}
//generate number from interval and get result value and it's frequency
static int[] getRandomResult(int[][] inArray){
int[]ret=new int[2];
int random = new Random().nextInt(inArray.length);
ret[0] = inArray[random][0];
ret[1] = inArray[random][1];
return ret;
}
I have to write a program to accept a String as input, and as output I'll have to print each and every alphabetical letter, and how many times each occurred in the user input. There are some constraints:
I cannot use built-in functions and collection
The printed result should be sorted by occurrence-value.
For example, with this input:
abbbccccdddddzz
I would expect this output:
a-1,z-2,b-3,c-4,d-5
This is what I have so far:
public static void isCountChar(String s) {
char c1[] = s.toCharArray();
int c3[] = new int[26];
for (int i = 0; i < c1.length; i++) {
char c = s.charAt(i);
c3[c - 'a']++;
}
for (int j = 0; j < c3.length; j++) {
if (c3[j] != 0) {
char c = (char) (j + 'a');
System.out.println("character is:" + c + " " + "count is: " + c3[j]);
}
}
}
But I don't know how to sort.
First of all a tip for your next question: The things you've stated in your comments would fit better as an edit to your question. Try to clearly state what the current result is, and what the expected result should be.
That being said, it was an interesting problem, because of the two constraints.
First of all you weren't allowed to use libraries or collections. If this wasn't a constraint I would have suggested a HashMap with character as keys, and int as values, and then the sorting would be easy.
Second constraint was to order by value. Most people here suggested a sorting like BubbleSort which I agree with, but it wouldn't work with your current code because it would sort by alphabetic character instead of output value.
With these two constraints it is probably best to fake key-value pairing yourself by making both an keys-array and values-array, and sort them both at the same time (with something like a BubbleSort-algorithm). Here is the code:
private static final int ALPHABET_SIZE = 26;
public static void isCountChar(String s)
{
// Convert input String to char-array (and uppercase to lowercase)
char[] array = s.toLowerCase().toCharArray();
// Fill the keys-array with the alphabet
char[] keys = new char[ALPHABET_SIZE];
for (int i = 0; i < ALPHABET_SIZE; i++)
{
keys[i] = (char)('a' + i);
}
// Count how much each char occurs in the input String
int[] values = new int[ALPHABET_SIZE];
for (char c : array)
{
values[c - 'a']++;
}
// Sort both the keys and values so the indexes stay the same
bubbleSort(keys, values);
// Print the output:
for (int j = 0; j < ALPHABET_SIZE; j++)
{
if (values[j] != 0)
{
System.out.println("character is: " + keys[j] + "; count is: " + values[j]);
}
}
}
private static void bubbleSort(char[] keys, int[] values)
{
// BUBBLESORT (copied from http://www.java-examples.com/java-bubble-sort-example and modified)
int n = values.length;
for(int i = 0; i < n; i++){
for(int j = 1; j < (n - i); j++){
if(values[j-1] > values[j]){
// Swap the elements:
int tempValue = values[j - 1];
values[j - 1] = values[j];
values[j] = tempValue;
char tempKey = keys[j - 1];
keys[j - 1] = keys[j];
keys[j] = tempKey;
}
}
}
}
Example usage:
public static void main (String[] args) throws java.lang.Exception
{
isCountChar("TestString");
}
Output:
character is: e; count is: 1
character is: g; count is: 1
character is: i; count is: 1
character is: n; count is: 1
character is: r; count is: 1
character is: s; count is: 2
character is: t; count is: 3
Here is a working ideone to see the input and output.
some sort: easy if not easiest to understand an coding
You loop from the first element to the end -1 : element K
compare element K and element K+1: if element K>element K+1, invert them
continue loop
if you made one change redo that !