Sorting Order and Finding repeating patterns - java

//other arrays sequences sample
{23,45,38, 9,43,25,18}
{21,33,22, 5, 1,44,16}
{28,24, 5,42,15,49,41}
{43,18,50,29,22,32,25}
{33,38,27,35,25, 1,12}
{21,33,22, 5, 1,44,16}
{28,24, 5,42,15,49,41}
I have a little project where i have a list of sequences and i would like to have them rearranged from small to large and reprinted for use to find repeating sequences and show how many time each sequence repeats
Now I wrote a small code sorting the sequences from small to large with the aid of a friend in order to solve the first problem.
But I would like it to work with multiple sets and arrange each set and print them on there own line, In order for me to find the repeating patterns
Yet every time i change the {int} to accommodate more sequences the code fails
public class Main {
public static void main(String args[]) {
int x[] = {37, 36, 20, 23, 44, 27, 24};
for (int y = 0; y <= x.length; y++) {
for (int z = 0; z <= x.length - 2; z++) {
if (x[z] > x[z + 1]) {
int temp = 0;
temp = x[z];
x[z] = x[z + 1];
x[z + 1] = temp;
}
}
}
for (int y = 0; y < x.length; y++) {
System.out.print(x[y]);
}
}
}
as part of the second problem finding the repeating sequence i'm looking into dis post and busy reworking to see if it will work.
Yet as far as i see it will find the repeating number and not sequence witch is where i'm stuck.
How to find repeating sequence of Integers in an array of Integers?
I'm still new to java and any aid will be appreciated
Kind Regards
Deon

can't you just use Arrays.sort(x) to sort the arrays in to order.

I suggest you split this in two separate questions.
I will now try to answer to the sorting problem, however, I'm not quite sure if I understand your problem here.
You implemented the bubble sort. You can see in the linked Wikipedia article how this is correctly implemented. Basically there is a do-while loop as the outer loop.
Alternatively, you could also use Java's Arrays#sort
EDIT
You can create a two dimensional array for your sequences like this:
int[][] seq = {
{23,45,38, 9,43,25,18},
{21,33,22, 5, 1,44,16},
{28,24, 5,42,15,49,41},
{43,18,50,29,22,32,25},
{33,38,27,35,25, 1,12},
{21,33,22, 5, 1,44,16},
{28,24, 5,42,15,49,41}
};
Then, you can iterate over seq and sort each contained array individually:
for(int i = 0; i < seq.length; i++) {
int[] x = seq[i];
// sort x
}

Thanks Hage, It's small but I learned a lot Here is the working code
public class Main {
public static void main(String[] args) {
int[][] seq={{ 42, 22, 40, 1, 11, 5, 43 },
{ 13, 11, 18, 45, 3, 44, 19 },
{ 46, 1, 32, 47, 35, 7, 36 },
{ 48, 21, 38, 29, 3, 12, 11 },
};
for (int i=0; i < seq.length; i++) {
int[] x=seq[i];
Arrays.sort(x);
for (int number : x) {
System.out.print(number + " ");}
System.out.print("\n");
}
}
}

Related

How can I create an array of only "odd" numbers between 1 and n - Java?

