This is my first time using stack overflow, so I'm so sorry if this is formatted incorrectly in any way. For a comp sci project, I have to do some different things to a 40-item Array List of random numbers.
The task I'm struggling with is this:
Count the longest run of the same number. A run continues only when consecutive numbers
have the same value. The repeated number and the length of the run is then printed. (Ex: Longest run is of number: 3, length is: 5.)
If there is more than one run of maximum length, mark the last one. Print the array with the longest run marked in the following fashion:
1 1 1 6 5 4 6 3 2 3 2 (3 3 3 3 3) 1 5 6 3 4 4 4
I genuinely have no idea how to approach this problem. Even just some pseudocode could be helpful; I know that these should probably be 2 different 'for' loops, one that detects the run and the other that prints it. I have some code from a friend who completed this using Arrays instead of ArrayLists:
public String longestRun()
{
int maxRun=1;
int currentLen = 1;
int repeated = x[0];
for (int i =1; i< 40-1; i++)
{
if (x[i] == x[i+1])
currentLen++;
else
{
if (currentLen >= maxRun)
{
maxRun = currentLen;
repeated = x[i-1];
startRun = i-maxRun;
endRun = i-1;
}
currentLen = 1;
}
}
return "The longest run is " + maxRun + " and the repeated number is " + repeated ;
}
public String printParenth()
{
for(int i = 0; i<40; i++)
{
if(i != startRun+1 && i != endRun+1)
System.out.print(x[i]);
else if(i == startRun+1)
System.out.print("(" + x[i]);
else
System.out.print(x[i] + ")");
}
return "";
}
I know how to create the ArrayList, convert to string & print, etc, it's just this one task that I don't understand. I assume this should be easier with an ArrayList, considering the increased number and utility of ArrayList methods. Thanks so much in advance, I really appreciate it!
Put your numbers in a list or an array.
Set max to 1 (you will always have at least 1 number).
initialize count to 1.
initialize the variable most to the first number in the array
also set the variable last to the first number in the array.
Now iterate thru the list starting with the second number.
If the current number is the same as last, increment count.
then see if count > max.
if it is
set max = count.
set most = last
if it isn't
set count = 1
set last = current number
continue in this fashion until all numbers have been checked.
At the end most will contain the number that was repeated and max will contain the length of the repetition.
I'm trying to do a certain project and there is this part in which I want to loop in a two-dimensional (2D) array and if the certain value of i and j then do something.
To be more specific my 2D array is defined for files and users (the attached photo might explain well); I want, for example, when i = 0 and j = 0 equals 1 then print out that user 1 can write in file. I was able to iterate over the array and find the indexes where 1's occur in the array with the following code:
my 2d array defined
public class Test {
public int counteri = 0;
public int counterj = 0;
public void readpermission(int[][] array) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 6; j++) {
if (array[i][j] == 1) {
counterj = j;
counteri = i;
System.out.println("found 1's at index =" + counteri + " " + counterj);
}
}
}
}
}
found 1's at index =0 0,
found 1's at index =0 1
found 1's at index =0 4
found 1's at index =1 1
found 1's at index =1 2
found 1's at index =1 3
found 1's at index =1 4
found 1's at index =1 5
When the first value is 0 0, I want an output that user 1 can write in file 1 and when the output is 0 1 I want an output stating that user 1 can read in file 1...and so on.
Given your last comment:
if(array[i=0][j=0]==1)
could be
if (i==0 && j==0 && array[i][j] == 1)
But the point is: that is really basic java syntax; and you should not need to come here and ask about that. Instead: you study tutorials and education materials that tells you how to do work with java syntax, for example here.
But please note: the whole thing that you are describing doesn't make too much sense. You are using int values to model permissions. That is not a good idea. Instead: you could create your own Permission class; or at least: use an enum instead of int values. Assuming that an int with value 1 ... means "write access" is simply a very naive and actually not-at-all intuitive model.
I have a string array
"Ben", "Jim", "Ken"
how can I print the above array 3 times to look like this:
"Ben", "Jim", "Ken"
"Jim", "Ben", "Ken"
"Ken", "Jim", "Ben"
I just want each item in the initial array to appear as the first element. The order the other items appear does not matter.
more examples
Input
"a","b","c","d"
output
"a","b","c","d"
"b","a","c","d"
"c","b","a","d"
"d","a","c","d"
Method signature
public void printArray(String[] s){
}
Rather than give you straight-up code, I'm going to try and explain the theory/mathematics for this problem.
The two easiest ways I can come up with to solve this problem is to either
Cycle through all the elements
Pick an element and list the rest
The first method would require you to iterate through the indices and then iterate through all the elements in the array and loop back to the beginning when necessary, terminating when you return to the original element.
The second method would require you to iterate through the indices, print original element, then proceed to iterate through the array from the beginning, skipping the original element.
As you can see, both these methods require two loops (as you are iterating through the array twice)
In pseudo code, the first method could be written as:
for (i = array_start; i < array_end; i++) {
print array_element[i]
for (j = i + 1; j != i; j++) {
if (j is_larger_than array_end) {
set j equal to array_start
}
print array_element[j]
}
}
In pseudo code, the second method could be written as:
for (i = array_start; i < array_end; i++) {
print array_element[i]
for (j = array_start; j < array_end; j++) {
if (j is_not_equal_to i) {
print array_element[j]
}
}
}
public void printArray(String[] s){
for (int i = 0; i < s.length; i++) {
System.out.print("\"" + s[i] + "\",");
for (int j = 0; j < s.length; j++) {
if (j != i) {
System.out.print("\"" + s[j] + "\",");
}
}
System.out.println();
}
}
This sounds like a homework question so while I feel I shouldn't answer it, I'll give a simple hint. You are looking for an algorithm which will give all permutations (combinations) of the "for loop index" of the elements not the elements themselves. so if you have three elements a,b,c them the index is 0,1,2 and all we need is a way to generate permutations of 0,1,2 so this leads to a common math problem with a very simple math formula.
See here: https://cbpowell.wordpress.com/2009/11/14/permutations-vs-combinations-how-to-calculate-arrangements/
for(int i=0;i<s.length;i++){
for(int j=i;j<s.length+i;j++) {
System.out.print(s[j%(s.length)]);
}
System.out.println();
}
Using mod is approppiate for this question. The indexes of the printed values for your first example are like this;
0 1 2
1 2 0
2 0 1
so if you write them like the following and take mod of length of the array (3 in this case) you will reach solution.
0 1 2
1 2 3
2 3 4
while trouble-shooting my method for quicksort algorithm, this problem popped up;
consider this simple example of printing an array elements individually:
public static void print1(int[] arr, int start, int end){
for (int k = start; k<end;k++){
System.out.println(arr[k]);
}
}
public static void print2(int[] arr, int start, int end){
for (int k=start; k<=end;k++){
System.out.println(arr[k]);
}
}
In the main, if I call:
public static void main(String[] args) {
int[] data2 = new int[]{10,11,9,7,5};
print1(data2,0,data2.length);
System.out.println("___________");
print2(data2,0,data2.length-1);
}
both prints the same content, which is well and good;
(Note, I pass data2.length and data2.length-1 as arguments to my print1 and print2 methods and the for-loop in each method changes accordingly)
Now comes the problem with quicksort regime:
consider this code:
public static void quickSort2(int[] arr, int i, int j){
if (i<j){
int part =partition(arr, i, j);
quickSort2(arr, i, part-1);
quickSort2(arr, part+1, j);
}
}
public static int partition(int[] arr, int start, int end){
int pivot = arr[start];
int i = start;
for (int j = start+1;j<=end;j++){ // ******
if (arr[j]<pivot){
i++;
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
arr[start]=arr[i];
arr[i]=pivot;
return i;
}
In the main;
public static void main(String[] args) {
//int[] data = new int[]{5,10,1,9,4,4,8,3,6,2,7,4};
int[] data = new int[]{3,4,1,2};
int[] data2 = new int[]{10,11,9,7,5};
System.out.print("Unsorted array data ");
display(data);
System.out.print("\nUnsorted array data2 :");
display(data2);
quickSort2(data, 0, data.length-1);
System.out.println("_____________");
quickSort2(data2,0,data2.length-1);
System.out.print("\nSorted array data: ");
display(data);
System.out.print("\nSorted array data2:");
display(data2);
}
works fine and good;
now If I change the call to quickSort(data, 0, data.length) and change the for-loop line (marked in the code with *******) to for (int j = start+1;j<end;j++), I get entirely different result:
i.e: first two elements are not sorted, but rest rest of it is sorted.
I get
Sorted array data: [2, 1, 3, 4]
Sorted array data2:[5, 9, 7, 10, 11]
I need some help
While calling the first partition in your quicksort function you will also have to change:
quickSort2(arr, i, part-1);
to
quickSort2(arr, i, part);
This is because you are not using the last index (end). Hence your quicksort will be incomplete since you are not placing the last element before the pivot even if it has a lower value than pivot.
After a quick look, I think there are two separate bugs - I discovered one for each of your quickSort2() calls in 'main`. Each was triggered because of the nature of the array you were trying to sort.
Bug 1: at line 9 in your main, you call:
quickSort(data, 0, data.length);
So, this is when you try to quickSort() {3,4,1,2}. The error occurs on the first recursive call to quickSort2(), the exact call with its arguments being
quickSort2({2,1,3,4}, 0, 1);
which then calls partition() with the same parameters
partition({2,1,3,4}, 0, 1);
This is where the error occurs. Look at the terms of your for-loop:
for (int j = start+1; j< end;j++)
j will immediately be set to 1. End already equals 1. 1 < 1 is false, so the loop never triggers.
Solution: just get rid of the +1 when assigning j a value. Your loop will look like this:
for (int j = start; j< end;j++)
The initial case where i == j is will never trigger the if-statement so I believe it should be fine.
Bug 2: at line 11 in main, you call:
quickSort2(data2,0,data2.length-1);
The eventual error occurs at the same place as it did in the first bug - in partition() during the first recursive call to quickSort2(), which ends up having these parameters:
partition({5,9,7,10,11}, 0, 2);
The if-statement in your for-loop is never triggered, because 5 is the pivot and 9 and 7 are both larger. Thus i returns as zero, and this half of the array is never sorted again.
As for a quick solution to this, I can't say there is one I can readily think of. You'd have to alter the logic of your sort.
Some notes/pointers that may help you out.
Quicksort algorithms, in general, aren't typically called all the way down the array. There is usually a base case in which sorting switches over to a different algorithm. Example, you have only 5 objects left to sort on this call. That's not that many, so let's switch to something simpler, such as insertion sort. Even though insertion sort is generally less efficient on large collections, when you get down to only having 5 or fewer objects to rearrange, it's not such a big deal.
Quicksort implementations also typically don't call the very first object in the collection the pivot. This is a bad method in general, as what if your list was already sorted, or reverse sorted? The time complexity would be pretty mediocre ( O(N2)). Instead, there is a method called "Median-Of-Three", which not only just might solve the second bug you have, but give you a better time-complexity.
quickSort(data, 0, data.length-1);
//...
quickSort2(data2,0,data2.length-1);
I see the two quickSort is not the same, maybe you have a another function named quickSort you forget?Or just wrong written?
had a look at the code added some prints and found out, that after your modification is in the second run your pivot element 0, what is obviously wrong. I added some numbers to be the
unsorted array data this:
3 4 1 2 7 5 6
3 4 1 2 7 5 6
pivot: 2
2 1 3 4 7 5 6
pivot: 0
2 1 3 4 7 5 6
2 1 3 4 7 5 6
2 1 3 4 7 5 6
pivot: 3
2 1 3 4 7 5 6
2 1 3 4 7 5 6
pivot: 6
2 1 3 4 6 5 7
pivot: 4
2 1 3 4 6 5 7
2 1 3 4 6 5 7
2 1 3 4 6 5 7
Sorted array data:
2 1 3 4 6 5 7
package quicksort;
public class Quicksort {
public static void main(String[] args) {
int[] data = new int[]{3,4,1,2,7,5,6};
System.out.print("Unsorted array data:\n");
display(data);
quickSort2(data,0,data.length);
System.out.print("\nSorted array data:\n");
display(data);
}
public static void quickSort2(int[] arr, int i, int j){
display(arr);
if (i<j){
int part =partition(arr, i, j);
quickSort2(arr, i, part-1);
quickSort2(arr, part+1, j);
}
}
public static int partition(int[] arr, int start, int end){
int pivot = arr[start];
//System.out.println(pivot);
int i = start;
int temp;
for (int j = start;j<end;j++){ // ******
if (arr[j]<pivot){
i++;
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
arr[start]=arr[i];
arr[i]=pivot;
System.out.println("pivot: "+i);
return i;
}
public static void display(int[] data){
for(int i=0;i<data.length;i++){
System.out.print(data[i]+" ");
}
System.out.println("\n");
}}
I have a problem that asks:
Write a program that converts its input arguments into an array of
integers, and then finds the length and location of the longest
contiguous sequence of equal values where the values of the elements
just before and just after this sequence are smaller.
For example, if
the command line arguments are “1 2 2 2 2 5 5 5 3” your program should
output the numbers 5 3 (the first number is a zero-based offset, and
the second number is the length of the subsequence). If a contiguous
subsequence appears at the beginning or end of the array, treat this
as a special case;e.g.,for input “5 5 5 5 3 8 8 8 1”your output should
be 0 4 (and not 5 3). If there are multiple subsequences that satisfy
the above condition, then output the first one.
Updated code:
public class LongestPlateau {
public static void main(String[] args) {
// TODO - Your solution
int N= args.length;
int [] array = new int [N];
int new_length=0;
int location=0;
int max=0;
int current_length=0;
//assign digits into array
for (int i=0; i < N; i++){
int number = Integer.parseInt(args[i]);
array [i] = number;
}
int compare=array[0];
for (int l=0; l<N; l++){
if (array[l] < compare){
current_length=0;
compare = array[l];
}
else if (array[l] == compare){
current_length+=1;
compare = array[l];
}
else if (array[l] > compare){
compare=array[l];
l++;
}
compare= array[l];
for (int b=0; b<N; b++){
if (current_length > max){
max = current_length;
location = array[l];
new_length=max-1;
}
else if (current_length==1){
new_length=max;
}
}
}
System.out.println(location);
System.out.println(new_length);
}
}
Issue is that for the input of "1 2 3 4" I continously get an Array Index out of bounds error.
Before you start writing code, try and think how a human would have solved it.
e.g.
For every item in the input, compare it to the previous, if it's larger, start a new sequence length check (write 0 in your notebook under - "current sequence length)), if it's the same, increase it by 1, if it's less, mark that sequence length as complete. if it's larger than your largest sequence length so far (started with 0) then this is now your largest sequence, if not, ignore that sequence length and move on to the next character. (or something like this)
write these instructions to yourself as a human, and try to follow them, and fix them as you find edge cases. Once you have a working human language algorithm, writing the code will be almost self driven.
You really need to post the specific issue you are seeing, how your actual results differ from your expected results, and what solutions you have attempted.
In any case, as for the general "how to proceed" question, I find that it often helps to work out these types of problems on paper first. Write down your sequence and step through it, observe what information you need to keep track of and what logic you need to apply to produce the desired results. Once you are able to do this, it will be far more straightforward to translate your clearly thought out algorithm into concrete code.
It appears you are at least somewhat on the right track parsing and storing your integer array, but you are a bit misguided with your [t+?] lookaheads. If you write this out and step through it by hand, you may be surprised at what you come up with.
Here is a full program description with test cases:
Given an array of integers int A[], find the length and location of the longest contiguous sequence of equal values for which the values of the elements just before and just after this sequence are smaller.
You should just print these two numbers (first is the length and second is the starting index of the plateau).
To complete the definition, we can consider there are imaginary index positions at A[-1] and A[A.length] where A[-1] < A[0] and A[A.length] < A[A.length-1]. Therefore, the plateau can start/end at both ends of array A. This condition guarantees the existence of a plateau. A plateau can be of length 1.
Example 1:
java LongestPlateau 1 2 2 2 2 1
With this command line arguments, program should print:
4
1
Example 2:
java LongestPlateau 1 2 2 2 2 3
With this command line arguments, program should print:
1
5
Example 2:
java LongestPlateau 3 2 2 2 1 2 1 1 1 2 2 0 1 1 1 1 0
With this command line arguments, program should print:
4
12
Example 2:
java LongestPlateau 3 2 2 2 2 2 2 1 2 1 1 1 2 2 0 1 1 1 1
With these command-line arguments, the program should print:
4
15
Here is my solution:
public class LongestPlateau {
private static int[] parseInputArray(String[] args) {
int[] value = new int[args.length+1];
for(int i = 0 ; i < args.length; i++){
if (i == args.length-1) value[i] = 0; // this imaginary last value of the array ensures that if the plateau is the last value of the array, then it outputs the correct answer
value[i] = Integer.parseInt(args[i]);
}
return value;
}
public static void printLargestPlateau(int[] values) {
int biggestStartIndex = -1;
int biggestLength = 0;
int currentIndex = 1;
int currentPlateauStartIndex = 1;
int currentLength = 1;
boolean plateauStarted = false;
while (currentIndex < values.length) {
if(isStartOfPlateau(currentIndex, values)){
currentLength = 1;
plateauStarted = true;
currentPlateauStartIndex = currentIndex;
} else if (isEndOfPlateau(currentIndex, values)) {
if(plateauStarted && currentLength > biggestLength){
biggestLength = currentLength;
biggestStartIndex = currentPlateauStartIndex;
}
plateauStarted = false;
currentLength = 1;
} else {
currentLength++;
}
currentIndex++;
}
System.out.println(biggestLength +"\n"+biggestStartIndex);
}
private static boolean isStartOfPlateau(int index, int[] values){
if(index <= 0){
return false;
}
return values[index-1] < values[index];
}
private static boolean isEndOfPlateau(int index, int[] values){
if(index <= 0){
return false;
}
return values[index - 1] > values[index];
}
public static void main(String[] args) {
int[] values = parseInputArray(args);
printLargestPlateau(values);
}
}