I'm new at programming. I have to write a code, main requirements - user chooses the sorting method (one is already added, the second one I will add later), enters the amount of elements in the array, enters the elements and then the code sorts them. But it looks like the code only takes the last entered element and tries to sort it. What do I have to do to make it sort all entered elements?
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("181RDB094 Līva Gundega Ermansone 1");
System.out.print("method:");
int M;
if (sc.hasNextInt())
M = sc.nextInt();
else {
System.out.println("input-output error");
sc.close();
return;
}
System.out.print("count:");
int count = sc.nextInt();
int[] masīvs = new int[count];
System.out.println("items:");
masīvs = new int[count];
for (int i = 0; i < count; i++) {
masīvs[i] = sc.nextInt();
}
System.out.println("result:");
if (M == 1) {
int[] b = new int[count];
int[] less = new int[count];
int[] equal = new int[count];
int k;
for (int i = 0; i < count; i++)
for (int j = 0; j < count; j++) {
if (masīvs[i] == masīvs[j]) {
equal[i] = i++;
} else if (masīvs[i] > masīvs[j]) {
less[i] = i++;
}
}
for (int i = 0; i < count; i++) {
k = less[i];
for (int j = 0; j < equal[i]; j++) {
b[k + j] = masīvs[i];
}
}
for (int i = 0; i < count; i++) {
masīvs[i] = b[i];
System.out.print(masīvs[i] + " ");
}
} else if (M == 2) {
} else {
System.out.println("input-output error");
return;
}
}
Sorry for the ugly code, it's just a draft.
Expected:
181RDB094 Līva Gundega Ermansone 1
method:1
count:4
items:
13
31
55
2
result:
55 31 13 2
Actual results:
181RDB094 Līva Gundega Ermansone 1
method:1
count:4
items:
13
31
55
2
result:
2 2 2 0
You can add a simple for loop after filling your array to check the contents. There, you can see that all entries are written into the array correctly.
This will output:
Array:13
Array:31
Array:55
Array:2
for (int i = 0; i < masīvs.length; i++) {
System.out.println("Array:" + masīvs[i]);
}
The sorting method you are following fixes a set of equal elements at their proper position by finding the no of elements less than those elements.
The problem in sorting lies in finding the no of elements less and equal to.
equal[i]++; instead of equal[i]=i++;
Similarly,
less[i]++; instead of less[i]=i++;
If you're using Java 8 or more recent, you may be able to use the ArrayList class (with the Integer class) instead of an 1D array (i.e. int[] var = new int[x]); it would allow you to use its sort(Comparator) method instead.
You would have to create a Comparator instance (lambda function, or anonymous) or an implementing class, unless you want to use the natural ordering of those.
It would give you something around those two lines:
ArrayList<Integer> var = new ArrayList<>();
and var.sort(); (assuming you use the natural ordering)
It might however be harder to manipulate at first, if you're new to the Java Collection Framework, so don't hesitate to ask questions.
P.S.: I might have misunderstood the code, so just tell me so I can fix my answer.
P.S.S.: Somewhat unrelated, and it's probably in your mind (ignore that part then), but I would recommend you to refactor that into much more smaller methods/functions.
I think that your code organization is very bad. It's easier to give you more correct solution, than count and fix your problem:
public class Foo {
public static void main(String... args) {
final BiFunction<int[], Comparator<Integer>, int[]> sort =
(items, comparator) -> Arrays.stream(items)
.boxed()
.sorted(comparator)
.mapToInt(i -> i)
.toArray();
try (Scanner scan = new Scanner(System.in)) {
Comparator<Integer> comparator = getSortingMethod(scan);
int[] items = getItems(scan);
int[] sorted = sort.apply(items, comparator);
System.out.println(Arrays.toString(sorted));
}
}
private static final Comparator<Integer> SORT_ASC = Comparator.naturalOrder();
private static final Comparator<Integer> SORT_DESC = Comparator.reverseOrder();
private static final Comparator<Integer> SORT_NULL = (one, two) -> {
throw new IllegalArgumentException("input-output error");
};
private static Comparator<Integer> getSortingMethod(Scanner scan) {
System.out.println("181RDB094 Līva Gundega Ermansone 1");
System.out.print("method:");
try {
int M = scan.nextInt();
if (M == 1)
return SORT_DESC;
if (M == 2)
return SORT_ASC;
return SORT_NULL;
} catch(RuntimeException e) {
return SORT_NULL;
}
}
private static int[] getItems(Scanner scan) {
System.out.print("count:");
int[] items = new int[scan.nextInt()];
System.out.println("items:");
for (int i = 0; i < items.length; i++)
items[i] = scan.nextInt();
return items;
}
}
Related
Conditions of the 6-digit code:
None of the digits are 0
Each digit of the combination is different
The 6-digit number is divisible by each one of the digits
Input:
Two integers, L and H
L is the limit on the smallest number on the range
H is the limit on the largest number on the range
Output:
C, which defines the number of possible combinations where L<=c<=H
I thought I could use arrays as the condition check, then realized I couldn't use it to find the number of possible combinations. Tried using loops, but couldn't figure it out, all I got for the pseudocode is the input, then a condition if L is less or equal to H. Then I sort of ran to a brick wall.
Here's the code.
''''''''
public static void main(String[] args) {
Scanner FF = new Scanner(System.in);
List<Integer> result = new ArrayList<>();
int l = FF.nextInt();
int h = FF.nextInt();
for (int i = l; i <= h; i++) {
result.add(i);
}
for (int i=l; i<=h; i++){
if (result.get(i) == result.get(i)){
result.remove(i);
}
int temp = result.get(i);
while (result.get(i)>0){
int k = result.get(i)%10;
if (temp % k != 0){
result.remove(i);
}
}
if (String.valueOf(result.get(i)).contains("0")){
result.remove(i);
}
}
System.out.println(result);
}
}
You can create a stream of integers, here 111111 to 1000000 and then filter out everything what doesnot meet your conditions.
public class SixDigitCode {
public static void main(String[] args) {
IntStream.iterate(111111, i -> i < 1000000, i -> i + 1)
.filter(containsZero.negate())
.filter(digitDifferent)
.filter(divideByDigits)
.forEach(System.out::println);
}
static IntPredicate containsZero = i -> Integer.toString(i).contains("0");
static IntPredicate digitDifferent = i -> Integer.toString(i).chars().boxed().collect(Collectors.toSet()).size() == 6;
static IntPredicate divideByDigits = i -> Integer.toString(i).chars().boxed()
.filter( x -> i%Character.getNumericValue(x) ==0)
.count() ==6;
}
There are multiple ways to solve this problem.
Let's start with an easy, but inefficient one:
boolean isOk(int number){
String numberStr = Integer.toString(number);
if(numberStr.contains("0"))
return false;
for(int i = 0; i < numberStr.length(); i++){
for(int j = i + 1; j < numberStr.length(); j++){
if(numberStr.charAt(i) == numberStr.charAt(j))
return false;
}
}
return true;
}
...
int count = 0;
for(int i = L; i <= H; i++){
if(isOk(i))
count ++;
}
Note: this code is by no means optimal, but I think it is a straight forward easy to understand solution.
However, I cannot test it right now, so it may contain minor issues.
Let's say I have five int variables that are prompted for user input. User keys in the five value and two of those values are 0. I would like to ONLY print out values that are greater than zero.
int v1 = 1;
int v2 = 30;
int v3 = 0;
int v4 = 37;
int v5 = 0;
I would like to write a dynamic print statement that would exclude the int variables with Zero value.
Currently, my print statement displays all values:
System.out.printf("%s %d%n%s %d%n%s %d%n%s %d%n%s %d%n","V1;","v1","V2:","v2","V3:","v3","V4:","v4","V5:","v5");
I tried writing if-else statements but that became very cumbersome.
Create a new method printNonZeroVars(Integer... ints).
public static void main(String[] args) {
int v1 = 1;
int v2 = 30;
int v3 = 0;
int v4 = 37;
int v5 = 0;
printNonZeroVars(v1, v2, v3, v4, v5)
}
public void printNonZeroVars(int... ints) {
for (int i = 0; i < ints.length; i++) {
if (ints[i] > 0) {
System.out.printf("V%d%d%n", i, ints[i]);
}
}
}
I would use an array.
Iterate over the array and with an if you can check whether your current value is 0.
So a simple way of achieving this would be to use some sort of Array/List.
ArrayList<Integer> list = new ArrayList<Integer>()
// Or as pointed out by David a better way would be to declare the list as
List<Integer> list = new ArrayList<>();
list.add(5);
list.add(1);
list.add(0);
....
Once you have the list you can use a loop to loop through the list and do relevant checks - something like this
String str = "";
for(int i=0; i<list.size(); i++) {
if(list.get(i) == 0) {
continue;
}
str += "v"+i + ":" + Integer.toString(list.get(i));
}
System.out.println(str);
Its pseudo but should give you a good head start :)
okay so we basically have this question to answer, but I am very confused and don't know how to use recursion to get all possible combinations.. Please someone save me!
Write a public static method threadings, which takes an int n (representing the number of beads on each necklace) and a Set of Strings (representing the available bead colours; your code must not alter this Set),and returns a Set of ArrayLists of Strings, representing all the orders in which n beads of the given colours can be threaded. If n < 1, return a Set containing just one, empty, ArrayList.
Examples of correct behaviour:
• threadings(0, {red,green}) = {[]}
• threadings(1, {red,green}) = {[red],[green]}
• threadings(2, {red,green})
= {[red,red],[red,green],[green,red],[green,green]}
• threadings(3, {red}) = {[red,red,red]}
Hint: you will probably want threadings to call itself recursively, although
full marks are available for any correct method.
This is what I have written until now:
public static HashSet<ArrayList<String>> threadings (int n, Set<String> colours){
HashSet<ArrayList<String>> result= new HashSet<ArrayList<String>>();
ArrayList<String> inresult= new ArrayList<String>();
String[] col= new String[colours.size()];
if (n==0){
result.add(inresult);
return result;
}else{
}
}
Try this:
public static HashSet<ArrayList<String>> threadings (int n, Set<String> colours) {
List<String> colorsList = new ArrayList<>(colours);
ArrayList<String> resultList = new ArrayList<>();
HashSet<ArrayList<String>> result = new HashSet<ArrayList<String>>();
int carry;
int[] indices = new int[n];
do
{
for(int index : indices) {
resultList.add(colorsList.get(index));
}
result.add(resultList);
resultList = new ArrayList<>();
carry = 1;
for(int i = indices.length - 1; i >= 0; i--)
{
if(carry == 0)
break;
indices[i] += carry;
carry = 0;
if(indices[i] == colorsList.size())
{
carry = 1;
indices[i] = 0;
}
}
}
while(carry != 1);
return result;
}
As the title reads, I have been thinking about creating multiple nested loops that aim to achieve one purpose. Move two generated random numbers between 0-9 through each possible possition of an array.
For example, App generates first number (fNum) 1 and second number (sNum) 6. It then moves these numbers in the array which containts ABC. However firstNum and secondNum will need to also try all the possible combinations, so each one will need to be different with each loop.
-1ABC6
-A1BC6
-AB1C6
-ABC16
-ABC61
-AB6C1
-A6BC1
-6ABC1
-A6B1C
-A61BC
-A16BC
-A1B6C
-A1BC6
and so on...
I beleive the best way will be to create a method for generating a counter, which increments the numbers which I can call.
private int getNextNumber(int num) {
if (num == 0) {
return num;
} else {
num++;
}
if (num < 10) {
return num;
} else {
return -1;
}
}
Then I will need multiple nested loops... I have decided to go for several loops which will go infinitly.
while (j < maxlen) {
//J = 0 and maxlen = length of text so in this case 3 as it is ABC
//Add two numbers and check against answer
while (fNum != -1 || sNum != -1) {
//incrememnt numbers
fNum = getNextNumber(fNum);
System.out.println(fNum);
sNum = getNextNumber(sNum);
System.out.println(fNum);
}
String textIni = "ABC";
int lenOfText = textIni.length();
char[] split = textIni.toCharArray();
for (int i = 0; i < lenOfText; i++) {
//here it will look at the length of the Text and
//try the possible positions it could be at....
//maybe wiser to do a longer loop but I am not too sure
}
}
Since you don't need to store all possible combinations, we will save some memory using only O(n) storage with an iterative solution. I propose you a basic implementation but don't expect to use it on large arrays since it has a O(n³) complexity.
public static void generateCombinationsIterative(List<Integer> original, int fnum, int snum) {
int size = original.size();
for (int i=0 ; i<=size ; i++) {
List<Integer> tmp = new ArrayList<>(original);
tmp.add(i,fnum);
for (int j=0 ; j<=size + 1 ; j++) {
tmp.add(j,snum);
System.out.print(tmp + (i == size && j == size + 1 ? "" : ", "));
tmp.remove(j);
}
}
}
For your culture, here is an example of a recursive solution, which takes a lot of memory so don't use it if you don't need to generate the lists of results. Nevertheless, this is a more general solution that can deal with any number of elements to insert.
public static List<List<Integer>> generateCombinations(List<Integer> original, Deque<Integer> toAdd) {
if (toAdd.isEmpty()) {
List<List<Integer>> res = new ArrayList<>();
res.add(original);
return res;
}
int element = toAdd.pop();
List<List<Integer>> res = new LinkedList<>();
for (int i=0 ; i<=original.size() ; i++)
// you must make a copy of toAdd, otherwise each recursive call will perform
// a pop() on it and the result will be wrong
res.addAll(generateCombinations(insertAt(original,element,i),new LinkedList<>(toAdd)));
return res;
}
// a helper function for a clear code
public static List<Integer> insertAt(List<Integer> input, int element, int index) {
List<Integer> result = new ArrayList<>(input);
result.add(index,element);
return result;
}
Note that I did not use any array in order to benefit from dynamic data structures, however you can call the methods like this :
int[] arr = { 1,2,3 };
int fnum = 4, snum = 5;
generateCombinationsIterative(Arrays.asList(arr),fnum,snum);
generateCombinations(Arrays.asList(arr),new LinkedList<>(Arrays.asList(fnum,snum));
Note that both methods generate the combinations in the same order.
I've just been looking at the following piece of code
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(final String[] args) {
final int sizeA = 3;
final int sizeB = 5;
final List<int[]> combos = getAllCombinations(sizeA-1, sizeB);
int counter = 1;
for(final int[] combo : combos) {
System.out.println("Combination " + counter);
System.out.println("--------------");
for(final int value : combo) {
System.out.print(value + " ");
}
System.out.println();
System.out.println();
++counter;
}
}
private static List<int[]> getAllCombinations(final int maxIndex, final int size) {
if(maxIndex >= size)
throw new IllegalArgumentException("The maximum index must be smaller than the array size.");
final List<int[]> result = new ArrayList<int[]>();
if(maxIndex == 0) {
final int[] array = new int[size];
Arrays.fill(array, maxIndex);
result.add(array);
return result;
}
//We'll create one array for every time the maxIndex can occur while allowing
//every other index to appear, then create every variation on that array
//by having every possible head generated recursively
for(int i = 1; i < size - maxIndex + 1; ++i) {
//Generating every possible head for the array
final List<int[]> heads = getAllCombinations(maxIndex - 1, size - i);
//Combining every head with the tail
for(final int[] head : heads) {
final int[] array = new int[size];
System.arraycopy(head, 0, array, 0, head.length);
//Filling the tail of the array with i maxIndex values
for(int j = 1; j <= i; ++j)
array[size - j] = maxIndex;
result.add(array);
}
}
return result;
}
}
I'm wondering, how do I eliminate recursion from this, so that it returns a single random combination, rather than a list of all possible combinations?
Thanks
If I understand your code correctly your task is as follows: give a random combination of numbers '0' .. 'sizeA-1' of length sizeB where
the combination is sorted
each number occurs at least once
i.e. in your example e.g. [0,0,1,2,2].
If you want to have a single combination only I'd suggest another algorithm (pseudo-code):
Randomly choose the step-up positions (e.g. for sequence [0,0,1,1,2] it would be steps (1->2) & (3->4)) - we need sizeA-1 steps randomly chosen at sizeB-1 positions.
Calculate your target combination out of this vector
A quick-and-dirty implementation in java looks like follows
// Generate list 0,1,2,...,sizeB-2 of possible step-positions
List<Integer> steps = new ArrayList<Integer>();
for (int h = 0; h < sizeB-1; h++) {
steps.add(h);
}
// Randomly choose sizeA-1 elements
Collections.shuffle(steps);
steps = steps.subList(0, sizeA - 1);
Collections.sort(steps);
// Build result array
int[] result = new int[sizeB];
for (int h = 0, o = 0; h < sizeB; h++) {
result[h] = o;
if (o < steps.size() && steps.get(o) == h) {
o++;
}
}
Note: this can be optimized further - the first step generates a random permutation and later strips this down to desired size. Therefore it is just for demonstration purpose that the algorithm itself works as desired.
This appears to be homework. Without giving you code, here's an idea. Call getAllCombinations, store the result in a List, and return a value from a random index in that list. As Howard pointed out in his comment to your question, eliminating recursion, and returning a random combination are separate tasks.