I ran into an issue I can't seem to solve, and all the searches I do are not completely relevant to the issue I am having, and trying to implement those things to solve my issue still doesn't work. I've spent an hour trying to find another question or post somewhere that would help but can't seem to find any specific to my issue (unless Google just doesn't want to work today).
I am trying to create a method that returns an array of all of the odd numbers between 1 and n, say in this example 1 to 255.
I tried the following (here is the method currently):
import java.util.Arrays;
public class BasicJava: {
public Integer[] arrayOfOdds() {
int n = 255;
Integer[] odds = new Integer[(n+1)/2];
for(int i = 1; i < n+1; i+=2) {
odds[i/2] = i;
}
return odds;
}
}
Main Method:
import java.util.Arrays;
public class BasicJavaTest {
public static void main(String[] args) {
BasicJava test = new BasicJava();
System.out.println(Arrays.toString(test.arrayOfOdds()));
}
}
I tried using an array to do the same thing before switching to using an ArrayList (I like other data structures more than I do arrays) and converting to an array and got the same output (I will just put part of the output array to not use too much space):
[0, 1, 0, 3, 0, 5, 0, 7, 0, 9, 0, 11, 0, 13, 0, 15, 0, 17, 0, 19, 0, 21, 0, 23, 0, 25, 0, 27, 0, 29, 0, 31, 0]
What do I need to resolve this issue?
If I just wanted to print all of the odds between 1 and N using the same for loop and if statement, I would get the correct output.
Thank you
You can do this is linear time complexity and without using an ArrayList.
Your final output will always have n/2 elements so your array size can be fixed at the same. In the next step you can simply populate the values in your array.
FYR code:
int[] arr = new int[((n+1)/2)];
for(int i = 0, e = 1; i < arr.length; e += 2, i++) {
arr[i] = e;
}
You can use IntStream like this.
static int[] arrayOfOdds() {
return IntStream.iterate(1, i -> i + 2)
.takeWhile(i -> i < 256)
.toArray();
}
public static void main(String[] args) {
System.out.println(Arrays.toString(arrayOfOdds()));
}
output:
[1, 3, 5, 7, 9, 11, 13, 15, ... , 251, 253, 255]
int N = 255;
Integer[] array = new Integer[(N+1)/2];
for (int j = 1; j < N+1; j+=2) {
array[j/2] = j;
}
System.out.println(Arrays.toString(array));
You don't need to add condition to check for each integer.
Here is a simple trick to create odds number:
Start with 1 and increase 2 for next element. ( 1,3,5...)
public static void main(String[] args) {
List<Integer> arr = getOddList(255);
System.out.print(arr);
}
private static List<Integer> getOddList(int n) {
List<Integer> nums = new ArrayList<>();
for (int i = 1; i < n; i = i + 2) {
nums.add(i);
}
return nums;
}
//Output [1, 3, 5, 7, 9, 11...

Java int array find and print matching

Here I have a Java case switch where I compare 2 randomly generated 7 number integer arrays, lottery1 array is generated earlier depending on the user input. The problem I am having is, I need to compare the two arrays and count the number of matching numbers and then print the matching numbers and how many numbers were the same.
I'm trying to put the matching numbers into the array called similar, now it's just comparing the first number of lottery1 to all of the lottery2's numbers. There's plenty of tutorials on how to compare arrays that return a bool but I need the matching numbers, please help!
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Random rnd = new Random();
int[] lottery1 = new int[7];
for (int i = 0; i < lottery1.length; i++) {
lottery1[i] = rnd.nextInt(52);
}
Arrays.sort(lottery1);
System.out.printf("Lottery array is: %s", Arrays.toString(lottery1));
System.out.print("\nDo you want to generate an array(y/n): ");
char answer = scan.next().charAt(0);
switch (answer) {
case 'n' -> System.out.print("Goodbye!");
case 'y' -> {
int[] lottery2 = new int[7];
for (int i = 0; i < lottery2.length; i++) {
int rndNum = rnd.nextInt(52);
lottery2[i] = rndNum; //Here i fill the lottery2 with random
} numbers
Arrays.sort(lottery2);
System.out.printf("Program created an array of: %s", Arrays.toString(lottery2));
int j = 0;
int[] similar = new int[7]; //I'm trying to put the matching numbers into this new array
for (int i = 0; i < 7; i++)
{
if (lottery2[i] == lottery1[j])
{
lottery1[i] = similar[j];
i++;
j++;
}
}
System.out.printf("\nThis is how many numbers are matching: ");
System.out.printf("\nThese numbers are matching ones: ");
}
I get that you are trying to compare all numbers in 2 list and get the ones with same values I wrote this code I think it answers your question:
int[] matching = new int[7];
int[] lottery1 = new int[7];
int[] lottery2 = new int[7];
// Generate random numbers
for (int i = 0; i < 7; i++) {
lottery1[i] = (int) (Math.random() * 52.0);
lottery2[i] = (int) (Math.random() * 52.0);
}
// Compare and store matching numbers in matching array;
// The nested loop below will compare the every element of the both lists
// together and store the
// results in matching array
int matchingCount = 0;
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
if (lottery1[i] == lottery2[j]) {
matching[matchingCount++] = lottery1[i];
}
}
}
System.out.print("Matching Count: " + matchingCount + "\nMatch Numbers: [ ");
for (int i = 0; i < matchingCount; i++)
System.out.print(matching[i] + " ");
System.out.println("]");
int[] similar = new int[7]; //I'm trying to put the matching numbers into this new array
lottery1[i] = similar[j];
similar is an array of size 7, filled with seven 0 values (because arrays start out zeroed out). You never write anything into similar. You overwrite lottery1 with what's in similar. In other words, this code is an obtuse way to accomplish:
lottery1[i] = 0;
which surely isn't what you wanted. You also initialize similar to have size 7 but this is incorrect: Who knows how many similar numbers even exist?
You have 4 options:
Use a List<Integer> list = new ArrayList<Integer>(); - unlike arrays, arraylists don't need to be pre-sized, you can just call list.add(), and the list will take care of it. It's variable size.
Loop twice; once to determine how many matches, then you can make your similar array with the right size, and then a second time to fill it.
Make the similar array at 7, also count how many similar numbers exist, then when done copy the data over to a new array at the proper size.
Make the similar array at size 7 and use a special sentinel value (such as -1) to indicate that this one should not be shown/printed.
Also, your code is buggy: If you have replications, you overcount. Imagine lottery1 is [1,2,3,4,5,6,1] and lottery2 is [1,2,2,3,4,1,6], your algorithm would say that there are 6 matches, which doesn't sound right (the first '1' matches twice, the second '1' matches twice, and the 2 matches 2. You're going to have to think about how you want to tackle this issue.
Think about this, and write down some sample inputs + the sample output you desire, and then think about how to write code that does this. Don't just dive in.
This seems to be a good task to learn decomposition of the bigger tasks into subtasks.
The first subtask is definitely to generate an array of size K of random integer values in the given range, let's assume that for lottery the range is from 1 to N inclusive.
Then two arrays are generated, and the second subtask is to find a match between these two.
An example implementation using Stream API could be as follows:
Generate array of random integers:
static int[] getRandomArray() {
return getRandomArray(7, 52);
}
static int[] getRandomArray(int k, int n) {
int[] result = new SecureRandom().ints(1, n + 1) // n + 1 to ensure N can be included
.distinct() // make sure all elements are different
.limit(k) // pick K numbers
// .sorted() // sort the array if needed
.toArray();
System.out.println("Random array: " + Arrays.toString(result));
return result;
}
Match the results with the help of Set:
static int[] findMatch(int[] lotteryPick, int[] lotteryGuess) {
Set<Integer> set = Arrays.stream(lotteryPick).boxed().collect(Collectors.toSet());
int[] match = Arrays.stream(lotteryGuess).filter(x -> set.contains(x)).toArray();
if (match.length == 0) {
System.out.println("No matched numbers found");
} else {
String num = match.length == 1 ? " number" : " numbers";
System.out.println("Matched: " + match.length + num + ", the match: " + Arrays.toString(match));
}
System.out.println("-------------------------------");
return match;
}
Then the tests would look as simple as:
int t = 5;
while (t--> 0) {
findMatch(getRandomArray(), getRandomArray());
}
Possible output:
Random array: [26, 33, 29, 23, 49, 1, 14]
Random array: [37, 3, 27, 29, 34, 24, 36]
Matched: 1 number, the match: [29]
-------------------------------
Random array: [9, 4, 32, 27, 29, 18, 35]
Random array: [34, 2, 23, 29, 27, 6, 30]
Matched: 2 numbers, the match: [29, 27]
-------------------------------
Random array: [35, 18, 4, 42, 19, 6, 13]
Random array: [30, 8, 4, 37, 31, 9, 46]
Matched: 1 number, the match: [4]
-------------------------------
Random array: [52, 7, 47, 22, 12, 9, 26]
Random array: [46, 13, 20, 17, 1, 4, 34]
No matched numbers found
-------------------------------
Random array: [31, 40, 9, 3, 2, 49, 44]
Random array: [2, 15, 13, 36, 10, 43, 12]
Matched: 1 number, the match: [2]
-------------------------------

