I got an algorithm to write that set order of an Arrey but in a specific way.
Find the lowest number of an array
Save it at the start of the new array.
Mark in the origin (starting) array spot which from we found the lowest number (mark by for example change it to maximum int number).
Go back to point 1.
Repeat all to rewrite all numbers in ascending order.
So I got a working code that changes the order, but I can't figure out how to mark the numbers, and thanks to this create a new array.
public static void arrOrder(int[] intArray){
int temp = 0;
for (int i = 0; i <intArray.length; i++) {
for (int j = i+1; j <intArray.length; j++) {
if(intArray[i] >intArray[j]) {
temp = intArray[i];
intArray[i] = intArray[j];
intArray[j] = temp;
}
}
}
}
So I got a working code that changes the order
No, you don't. Even if you figure out how to do the marking thing, the code you pasted changes the order, perhaps, but it doesn't sort anything.
Your code will, for each element (the i loop):
For each element above it, if it is higher, replace stuff. This isn't, at all, what you wanted - what you wanted is to first figure out if the i-th number is the smallest number. If no, do nothing (continue on to the next number, check if that one is lowest), If yes, write it into a new array, and replace it with some placeholder to indicate that you've already done that one - the suggestion is Integer.MAX_VALUE, a fine suggestion.
The 'strategy' you describe involves:
Making a separate new array of the right size.
Maintaining a variable that counts how many numbers have been written into this new array - when you find your next lowest number, you'd write it at that index.
A double-loop construct where the inner loop doesn't write anything, it merely tracks if the i number is the lowest.
Some code inside the i loop but after the j loop that acts only if i was, in fact, the lowest number. Presumably involves a boolean that you set initially and clear in the inner loop (the j loop), then an if that only acts if the boolean remains true, i.e. - no lower number exists.
The j loop needs to hit the entire array, not 'only stuff above you'.
You need to explicitly exclude your sentinel value. I suggest you use Integer.MAX_VALUE. This probably involves another if.
If you code looks anything like what you pasted, you didn't do it right, given that what you pasted doesn't do any of the named strategy elements.
Related
I am looking at the LeetCode problem 2134. Minimum Swaps to Group All 1's Together II:
A swap is defined as taking two distinct positions in an array and swapping the values in them.
A circular array is defined as an array where we consider the first element and the last element to be adjacent.
Given a binary circular array nums, return the minimum number of swaps required to group all 1's present in the array together at any location.
I am trying to study how other people came up with solutions of their own. I came across this particular one, but I don't understand the logic:
class Solution {
public int minSwaps(int[] nums) {
// number of ones
int cntones=Arrays.stream(nums).sum();
// worst case answer
int rslt=nums.length;
// position lft and figure better value for min/rslt
int holes = 0;
for(int i=0;i<cntones;i++) {
if(nums[i]==0)
holes++;
}
// better value for rslt from lft to rgt
// up to index of cntones.
rslt = Math.min(rslt, holes);
// they have a test case with one element
// and that trips up if you dont do modulo
int rgt=cntones % nums.length;
for(int lft=0;lft<nums.length;lft++) {
rslt=Math.min(rslt,holes);
if(nums[lft]!=nums[rgt])
if(nums[rgt]==1)
holes--;
else
holes++;
rgt=(rgt+1)%nums.length;
}
return rslt;
}
}
Why is the worst case, the length of the input array?
I'm thinking wait, wouldn't the worst case be something like [0,1,0,1,0,1...] where 0's and 1's are alternating? Can you give me an example?
I suppose #of holes can potentially be a possible solution in some cases, from counting 0's in a fixed length (the number of total 1's) of a window but because I do not understand the worst case, rslt from question #1, below line stumps me as well.
// better value for rslt from lft to rgt
// up to index of cntones.
rslt = Math.min(rslt, holes);
About the modulo below, I don't think cntones can ever be bigger than nums.length, in turn which will result in 0 all the time? I'm thinking for the case with one element, you'd have to check whether that one element is 0 or 1. How does below line cover that edge case?
// they have a test case with one element
// and that trips up if you dont do modulo
int rgt=cntones % nums.length;
Due to #1~#3 the last for loop makes no sense to me...
Why is the worst case, the length of the input array?
First note that a swap is only useful when it swaps a 0 with 1. Secondly, it makes no sense to swap the same digit a second time, as the result of such double swap could have been achieved with a single swap. So we can say that an upper limit for the number of swaps is the number of 0-digits or number of 1-digits (which ever is the least). In fact, this is an overestimation, because at least one 1-digit should be able to stay unmoved. But let's ignore that for now. To reach that worst case, there should be as many 1 as 0 digits, so then we have half of the length as worst case. Of course, by initialising with a value that is greater than that (like the length) we do no harm.
The example of alternating digits would be resolved by keeping half of those 1-digits unmoved, and moving the remaining 1-digits in the holes between them. So that means we have a number of swaps that is equal to about one fourth of the length of the array.
below line stumps me as well.
rslt = Math.min(rslt, holes);
As you said, there is a window moving over the circular array, which represents the final situation where all 1-digits should end up. So it sets the target to work towards. Obviously, the 1-digits that are already within that window don't need to be swapped. Each 0-digit inside that window has to be swapped with a 1-digit that is currently outside that window. Doing that will reach the target, and so the number of swaps for reaching that particular target window is equal to the number of holes (0-digits) inside that window.
As that exercise is done for each possible window, we are interested to find the best position of the window, i.e. the one where the number of holes (swaps) is minimised. That is what this line of code is doing. rslt is the minimum "so far" and holes is the fresh value we have for the current window. If that is less, then rslt should be updated to it. That's what happens in this statement.
About the modulo below, I don't think cntones can ever be bigger than nums.length, in turn which will result in 0 all the time? I'm thinking for the case with one element, you'd have to check whether that one element is 0 or 1. How does below line cover that edge case?
int rgt=cntones % nums.length;
That modulo only serves for the case that cntones is equal to nums.length. You are right that it will never exceed it. But the case where it is equal is possible (when the input only has 1-digits). And as rgt is going to be used as an index, it should not be equal to nums.length as that is an undefined slot in the array.
Due to #1~#3 the last for loop makes no sense to me...
It should be clear from the above details. That loop moves the window with one step at a time, and keeps the variable holes updated incrementally. Of course, we could have decided to count the number of holes from scratch in each window, but that would be a waste of time. As we go from one window to the next, we only lose one digit on the left and gain one on the right, so we can just update holes with that information and know how many holes there are in the current window -- the one that starts at lft and runs (circular) to rgt. In case the digit that we lose at the left is the same as the one we gain at the right, we obviously didn't change the number of holes. Where they are different, we either win or lose one hole in comparison with the previous window.
I am having some trouble sorting a vector by comparing the elements finding the minimum and putting it in another vector that will be the sorted one using two cycles, in particular i keep having ArrayIndexOutOfBoundsException.
Vector<Figure> myList = new Vector<Figure>(); //this is the vector with all the unsorted geometric shapes
Vector<Figure> listordered = new Vector<Figure>(); //the vector where i want to put them sorted
Figure x = null;
int indice = 0;
System.out.println(myList.size());
do{
for(int i=0;i<myList.size();i++) {
x = myList.get(i);
if(x.compareTo(MIN) <0)
MIN=x;
indice = myList.indexOf(MIN);
}
listordered.add(MIN);
myList.removeElementAt(indice);
System.out.println(myList.size());
}while(myList.size()!=0);
System.out.println(listordered);
My idea was to find the minimum with a cycle then add it to the sorted vector and with another cycle keep doing this untill there were no more elements in the first vector and removing each time the new minimum element found. but it doesnt work.
The problem is that your code never resets MIN and indice between iterations of the outer do - while loop. Since the code never updates MIN, the second iteration unintentionally reuses the old value of indice, eventually causing index out of bounds exception in removeElementAt.
One approach to fix this is to set indice to zero and MIN to myList.get(0) before going into the for loop. In fact, you should move indice and MIN declarations inside the do - whole loop, because this is their proper scope.
Finally, you are missing curly braces around if's body. This has no effect on functionality, but results in redundant processing.
Note: I assume that you are writing your own sort as a learning exercise. Otherwise you should use Java library functions or ordering collections.
Explanation
I was given a task in my Grade 12 Computer Science class that just totally has me stumped. So far I have tried using a bunch of if statements (While i know that is not the best way of doing I though for sure it was going to work) but that didn't work. I then tried to use nested loops but that didn't work either here is the code that I created so far for this method.
Code (Note: Max=1000)
private static void totals2 (Scanner user_input,int max){
int[] num = new int[max];
int[] total=new int[10];
System.out.println("Welcome to totals\nThis method gathers input and displays the sum depending on which category they fall in");
System.out.println("Enter numbers from 0-99 only (Up to 1000 inputs)\nEnter any number outside of 0-99 to stop collecting\n");
for (int i = 0; i < num.length; i++) {
System.out.println("Please enter a number to be stored in index: " + i);
num[i] = user_input.nextInt();
if (num[i] < 0 || num[i] > 99) {
break;
}
}
for(int i = 0; i < 100; i +=10){
int j;
int k=(i/10)-1;
for(j=0 ;j<1000;j++){
if (num[j] <= i){
total[k]+= num[j];
}
}
System.out.println(total[k]);
}
}
Question
Create a procedure that will output the total of all numbers (in an array) entered less than 10, the total of all numbers entered less than 20, the total of all numbers entered less than 30, ... and the total of all numbers entered less than 100 (so 88 will be included in both totals for numbers less than 90 and less than 100).
As it is your assignment, I will not post any code here. Just some thoughts.
Do you need to save the number out of 0 to 99? If not, check your first loop.
for your second for loop, if i=0, what value will be k? if i=10 what value will be k?
I did not run your algo, that's all issues I found while reading it. Learn how to use a debugging tool will be helpful for your further study. (Recommend Intellj for Java development)
Great first question:
This already has answers for your problems, normally your question would probably get closed as a duplicate of these, but I think it should be left open so you can get some details about your code since you did such a good job with your first question.
Since you are pretty close to getting this correct I am just going to say that everything you need to get your code working is in the two questions linked below.
How to use Scanner properly:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
How to iterate over an Array:
How to avoid ArrayIndexOutOfBoundsException or IndexOutOfBoundsException?
Effectively Debugging:
What is a debugger and how can it help me diagnose problems?
What is a stack trace, and how can I use it to debug my application errors?
First off, you can not iterate through an Array with integer index values greater than the number of indexes (- 1 because arrays are zero (0) based) contained within the Array otherwise you will simply end up with an ArrayIndexOutOfBoundsException. If there are only 20 elements contained within the Array then you can only iterate from 0 to 19....not 0 to 999. With this in mind, change 1000 to num.length and you should be fine with the exception of....
For your for loop used to increment by 10 for the "find values less than" value, initialize the variable i to 10 instead of 0. Think about it...do the math...what do you think will happen when you try to divide 0 into 10 then subtract 1 [(0 / 10) - 1]? You end up with an invalid index value for the variable k and therefore, another ArrayIndexOutOfBoundsException.
Also, if you read the question carefully you can see that what is required are the sums of values supplied that are less than 10, less than 20, less than 30....less than 100. Not Less Than or Equal To (... <= ...). Correct your if statement condition within your second for loop.
Food for thought:
You might want to ask the User to supply the max array index value as
well and eliminate that as a parameter for the totals2() method. Place the explanation for it into the "Welcome" message.
Hey I did a runtime analysis on Bubblesort and I wanted to ask you if there were any mistakes since I was not sure at a certain point
heres an extract of the algorithm:
boolean sorted = false;
while(!sorted)
{
int a = 0;
int b = 1;
sorted = true;
while(a < sortArray.length && b < sortArray.length)
{
if(sortArray[a].getWertigkeit() < sortArray[b].getWertigkeit())
{
Karte tmp1 = sortArray[a];
Karte tmp2 = sortArray[b];
sortArray[a] = tmp2;
sortArray[b] = tmp1;
sorted = false;
}
a++;
b++;
}
}
So the problem I got is in the first while-loop, I solved it as following:
Best Case: In the best Case the sorted never gets set back to the false (through the if(..){..}) so it only goes once through the loop;
So the runtime is, if I am not wrong, 2*2n*1 = 4n => O(n) for the best Case;
Worst Case:In the worst Case the variable sorted gets set on false everytime the loop starts, as far as I know, so it needs another "n" comparisons so the runtime should be: n*2n*1 = 2n^2 => O(n^2)
I am really not sure if my thoughts about the while(!sorted) are correct or if the runtime makes any sense (since the big o notation seems fine, but im not sure about the precise runtime)
I really hope that my problem is relatable and I look forward to hear from you.
Thx already
Your analysis of the best-case runtime of O(n) is correct. Nice job!
For the worst-case, you need to be a little bit more precise. You're right that every time the flag gets reset you have to make another pass over the array to get it more sorted than before, so you know it's going to be O(n) times the number of times the loop runs. What you haven't yet done in your analysis is talk about how many times that loop can run before everything is going to end up sorted.
One observation you can make about bubble sort is that after the first pass over the array, the largest element is guaranteed to be in the last position - can you explain why? After the second pass, the second-largest element is guaranteed to be in the second-to-last position - again, can you explain why? Based on this pattern, can you argue why the number of times the outer loop runs is at most O(n)?
I'm working on my homework and there's a question that ask us to sort a struct array
The structcitizen consist of an int id and a boolean gender, where id is randomly generated between 1 to 100,
and gender is determined by if id is odd or even, odd=true(male) and even=false(female)
for example a = {33, true}
The question requires me to sort the citizen[] array by gender, it seems very easy but it has the following requirements:
run in linear times O(N)
no new array
only constant extra space can be used
I am thinking about using counting sort but it seems a little bit hard to do it without a new array, is there any suggestion?
Since this is a homework question I'm not going to provide code. The following should be sufficient to get you started.
"Sorting" by gender here really means partitioning into two groups. A general purpose sort cannot be better than O(n*log(n)), but partitioning can be done in O(n) with constant space.
Consider iterating from both ends simultaneously (while loop, two index pointers initialized to first and last elements) looking for elements that are in the "wrong" section. When you find one such element at each end, swap them. Note that the pointers move independently of each other, only when skipping over elements that are already in the right section, and of course immediately after a swap, which is a subcase of "elements already in the right section".
Quit when the index pointers meet somewhere in the middle.
This is not a general purpose sort. You cannot do this for the case where the number of keys is unknown.
Since you only have two values to sort, you could use a kind of swap-counting-sort (I couldn't find any relevant paper on that one).
There is room for optimisation on that sort, but that will be your job.
Here is a pseudo-code of that special sort according to your issue :
integer maleIndex = 0 // Current position of males in the array
for i=0 until array.size do
if array.at(i) is a male then
// after a while, all female will end up at the end
// while all male will end up at the beginning
swap(array.at(maleIndex), array.at(i))
maleIndex = maleIndex + 1
end
end
One approach is similar to the partition stage in QuickSort, or to the median/rank finding algorithm QuickSelect.
I'm going to describe the outline of the algorithms, but not provide any code. Hopefully, it will be good enough that it is easy to make the translation.
You basically want to reorganize the array so that one gender is at the start, and the other is at the end of the array. You'll have the array partitioned in three:
From 0 to i-1 you have the first gender (male or female, up to you)
From i to j-1 you have both male/female. This is the unknown area.
From j to n-1 you have the second gender.
At the start of the algorithm i is set to 0, so the first area is empty, and j is set to n-1, so the second area is empty. Basically the whole array is in the unknown state.
Then, you iterate over the array in a particular way. At each step, you look at citizen[i].gender. If it is the first gender, you leave it alone and increment i. If it is the second gender, you swap A[i] with A[j] and decrement j. You stop when i is equal to j.
Why is this correct? Well, at each step we can see that the constraint of having the three areas is maintained, assuming it held to begin with (which it does), and either the first or the second one increases. At the end, the second area has no elements, so we're only left with the first gender at the start, and the second at the end.
Why is it linear? Well, at each step we make a constant-time decision for one element in the array about where it should belong. There's n such elements, so the time is linear in that. Alternatively, the iteration test can be expressed as while (j - i > 0), and the expression j - i starts at n-1 and drops by 1 for each iteration.