I'm putting together a code to output the following pattern:
000000000X
00000000XX
0000000XXX
000000XXXX
00000XXXXX
0000XXXXXX
000XXXXXXX
00XXXXXXXX
0XXXXXXXXX
(each line should be one after another. I'm not quite sure how to display the pattern on forums...sorry)
I'm supposed to use a recursive loop inside the code but I end up in an infinite loop and I really don't understand why..(It may be ok to assue that I've never used a recursive loop practically).This is my code:
class Recursion {
//recursion should stop after 9 attempts
static int stopindex = 9;
public static void main(String[] args) {
//a=number of "O"s and b=number of "X"s
int a = 9;
int b = 1;
recursion(a, b);
}
public static void recursion(int a, int b) {
//start of recursion at index 1
int startindex = 1;
//stop condition of recursion
if (startindex == stopindex)
return;
//printing of pattern
for (int i = a; i > 0; i--) {
System.out.print("O");
}
for (int j = 0; j < b; j++) {
System.out.print("X");
}
System.out.println();
--a;
++b;
++startindex;
recursion(a, b);
}
}
Your algorithm is slightly off, you shouldn't have the static variables and you shouldn't change a, and your first for loop condition - I think you wanted,
public static void recursion(int a, int b) {
// stop condition of recursion
if (a == b) return;
// printing of pattern
for (int i = a - b; i > 0; i--) {
System.out.print("O");
}
for (int j = 0; j < b; j++) {
System.out.print("X");
}
System.out.println();
// --a;
++b; // <-- this could be done in the recursion call below,
recursion(a, b);
// recursion(a, ++b); // <-- like that.
}
The output is
OOOOOOOOX
OOOOOOOXX
OOOOOOXXX
OOOOOXXXX
OOOOXXXXX
OOOXXXXXX
OOXXXXXXX
OXXXXXXXX
You are resetting the variable startindex at the start of recursion method, so if the recursion method is called and startindex is increased by one and then the method is called upon again the variable will be reset, due to int startindex = 1;.
class Recursion {
static int stopindex = 9;
int startindex = 1;
public static void main(String[] args) {
//a=number of "O"s and b=number of "X"s
int a = 9;
int b = 1;
recursion(a, b);
}
public static void recursion(int a, int b) {
//start of recursion at index 1
//int startindex = 1; - removed due to variable reset
//stop condition of recursion
if (startindex == stopindex)
return;
//printing of pattern
for (int i = a; i > 0; i--) {
System.out.print("O");
}
for (int j = 0; j < b; j++) {
System.out.print("X");
}
System.out.println();
--a;
++b;
++startindex;
recursion(a, b);
}
}
Your problem is that your start index gets reset each time the function is called. Try this code
class Recursion {
//recursion should stop after 9 attempts
static int stopindex = 9;
public static void main(String[] args) {
//a=number of "O"s and b=number of "X"s
int a = 9;
int b = 1;
int startindex = 1;
recursion(a, b, startindex);
}
public static void recursion(int a, int b, int startIndex) {
//start of recursion at index 1
//stop condition of recursion
if (startIndex > stopindex)
return;
//printing of pattern
for (int i = a; i > 0; i--) {
System.out.print("O");
}
for (int j = 0; j < b; j++) {
System.out.print("X");
}
System.out.println();
--a;
++b;
++startIndex;
recursion(a, b, startIndex);
}
}
Output
OOOOOOOOOX
OOOOOOOOXX
OOOOOOOXXX
OOOOOOXXXX
OOOOOXXXXX
OOOOXXXXXX
OOOXXXXXXX
OOXXXXXXXX
OXXXXXXXXX
You don't need startindex at all - your parameter a is all you need to formulate the halting condition for the recursion. For every recursive invocation of recusion, a is one less and once a == 0 you break the recursion.
As is, you are resetting startindex to 1 every time so the breaking condition is always false.
public static void recursion(int a, int b) {
if (a == 0) {
return;
}
// Print here
recursion(a - 1, b + 1);
}
Related
I was learning to merge sort an integer array, when I noticed that while copying the sorted array elements to the original array, we need two separate loop variables to run simultaneously, while the values at those indices are copied to the original array. Here is the code for reference:
class MergeSort {
public static void sort(int arr[], int si, int ei, int mid) {
int merged[] = new int[ei - si + 1];
int index1 = si; // tracks the first array
int index2 = mid + 1; // tracks the second array
int i = 0;
while (index1 <= mid && index2 <= ei) {
if (arr[index1] <= arr[index2]) {
merged[i++] = arr[index1++];
} else {
merged[i++] = arr[index2++];
}
} // end of while
while (index1 <= mid) {
merged[i++] = arr[index1++];
}
while (index2 <= ei) {
merged[i++] = arr[index2++];
}
// to copy merged[] to arr[]
int j = si;
for (i = 0; i < merged.length; i++, j++) {
arr[j] = merged[i];
}
} // end sort()
public static void divide(int arr[], int si, int ei) {
// base case
if (si >= ei) {
return;
} // end of base case
int mid = si + (ei - si) / 2; // same as (ei-si)/2 but with less space complexity
divide(arr, si, mid);
divide(arr, mid + 1, ei);
sort(arr, si, ei, mid);
} // end of divide
public static void main(String args[]) {
int arr[] = { 1, 8, 0, 7, -4 };
int n = arr.length;
divide(arr, 0, n - 1);
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
} // end of for
} // end of main
} // end of class
Notice that while copying the values of the array merged[] to the array arr[], we are using two separate variables i and j. I did try using only one loop variable, which went like:
for (int i = 0; i < arr.length; i++) {
arr[i] = merged[i];
}
but received an incorrect output. If anyone knows why we need two separate variables for the operation, please let me know. Thank you :)
You could use a single variable in this final loop, but you must add the offset of the start of the slice in the destination array:
for (int i = 0; i < arr.length; i++) {
arr[si + i] = merged[i];
}
I am getting a StackOverflowError for this code. It says lines 184/185, which is where I initialize the split position (see below) and call the first recursive quickSort method. I can see that the code is having trouble exiting from the recursion, but I'm not sure where that is happening. Each time I call quickSort, it is on a smaller partition.
import java.util.*;
public class java2{
public static int MAXINT = 10000;
public static int[] intArray = new int[MAXINT];
public static int index;
public static long comparisons;
public static void main(String[] args)
{
System.out.println("SORTING ALGORITHM: Quicksort");
// Create a random array of integers and sort using the CombSort algorithm
// Print the number of items and comparisions
for(index = 10; index <= 10000; index = index * 10)
{
if (index == 10)
for(int i = 0; i < index; i++)
System.out.print(intArray[i] + " ");
comparisons = 0;
generate(intArray, index);
quickSort(intArray, 0, index - 1);
output(comparisons);
}
}
// Generate an array of random values between 0 and 10000
public static void generate(int[] valueArray, int count)
{
Random generator = new Random();
for(int temp = 0; temp < count; temp++)
{
valueArray[temp] = generator.nextInt(MAXINT) + 1;
}
}
// Print the number of values in the array and the number of comparisons
public static void output(long count)
{
System.out.println("Number of values in array: " + index);
System.out.println("Number of comparisons required: " + count);
System.out.println();
}
//Swap the given values and then assign them to the correct place in the array
public static void swap(int[] value, int i, int j)
{
int temp = value[i];
value[i] = value[j];
value[j] = temp;
}
//Implement Quicksort algorithm
public static void quickSort(int[] value, int startIndex, int endIndex)
{
int r = endIndex;
int l = startIndex;
int s;
if (l < r)
{
s = partition(intArray, l, r);
quickSort(intArray, l, s - 1); // StackOverflowError here
quickSort(intArray, s + 1, r);
}
}
//Partition an array into two parts
public static int partition(int[] value, int startIndex, int endIndex)
{
int r = endIndex;
int l = startIndex;
int p = value[l];
int i = l;
int j = r + 1;
while(i < j)
{
while(value[i] < p)
{
i++;
comparisons++;
}
while(value[j] > p)
{
j--;
comparisons++;
}
swap(value, i, j);
}
swap(value, i, j);
swap(value, l, j);
return j;
}
} // end main
Here are a few things to get you started with debugging.
You haven't posted your swap, but it's almost certainly incorrect. The way you're using it, its prototype would be void swap(int, int, int, int) which means it cannot have any effect on the value array. Try something like this:
public static void swap(int[] value, int i, int j) {
int temp = value[i];
value[i] = value[j];
value[j] = temp;
}
and use it like this:
swap(value, i, j);
Next, get the length=10 case correct. Print out the full array before and after sort, verify that the output is correct. When I run your code on an all zero array I get an infinite loop.
Next, if you're still having problems, add print statements!
By restructuring the partition method, the problem has been fixed:
public static int partition(int[] value, int p, int r)
{
int x = value[p];
int i = p - 1;
int j = r + 1 ;
while (true)
{
do
{
j--;
comparisons++;
}
while (value[j] > x);
do
{
i++;
comparisons++;
}
while (value[i] < x);
if (i < j)
{
swap(value, i, j);
}
else
return j;
}
}
There's a mergeSort code that I copied at class lesson, can you help me to find the errors?
When I run the main that use mergeSort the program enters in an infinite loop but doesn't display any error. I tried to run in debug mode but I am not very expert and I don't find what's wrong. However I think that the error is in mergeSort(int[] v, int inf, int sup) recursion.
public class CopyOfSortMethods {
private static void merge(int[] v, int inf, int med, int sup) {
int aux[] = new int[v.length];
int i = inf;
int j = med + 1;
int k = inf;
while ((i <= med) && (j <= sup)) {
if (v[i] < v[j]) {
aux[k] = v[i];
i++;
k++;
} else {
aux[k] = v[j];
j++;
k++;
}
}
while (i <= med) {
aux[k] = v[i];
i++;
k++;
}
while (j <= sup) {
aux[k] = v[j];
j++;
k++;
}
for (i = 0; i <= sup; i++) {
v[i] = aux[i];
}
}
public static void mergeSort(int[] v, int inf, int sup) {
int med;
while (inf < sup){
med = (inf + sup)/2;
mergeSort(v, inf, med);
mergeSort(v, med + 1, sup);
merge(v, inf, med, sup);
}
}
public static void mergeSort(int[] v) {
if(v!=null) {
mergeSort(v, 0, v.length - 1);
}
}
}
As Maverik points out, the issue is the while loop in mergeSort().
inf and sup are never modified, so inf is always less than sup. The loop never terminates.
The problems in your merge sort (based in the comments):
In mergeSort method, you're recursively calling the mergeSort inside a while loop and never changing the values of inf and sup. Change this for an if instead.
if (inf < sup) {
//code goes here...
}
In your merge sort, at the bottom of the method body, you're moving the items all the items from aux array to v array. You should only move the elements between inf and sup:
//for (i = 0; i <= sup; i++) {
for (i = inf; i <= sup; i++) {
//code goes here...
}
The purpose of this program is to find the kth smallest element in an array without sorting the array using a recursive and nonrecursive decrease and conquer type method.
I was hoping someone could look over my code and try to help me with my array out of bounds error(s).
The method that is throwing these errors is the recursive selection the non recursive selection works fine.
My driver is also attached and everything should compile if you want to test my code.
public class KthSmallest
{
private int counter;
private int term;
private int[] A;
int SelectionNonRecursive(int A[], int kthSmallest, int sizeOfA)
{
this.A = A;
if(kthSmallest == 1 || kthSmallest == sizeOfA)
{
return (LinearSearch(kthSmallest, sizeOfA));
}
else
{
for(int i = 0; i<sizeOfA; i++)
{
counter = 0;
for(int j = 0; j<sizeOfA; j++)
{
if(A[i] < A[j])
{
counter++;
}
}
if((sizeOfA - counter) == kthSmallest)
{
return A[i];
}
}
}
return 0;
}
int SelectionRecursive(int A[], int kthSmallest, int sizeOfA)
{
this.A = A;
return Selection_R(0, sizeOfA - 1, kthSmallest);
}
int Selection_R(int l, int r, int kthSmallest)
{
if(l<r)
{
if(kthSmallest == 1 || kthSmallest == A.length)
{
return (LinearSearch(kthSmallest, A.length));
}
else
{
int s = LomutoPartition(l, r);
if(s == kthSmallest - 1)
{
return A[s];
}
else if(s > (A[0] + kthSmallest - 1))
{
Selection_R(l, s-1, kthSmallest);
}
else
{
Selection_R(s+1, r, kthSmallest);
}
}
}
return 0;
}
int LomutoPartition(int l, int r)
{
int pivot = A[l];
int s = l;
for(int i = l+1; i<r; i++)
{
if(A[i] < pivot)
{
s += 1;
swap(A[s], A[i]);
}
}
swap(A[l], A[s]);
return s;
}
public void swap(int i, int j)
{
int holder = A[i];
A[i] = A[j];
A[j] = holder;
}
int LinearSearch(int kthSmallest, int sizeOfA)
{
term = A[0];
for(int i=1; i<sizeOfA; i++)
{
if(kthSmallest == 1)
{
if(term > A[i])
{
term = A[i];
}
}
else
{
if(term < A[i])
{
term = A[i];
}
}
}
return term;
}
}
public class KthDriver
{
public static void main(String[] args)
{
KthSmallest k1 = new KthSmallest();
int[] array = {7,1,5,9,3};
System.out.print(k1.SelectionRecursive(array, 3, array.length));
}
}
Inside your LomutoPartition method, you are passing the array elements in your swap method: -
swap(A[s], A[i]); // Inside for loop
and
swap(A[l], A[s]); // Outside for loop
And your swap method considers them as indices: -
public void swap(int i, int j) <-- // `i` and `j` are elements A[s] and A[i]
{
int holder = A[i]; <-- // You are accessing them as indices(A[i] -> A[A[s]])
A[i] = A[j];
A[j] = holder;
}
That is why you are getting that exception. Because, if any element in array is greater than size, it will blast out.
You should change your invocation to: -
swap(s, i); // Inside for loop
and
swap(l, s); // Outside for loop
respectively. And leave your method as it is.
Note that, you should pass array indices, and not array elements. If you pass array elements, then the swapping in the method will not be reflected in your array. Because, your method will have its own copy of your elements.
public class sequence {
public static void main(String args[]){
char[] c = {'a','x','c','e'};
char[] t = {'x','b'};
int count = 0,j;
for(int i=0;i<(c.length);i++)
{
int p = i;
int x = 0;
for( j=0;j<(t.length);j++){
if(c[p]!=c[j]){
break;
}
else
x++;
System.out.print(x);
if(x==((t.length))){
count++;
}
p++;
}
System.out.print('a');
}
System.out.println("Number of Occurences " + count);
}
}
My task is to count the number of time the sequence ie t[] occurs in the mother array c[].
I am not able to get the required result even though i tries all the iterations in my mind where it worked well.I am kind of a starter in programming so need some help here.
Thankya!
You should take this piece of code:
if(x==((t.length))){
count++;
}
From the inner loop.
The problem is that your x == t.length check is inside your inner for loop, but your inner for loop will never let x reach t.length. Also, your x variable is redundant and is always equal to j so it can be removed.
To fix this, move your length-check to the outside of the loop.
Edit: Also, you're accessing the wrong array in your inner loop (where the break statement is).
public static void main(String args[]){
char[] c = {'a','x','c','e'};
char[] t = {'x','b'};
int count = 0, j;
for (int i = 0; i < (c.length); i++) {
int p = i;
for (j = 0; j < (t.length); j++){
if (c[p] != t[j]) {
break;
}
p++;
}
if (j == t.length){
count++;
}
}
System.out.println("Number of Occurences " + count);
}
You shouldn't need two for loops:
public static void main(String args[]){
char[] c = {'a','x','b','c','x','b','e'};
char[] t = {'x','b'};
int count = 0;
int tInd = 0;
for(int i=0;i<(c.length);i++)
{
if(tInd < t.length && t[tInd] == c[i]){ // Found a member of t[]
tInd ++;
} else {
tInd = 0; // Didn't find t[]
}
if(tInd == t.length){ // Found full t[] sequence
count++;
tInd = 0;
}
}
System.out.println("Number of Occurences " + count);
}
You don't need to loop on all c elem (you can stop in the position of last possible match). In the inner loop as soon as you find a match you must continue on next c elem:
public static void main(String[] args) {
char[] c = {'c','a','x','b'};
char[] t = {'x','b'};
int count = 0, j;
for(int i=0;i<=(c.length-t.length);i++)
{
for(j=0;j<(t.length);j++){
if(t[j]!=c[i+j]){
break;
}
}
if(j==t.length)
count++;
}
System.out.println("Number of Occurences " + count);
}