How would I find the first 5 multiples of 4, 5, and 6 and add them to an ArrayList?

I have a homework assignment that needs me to write a method that, given a list, will remove all multiples of 3 and add the first 5 multiples of 4, 5, and 6. It will then add that list to a HashSet, removing the duplicate integers, and return the size of the HashSet.
I've figured out everything else in this problem save for the "add first 5 multiples of 4, 5, and 6". My current code is the one I'm stuck with, using a for loop to iterate from 1 to 30. However, given an empty list, this adds 28, which is the 7th multiple of 4. I've tried nesting loops so I can iterate to 30 while at the same time iterating to 5, but none of my attempts have worked. Can anyone help me out?
Below is my current code.
public static int modify(List<Integer> list) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == null) {
throw new IllegalArgumentException("Cannot be null.");
}
if (list.get(i) % 3 == 0) {
list.remove(i);
}
}
for (int i = 1; i <= 30; i++) {
if (i % 4 == 0) {
list.add(i);
}
if (i % 5 == 0) {
list.add(i);
}
if (i % 6 == 0) {
list.add(i);
}
}
Collections.sort(list);
HashSet<Integer> unique = new HashSet<Integer>();
unique.addAll(list);
return unique.size();
}
Instead of counting to 30 and checking for incidences of multiples of 4, 5, and 6, why don't you find the multiples directly?
for (int i = 1; i <= 5; i++) {
list.add(4 * i);
list.add(5 * i);
list.add(6 * i);
}
If there are any duplicates, they'll be removed when you add them to the HashSet.
Side note: I'm not sure why you're bothering to sort the list before you add them to the HashSet. Sets inherently have no order so it doesn't matter if the list is sorted or not.
I'm assuming you're expecting the output of passing in an empty list to be:
unique = [4, 5, 6, 8, 10, 12, 15, 16, 18, 20, 24, 25, 30]
size = 13
With your current logic, there's nothing stopping it from adding multiples which are more than 5 (i.e. the 7th multiple of 4 for example), you're just continuing on until you've hit 30 in the loop. Instead, I might recommend having your for loop go 1-5 and then multiply by the factor you'd like a multiple of. i.e.:
// add the first 5 multiples of 4,5,6 to the list
for (int i = 1; i < 6; i++) {
list.add(i*4);
list.add(i*5);
list.add(i*6);
}
I rewrote the whole method making some changes:
The removal part of multiples of 3 in this way is more efficient. I
used the very useful removeIf() method.
I wrote the solution to your problem, identical to the other
answers.
CODE
public static void main(String[] args) {
List<Integer> list = new LinkedList<>();
for (int i = 0; i < 30; i++) {
list.add(i);
}
System.out.println(modify(list));
}
public static int modify(List<Integer> list) {
list.removeIf(n -> (n % 3 == 0));
for (int i = 1; i < 6; i++) {
list.add(4 * i);
list.add(5 * i);
list.add(6 * i);
}
Collections.sort(list);
HashSet<Integer> unique = new HashSet<>(list);
System.out.println(unique.toString()); // You can delete this
return unique.size();
}
OUTPUT
[1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 28, 29, 30]
26

The objective is to prevent subject/user learning from memory, do you understand what that is? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Attached is developed merge sort code that is able to count comparisons made for a given array and print out each comparison. I want it to be able to prevent user learning effectively, so that the numbers compared are spaced out enough in which one would not remember seeing the past numbers as well. Now we need to make it do those comparisons in a different order. The code will probably no longer be pretty and recursive, but some giant ugly loops, I anticipate.
public class MyMergeSort {
private int[] array; //array declared
private int[] tempMergArr; //temporary array
private int length; //counting length of array
private int ncompare=0;
public static void main(String a[]){
int[] inputArr = {9, 2, 56, 5, 4, 6, 60, 8, 1, //the array, given 60
32, 21, 12, 42, 57, 15, 16, 50, 18, 19,
20, 11, 34, 23, 48, 25, 26, 27, 51, 29,
30, 31, 10, 33, 22, 35, 39, 37, 38, 36,
40, 41, 13, 43, 44, 53, 46, 47, 24, 49,
17, 28, 52, 45, 54, 55, 3, 14, 58, 59,
7};
MyMergeSort mms = new MyMergeSort(); //declaring the merge sort for the array
mms.sort(inputArr);
System.out.print("\n\n");
for(int i:inputArr){
System.out.print(i);
System.out.print(" ");
}
System.out.print("\n Number of comparisons "+mms.ncompare+"\n");
}
public void sort(int inputArr[]) { //sort method uses 'this' for array input
this.array = inputArr;
this.length = inputArr.length;
this.tempMergArr = new int[length];
doMergeSort(0, length - 1);
}
private void doMergeSort(int lowerIndex, int higherIndex) { //indexed method for merge sort, states each step and case
if (lowerIndex < higherIndex) {
int middle = lowerIndex + (higherIndex - lowerIndex) / 2;
// Below step sorts the left side of the array
doMergeSort(lowerIndex, middle);
// Below step sorts the right side of the array
doMergeSort(middle + 1, higherIndex);
// Now merge both sides
mergeParts(lowerIndex, middle, higherIndex);
}
}
private void mergeParts(int lowerIndex, int middle, int higherIndex) { //merge method using 'for' case,
for (int i = lowerIndex; i <= higherIndex; i++) {
tempMergArr[i] = array[i];
}
int i = lowerIndex; //declaring index variables for different cases
int j = middle + 1;
int k = lowerIndex;
while (i <= middle && j <= higherIndex) { //define loops for steps of different cases
System.out.print(" C "+i+" "+j);
ncompare=ncompare+1;
if (tempMergArr[i] <= tempMergArr[j]) {
array[k] = tempMergArr[i];
i++;
} else {
array[k] = tempMergArr[j];
j++;
}
k++;
}
while (i <= middle) {
array[k] = tempMergArr[i];
k++;
i++;
}
}
C 0 1
C 2 3
C 0 2
C 1 2
C 1 3
these are the first five comparisons made in my existing algorithm. I want to prevent it from comparing 0 and 2 and then 1 and 2, since the user will likely remember the 2, just like when comparing 1 and 2 and then 1 and 3 the user will remember the 1.
i want to make it so that the numbers compared would not be as memorable to the user as possible, so as to prevent them from making biased comparisons
The order of comparisons is defined by the merge sort algorithm. If you're comparing indexes in an unpredictable or "not memorable" order, you aren't doing merge sort anymore. You'd literally have to invent a new sort algorithm to get this behavior.
However, you could print the comparisons in a random order after doing them normally. Just store them in a list field, then shuffle and print them after the sort. For example:
public List<int[]> comparisons = new ArrayList<>();
Replace the print in mergeParts with:
comparisons.add(new int[] { i, j });
After the sort:
mms.sort(inputArr);
Collections.shuffle(mms.comparisons);
for (int[] c : mms.comparisons) {
System.out.print(" C "+c[0]+" "+c[1]);
}

Assigning multiple values to multiple variables in a single line

I'm trying to write the Java equivalent of the following Python Inversion-Sort algorithm:
import numpy as np
def main(items):
for i in range(1, len(items)):
j = i
while j > 0 and items[j] < items[j-1]:
items[j], items[j-1] = items[j-1], items[j]
j -= 1
print(items)
main(np.array([4, 78, 23, 24, 56, 7, 9]))
This is the Java version:
import java.util.Arrays;
public class Sorters {
public static void main(String args[]) {
Sorters sort = new Sorters();
int[] items = {4, 78, 23, 24, 56, 7, 9};
sort.insertionSort(items);
}
public void insertionSort(int[] items) {
for(int i=1 ; i<items.length ; i++) {
int j = i;
while(j>0 && items[j] < items[j-1]) {
items[j] = items[j-1]; // These two lines are
items[j-1] = items[j]; // causing the error
j -=1;
}
}
System.out.println("Sorted array: " + Arrays.toString(items));
}
}
I've narrowed the issue down to the two lines that are commented as such, above (in the Java method).
If I give the Python function this array: [4, 78, 23, 24, 56, 7, 9] (for example), everything works fine. However, if I give the same array to the Java method, I get this in return: [4, 78, 78, 78, 78, 78, 78].
Could someone tell me how to write the Java equivalent of Python's items[j], items[j-1] = items[j-1], items[j]? Explanations welcomed. Thanks.
That's because you need to use a temp variable to store one of the values when you swap between the items[j] with items[j-1]. It should be something like that:
int temp = items[j];
items[j] = items[j-1];
items[j-1] = temp;
What happens is that you lose the original value so each iteration of the loop you get to copy into items[j] the value of items[j-1].
That's how you got your output.
So basically you want to swap the two indexes. You can do it like this
int tmp = items[j];
items[j] = items[j-1];
items[j-1] = tmp;

Categories