Array size changed after sorting - c

I'm currently working on an assignment which tells me to get the largest count number on a sequence in a array (ex: arr[] = {1,2,3,4,5}, valid sequence is {1,2},{2,3},{5}, or {2,3,4,5}. I've used an algorithm that finds the largest value of an array without sorting it, but, the online judge considers it wrong because it ran for too long (Time Limit Error). So I've changed my code to use a sorting algorithm.
I'm trying to find the largest value in an array by sorting it first, then printing the last value (biggest) of the array, which worked if I input this:
Input:
1 // cases
3 2
2 2 2
Output:
SIZE of Array is: 3
UNSORTED countArr:
0. 1
1. 1
2. 1
(after sorting) SORTED countArr:
0. 1
1. 1
2. 1
However, if I try to have to input multiple "cases" I would get:
Input:
2 // cases
4 11
2 9 1 1
3 2
2 2 2
Output:
SIZE of Array is: 4
UNSORTED countArr:
0. 2
1. 3
2. 2
3. 1
(after sorting) SORTED countArr:
0. 1
1. 2
2. 2
3. 3
SIZE of Array is: 4 //why did the array size become 4, instead of 3
UNSORTED countArr:
0. 1
1. 1
2. 1
3. 3 // and what is this 3 doing here? it should have ended at number 2.
(after sorting) SORTED countArr:
0. 1
1. 1
2. 1
3. 3 // same as above
If anyone could help, could you tell me where I'm wrong?
Source code:
#include <stdio.h>
// all function is for quicksort
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition (int arr [], int low, int high) {
int pivot = arr [high];
int i = (low - 1);
for (int j = low; j <= high- 1; j++) {
if (arr [j] < pivot) {
i++;
swap (&arr [i], &arr [j]);
}
}
swap (&arr [i + 1], &arr [high]);
return (i + 1);
}
void quickSort (int arr[], int low, int high) {
if (low < high) {
int pi = partition (arr, low, high);
quickSort (arr, low, pi - 1);
quickSort (arr, pi + 1, high);
}
}
int main () {
int cases, numofElement;
int limit, set [5001], sum = 0, count = 0, countArr [100001], size = 0, largest;
int i, j, k, l, m;
scanf ("%d", &cases);
for (i = 0; i < cases; i++) {
scanf ("%d %d", &numofElement, &limit);
for (j = 0; j < numofElement; j++) {
scanf ("%d", &set [j]);
}
// so the program knows if the array 'set []' is reaching its last digit
set [numofElement] = -2;
for (k = 0; k < numofElement; k++) {
if (set [k] > limit) {
// to skip over or (if all sequence is invalid) to print "-1"
countArr [k] = -1;
continue;
}
for (l = k; l < numofElement; l++) {
sum += set [l];
count += 1;
if ((sum <= limit) && (sum + set [l + 1] > limit || set [l + 1] == -2)) {
countArr [k] = count;
sum = 0;
count = 0;
break;
}
}
}
// count how many number there are in 'countArr []', so we can find its largest value
size = 0;
l = 0;
while (countArr [l] != 0) {
size += 1;
l++;
}
printf ("SIZE of Array is: %d\n", size);
printf ("UNSORTED countArr:\n");
for (j = 0; j < size; j++) {
printf ("%d. %d\n", j, countArr [j]);
}
// sort the 'temp []' array, and output its largest value
quickSort (countArr, 0, size - 1);
printf ("(after sorting) SORTED countArr:\n");
for (j = 0; j < size; j++) {
printf ("%d. %d\n", j, countArr [j]);
}
}
return 0;
}

Is a simple error, you don't reset the element of countArr array to 0 at the beginning of the first for cycle.
If you fix this your program should work.
After this istruction you need to add the reset to zero :
for (i = 0; i < cases; i++){
... reset to zero countArr
... rest of the programm
}

Related

I have Mysterious C code witch have different behavior at same test case , I think it is coodblock problem

This code should give the max number in array but when I Enter
4 3 2 1 it give me 3 But if I enter 5 4 3 2 it gives me 5
So can any one tell me why there are 2 behaviors for the same case ?
int max_of_four(int a, int b, int c, int d){
int arr[4]= {a,b,c,d};
int i , j;
for (i=0 ; i<=3 ;i ++)
{
for (j=i+1 ; j<=3 ; j++)
{
if (arr[i]>arr[j])
{
continue;
}
else
break;
}
if (arr[i]>arr[j])
{
return arr[i];
}
}
return arr[j];
}
For your inner loop, if the element at index i is the largest value then the inner loop goes through all values of j from 0 to 3, and j will be 4 when the loop exits. When you then check arr[i]>arr[j], you're reading past the end of the array when j is 4. Reading past the end of an array invokes undefined behavior, which is why you see inconsistent results.
Instead, check if j is 4. If it is, you know you arr[i] is the largest.
for (j=i+1 ; j<=3 ; j++)
{
if (arr[i]>arr[j])
{
continue;
}
else
break;
}
if (j == 4)
{
return arr[i];
}
To find the max value in an array you only need to iterate over the array once.
int max_of_four(int a, int b, int c, int d)
{
int[] arr= {a,b,c,d};
int i = 0;
// set max as the first element in the array
int max = arr[0]; // arr[0]
// loop index from 1 to 3
for (i = 1; i <= 3; i++)
{
// if element is greater than current max
if (arr[i] > max)
max = arr[i];
}
return max;
}
// output
// max_of_four(4,3,2,1):
// 4
// max_of_four(1,5,4,2):
// 5

Generating k permutations from n in C

I basically need the equivalent result of the following Python itertools command in C:
a = itertools.permutations(range(4),2))
Currently my process involves first "choosing" 5 elements from 10 then generating permutations for those 5 elements as shown here
The issue with this approach is the order of the outputs. I need it to be (a), while what i get is (b), shown below.
a = itertools.permutations(range(4),2)
for i in a:
print(i)
(0, 1)
(0, 2)
(0, 3)
(1, 0)
(1, 2)
(1, 3)
(2, 0)
(2, 1)
(2, 3)
(3, 0)
(3, 1)
(3, 2)
b = itertools.combinations(range(4),2)
for i in b:
c = itertools.permutations(i)
for j in c:
print(j)
(0, 1)
(1, 0)
(0, 2)
(2, 0)
(0, 3)
(3, 0)
(1, 2)
(2, 1)
(1, 3)
(3, 1)
(2, 3)
(3, 2)
An alternate approach which I am using is as follows
void perm(int n, int k)
{
bool valid = true;
int h = 0, i = 0, j = 0, limit = 1;
int id = 0;
int perm[10] = { 0,0,0,0,0,0,0,0,0,0 };
for (i = 0; i < k; i++)
limit *= n;
for (i = 0; i < limit; i++)
{
id = i;
valid = true;
for (j = 0; j < k; j++)
{
perms[j] = id % n;
id /= n;
for (h = j - 1; h >= 0; h--)
if (perms[j] == perms[h])
{
valid = false; break;
}
if (!valid) break;
}
if (valid)
{
for (h = k - 1; h > 0; h--)
printf("%d,", perms[h]);
printf("%d\n", perms[h]);
count++;
}
}
}
Memory is my constraint, so I cannot store the permutations indefinitely. Performance needs to be better than the algorithm above, as when n is 50 and k is 10, I end up iterating through more invalid combinations(60+%)
I am aware of Heap's algorithm for generating permutations in place but again it generates for entire array not k of n like I need.
Questions.
Is there a better way to do this than iterate n^k times?
Can I make a lazy iterator which moves to next permutation given current permutation?
EDIT this is not a duplicate of std::next_permutation implementation as that will permute and entire range of the input.
I have clearly mentioned i need k of n permutation .ie if my range is 10 I want all permutations of a length (k) say 5, std::next_permutation works when length or permutation is same as length of input range
UPDATE
Here is an ugly recursive NextPerm solution which is about 4 times faster than my older solution and gives the incremental nextPerm like a Python lazy iterator.
int nextPerm(int perm[], int k, int n)
{
bool invalid = true;
int subject,i;
if (k == 1)
{
if (perm[0] == n - 1)
return 0;
else { perm[0]=perm[0]+1; return 1; }
}
subject = perm[k - 1]+1;
while (invalid)
{
if (subject == n)
{
subject = 0;
if (!nextPerm(perm, k - 1, n))
return 0;
}
for (i = 0; i < k-1; i++)
{
if (perm[i] != subject)
invalid = false;
else
{
invalid = true;subject++; break;
}
}
}
perm[k - 1] = subject;
return 1;
}
int main()
{
int a, k =3 ,n = 10;
int perm2[3] = { 0,1,2}; //starting permutation
unsigned long long count = 0;
int depth = 0;
do
{
for (a = 0; a < k - 1; a++)
printf("%d,", perm2[a]);
printf("%d\n", perm2[k - 1]);
count++;
}
while (nextPerm(perm2,k,n));
printf("\n%llu", count);
getchar();
return 0;
}
There are simple modification to the standard permutation algorithms which will produce k-permutations.
Lexicographically-ordered permutations (aka std::next_permutation)
In C++, k-permutations can be generated by the simple expedient using std::next_permutation, and just reversing the n-k-suffix of the permutation before each call to std::next_permutation.
It's reasonably clear how that works: the algorithm generates permutations in order, so the first permutation starting with a given prefix has the remaining suffix in increasing order, and the last permutation with the same prefix has its suffix in decreasing order. Decreasing order is simply the reverse of increasing order, so a single call to std::reverse is sufficient.
The lexicographical order next-permutation algorithm is very simple:
Search backwards from the end for an element which could be increased by swapping it with some later element.
Once the rightmost such element is found, find the smallest following element with which it could be swapped, and swap them.
Sort the new suffix into increasing order (by reversing it, since it was previously in decreasing order).
An advantage of the lexicographical algorithm is that it transparently handles arrays with repeated elements. As long as the number of repetitions of any given element is O(1), next-permutation is amortized O(1) (per call), and in the worst case it is O(n). When generating k-permutations, the extra flip causes the cost of next_k_permutation to be O(n-k), which is effectively O(n) if k is fixed. That's still reasonably fast, but not as fast as non-iterative algorithms which can maintain state instead of doing the search in step 1 to figure out which element to move.
The following C implementation is equivalent to std::reverse(); std::next_permutation(); (except that it swaps before reversing):
#include <stddef.h>
/* Helper functions */
static void swap(int* elements, size_t a, size_t b) {
int tmp = elements[a]; elements[a] = elements[b]; elements[b] = tmp;
}
static void flip(int* elements, size_t lo, size_t hi) {
for (; lo + 1 < hi; ++lo, --hi) swap(elements, lo, hi - 1);
}
/* Given an array of n elements, finds the next permutation in
* lexicographical order with a different k-prefix; in effect, it
* generates all k-permutations of the array.
* It is required that the suffix be sorted in ascending order. This
* invariant will be maintained by the function.
* Before the first call, the array must be sorted in ascending order.
* Returns true unless the input is the last k-permutation.
*/
int next_k_permutation(int* elements, size_t n, size_t k) {
// Find the rightmost element which is strictly less than some element to its
// right.
int tailmax = elements[n - 1];
size_t tail = k;
while (tail && elements[tail - 1] >= tailmax)
tailmax = elements[--tail];
// If no pivot was found, the given permutation is the last one.
if (tail) {
size_t swap_in;
int pivot = elements[tail - 1];
// Find the smallest element strictly greater than the pivot, either
// by searching forward from the pivot or backwards from the end.
if (pivot >= elements[n - 1]) {
for (swap_in = tail; swap_in + 1 < k && elements[swap_in + 1] > pivot; ++swap_in) {}
} else {
for (swap_in = n - 1; swap_in > k && elements[swap_in - 1] > pivot; --swap_in) {}
}
// Swap the pivots
elements[tail - 1] = elements[swap_in];
elements[swap_in] = pivot;
// Flip the tail.
flip(elements, k, n);
flip(elements, tail, n);
}
return tail;
}
Here's a simple driver and a sample run:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int intcmp(const void* a, const void* b) {
return *(int*)a < *(int*)b ? -1 :
*(int*)a > *(int*)b ? 1 :
0 ;
}
int main(int argc, char** argv) {
size_t k = (argc > 1) ? atoi(argv[1]) : 0;
if (argc < k + 2) {
fprintf(stderr, "Usage: %s K element...\n"
" where K <= number of elements\n",
argv[0]);
return 1;
}
size_t n = argc - 2;
int elements[n];
for (int i = 0; i < n; ++i) elements[i] = atoi(argv[i + 2]);
qsort(elements, n, sizeof *elements, intcmp);
do {
const char* delimiter = "";
for (size_t i = 0; i < k; ++i) {
printf("%s%2d ", delimiter, elements[i]);
delimiter = " ";
}
putchar('\n');
} while (next_k_permutation(elements, n, k));
return 0;
}
Sample run (with repeated element):
$ ./k_next_permutation 2 7 3 4 4 5
3 4
3 5
3 7
4 3
4 4
4 5
4 7
5 3
5 4
5 7
7 3
7 4
7 5
Modified Heap's algorithm
As an example of an algorithm which maintains state, Heap's algorithm can be easily modified to produce k-permutations. The only change is that when the algorithm recurses down to position n - k, the k-suffix is reported as the k-permutation and the (n-k)-prefix is transformed the way the Heap algorithm would transform it if it were run to conclusion: the prefix reversed if its length is odd and rotated one to the left if its length is even. (That's a big hint about how Heap's algorithm works, by the way.)
Using the recursive algorithm is a bit annoying because it doesn't really allow incremental permutations. However, it's simple to follow. Here, I've just passed a functor into the recursive procedure which is called with each permutation in turn.
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
/* Helper functions */
static void swap(int* elements, size_t a, size_t b) {
int tmp = elements[a]; elements[a] = elements[b]; elements[b] = tmp;
}
static void flip(int* elements, size_t lo, size_t hi) {
for (; lo + 1 < hi; ++lo, --hi) swap(elements, lo, hi - 1);
}
static void rotate_left(int* elements, size_t lo, size_t hi) {
if (hi > lo) {
int tmp = elements[lo];
for (size_t i = lo + 1; i < hi; ++i) elements[i - 1] = elements[i];
elements[hi - 1] = tmp;
}
}
/* Recursive function; the main function will fill in the extra parameters */
/* Requires hi >= lo and hi >= k. Array must have size (at least) lo + k */
static bool helper(int* array, size_t lo, size_t k, size_t hi,
bool(*process)(void*, int*, size_t), void* baton) {
if (hi == lo) {
if (!process(baton, array + lo, k)) return false;
if (lo % 2)
flip(array, 0, lo);
else
rotate_left(array, 0, lo);
}
else {
for (size_t i = 0; i < hi - 1; ++i) {
if (!helper(array, lo, k, hi - 1, process, baton))
return false;
swap(array, hi % 2 ? 0 : i, hi - 1);
}
if (!helper(array, lo, k, hi - 1, process, baton))
return false;
}
return true;
}
/* Generate all k-permutations of the given array of size n.
* The process function is called with each permutation; if it returns false,
* generation of permutations is terminated.
*/
bool k_heap_permute(int* array, size_t n, size_t k,
bool(*process)(void*, int*, size_t), void* baton) {
assert(k <= n);
return helper(array, n - k, k, n, process, baton);
}
Here's an example of its use:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool print_array(void* vf, int* elements, size_t n) {
FILE* f = vf;
const char* delim = "";
for (size_t i = 0; i < n; ++i) {
fprintf(f, "%s%2d", delim, elements[i]);
delim = " ";
}
putc('\n', f);
return true;
}
int main(int argc, char** argv) {
size_t k = (argc > 1) ? atoi(argv[1]) : 0;
if (argc < k + 2) {
fprintf(stderr, "Usage: %s K element...\n"
" where K <= number of elements\n",
argv[0]);
return 1;
}
size_t n = argc - 2;
int elements[n];
for (int i = 0; i < n; ++i)
elements[i] = atoi(argv[i + 2]);
k_heap_permute(elements, n, k, print_array, stdout);
return 0;
}
Sample run:
$ ./permut 2 1 5 9 7 3
7 3
9 3
5 3
1 3
1 5
7 5
9 5
3 5
3 9
1 9
7 9
5 9
5 7
3 7
1 7
9 7
9 1
5 1
3 1
7 1

arranging the numbers with duplicate entries deleted

#include<stdio.h>
int main(){
int a[9],i,j,r,t,min,c=0;
for(r=0;r<9;r++)
scanf("%d",&a[r]);
for (j=0;j<9;j++) {
min=a[j];
for(i=j;i<9;i++) {
if(a[i] < min ) {
c=i;
min=a[i];
}
}
t=a[j];
a[j]=min;
a[c]=t;
}
for(r=0;r<9;r++)
printf("%d",a[r]);
}
This is the code which i have to arrange the numbers entered byt the user in ascending order.
If input is 1 2 3 2 4 1 5 6 3 output is 1 1 2 2 3 3 4 5 6 but i want the output to be 1 2 3 4 5 6 i.e. duplicate entries deleted.Please help me.
If the range of the numbers is given then you can do it by using a boolean array which will store 1 to the corresponding index of the element.
#include <stdio.h>
#include <stdbool.h>
#define NUM_RANGE 10
int main(){
int num;
bool freq[NUM_RANGE + 1] = {0};
for(int r = 0; r < 9; r++){
scanf("%d",&num);
freq[num] = 1;
}
for (int i = 0; i < NUM_RANGE + 1; i++)
if(freq[i])
printf("%d ", i);
}
#include<stdio.h>
int main(){
int a[] = {1, 2, 3, 2, 4, 1, 5, 6, 3};
int n = sizeof(a)/sizeof(*a);
int i, j, t;
for (j=0;j<n-1;j++){
for(i=j+1;i<n;){
if(a[i] == a[j]){
t = a[i];
a[i] = a[--n];
a[n] = t;
continue;
}
if(a[i] < a[j]){
t = a[i];
a[i] = a[j];
a[j] = t;
}
++i;
}
}
for(i=0;i<n;i++)
printf("%d ", a[i]);
return 0;
}
So, this is the procedure you can follow.
You sort your array (as you have already done). Your sorting algorithm has O(n^2) worst-case-running time where n is the number of Elements in your array. If you care about running time, the optimal running time which can be achieved is O(n logn) [MergeSort].
Next, we need to find the duplicates and delete them.
Since you have already ordered them just loop through your array and check that every number a[i] and the next number a[i+1] are different. If they are not, delete it and fill the empty space by moving all the rest of the array one forward.
So:
for(i = 0; i < 9; i++){
if(a[i] == a[i+1]){
deletNumber(i); //deletes number at position i in the array and shifts the
//rest of the array so the empty space is filled.
}
}
void deleteNumber(int i){
int j;
for(j = i; j<8; j++){
a[j] = a[j++];
}
}

Absurd condition in Longest Increasing Subquence

/* A Naive recursive implementation of LIS problem */
#include<stdio.h>
#include<stdlib.h>
/* To make use of recursive calls, this function must return two things:
1) Length of LIS ending with element arr[n-1]. We use max_ending_here
for this purpose
2) Overall maximum as the LIS may end with an element before arr[n-1]
max_ref is used this purpose.
The value of LIS of full array of size n is stored in *max_ref which is our final result
*/
int _lis( int arr[], int n, int *max_ref)
{
/* Base case */
if(n == 1)
return 1;
int res, max_ending_here = 1; // length of LIS ending with arr[n-1]
/* Recursively get all LIS ending with arr[0], arr[1] ... ar[n-2]. If
arr[i-1] is smaller than arr[n-1], and max ending with arr[n-1] needs
to be updated, then update it */
for(int i = 1; i < n; i++)
{
res = _lis(arr, i, max_ref);
if (arr[i-1] < arr[n-1] && res + 1 > max_ending_here)
max_ending_here = res + 1;
}
// Compare max_ending_here with the overall max. And update the
// overall max if needed
if (*max_ref < max_ending_here)
*max_ref = max_ending_here;
// Return length of LIS ending with arr[n-1]
return max_ending_here;
}
// The wrapper function for _lis()
int lis(int arr[], int n)
{
// The max variable holds the result
int max = 1;
// The function _lis() stores its result in max
_lis( arr, n, &max );
// returns max
return max;
}
/* Driver program to test above function */
int main()
{
int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
int n = sizeof(arr)/sizeof(arr[0]);
printf("Length of LIS is %d\n", lis( arr, n ));
getchar();
return 0;
Let arr[0..n-1] be the input array and L(i) be the length of the LIS till index i such that arr[i] is part of LIS and arr[i] is the last element in LIS, then L(i) can be recursively written as.
L(i) = { 1 + Max ( L(j) ) } where j < i and arr[j] < arr[i] and if there is no such j then L(i) = 1.
In the above implementation , i am not able to understand the use/importance of the condition if (arr[i-1] < arr[n-1] && res + 1 > max_ending_here). It's doesn't even looks like the recursive formula , then why is it needed.When L(i)/*is just*/ = { 1 + Max ( L(j) ) } where j < i and arr[j] < arr[i] and if there is no such j then L(i) = 1 thenwhy do we need to compare arr[i-1] < arr[n-1]. Is it possible to come with a recursive solution which is similar to the recursive formula?
LIS: Here's a simple solution following the definition of LIS.
Assuming A is the input array of numbers, N is the size of A.
int L[51];
int res=-1;
for(int i=0;i<N;i++)
{
L[i]=1;
for(int j=0;j<i;j++)
if(A[j]<A[i])
{
L[i]=max(L[i],L[j]+1);
}
res=max(res,L[i]);
}
return res;
Time Complexity: O(N2).

Strange C function - What is this function doing?

I encountred this function without any comment. I wonder what is this function doing? Any help?
int flr(int n, char a[])
{
#define A(i) a[((i) + k) % n]
int l[n], ls = n, z[n], min = 0;
for (int i = 0; i < n; i++)
{
l[i] = i;
z[i] = 1;
}
for (int k = 0; ls >= 2; k++)
{
min = l[0];
for (int i=0; i<ls; i++) min = A(l[i])<A(min) ? l[i] : min;
for (int i=0; i<ls; i++) z[A(l[i])!=A(min) ? l[i] : (l[i]+k+1)%n] = 0;
for (int ls_=ls, i=ls=0; i<ls_; i++) if (z[l[i]]) l[ls++] = l[i];
}
return ls == 1 ? l[0] : min;
}
What a fun problem!
Other posters are correct that it returns the index of a minimum, but it's actually more interesting than that.
If you treat the array as being circular (i.e. when you get past the end, go back to the beginning), the function returns the starting index of the minimum lexicographic subsequence.
If only one element is minimal, that element is returned. If multiple elements are minimal, we compare the next element along from each minimal element.
E.g. with an input of 10 and {0, 1, 2, 1, 1, 1, 0, 0, 1, 0}:
There are four minimal elements of 0, at indices 0, 6, 7 and 9
Of these two are followed by a 1 (the 0 and 7 elements), and two are followed by a 0 (the 6 and 9 elements). Remember that the array is circular.
0 is smaller than 1, so we only consider the 0s at 6 and 9.
Of these the sequence of 3 elements starting at 6 is '001' and the sequence from 9 is also '001', so they're still both equally minimal
Looking at the sequence of 4 elements, we have '0010' from element 6 onwards and '0012' from element 9 onwards. The sequence from 6 onwards is therefore smaller and 6 is returned. (I've checked that this is the case).
Refactored and commented code follows:
int findStartOfMinimumSubsequence(int length, char circular_array[])
{
#define AccessWithOffset(index) circular_array[(index + offset) % length]
int indicesStillConsidered[length], count_left = length, indicator[length], minIndex = 0;
for (int index = 0; index < length; index++)
{
indicesStillConsidered[index] = index;
indicator[index] = 1;
}
// Keep increasing the offset between pairs of minima, until we have eliminated all of
// them or only have one left.
for (int offset = 0; count_left >= 2; offset++)
{
// Find the index of the minimal value for the next term in the sequence,
// starting at each of the starting indicesStillConsidered
minIndex = indicesStillConsidered[0];
for (int i=0; i<count_left; i++)
minIndex = AccessWithOffset(indicesStillConsidered[i])<AccessWithOffset(minIndex) ?
indicesStillConsidered[i] :
minIndex;
// Ensure that indicator is 0 for indices that have a non-minimal next in sequence
// For minimal indicesStillConsidered[i], we make indicator 0 1+offset away from the index.
// This prevents a subsequence of the current sequence being considered, which is just an efficiency saving.
for (int i=0; i<count_left; i++){
offsetIndexToSet = AccessWithOffset(indicesStillConsidered[i])!=AccessWithOffset(minIndex) ?
indicesStillConsidered[i] :
(indicesStillConsidered[i]+offset+1)%length;
indicator[offsetIndexToSet] = 0;
}
// Copy the indices where indicator is true down to the start of the l array.
// Indicator being true means the index is a minimum and hasn't yet been eliminated.
for (int count_before=count_left, i=count_left=0; i<count_before; i++)
if (indicator[indicesStillConsidered[i]])
indicesStillConsidered[count_left++] = indicesStillConsidered[i];
}
return count_left == 1 ? indicesStillConsidered[0] : minIndex;
}
Sample uses
Hard to say, really. Contrived example: from a circular list of letters, this would return the index of the shortest subsequence that appears earlier in a dictionary than any other subsequence of the same length (assuming all the letters are lower case).
It returns the position of the smallest element within the substring of a ranging from element 0..n-1.
Test code
#include <stdio.h>
int flr(int n, char a[])
{
#define A(i) a[((i) + k) % n]
int l[n], ls = n, z[n], min = 0;
for (int i = 0; i < n; i++)
{
l[i] = i;
z[i] = 1;
}
for (int k = 0; ls >= 2; k++)
{
min = l[0];
for (int i=0; i<ls; i++) min = A(l[i])<A(min) ? l[i] : min;
for (int i=0; i<ls; i++) z[A(l[i])!=A(min) ? l[i] : (l[i]+k+1)%n] = 0;
for (int ls_=ls, i=ls=0; i<ls_; i++) if (z[l[i]]) l[ls++] = l[i];
}
return ls == 1 ? l[0] : min;
}
int main() {
printf(" test 1: %d\n", flr(4, "abcd"));
printf(" test 3: %d\n", flr(6, "10e-10"));
printf(" test 3: %d\n", flr(3, "zxyghab");
printf(" test 4: %d\n", flr(5, "bcaaa"));
printf(" test 5: %d\n", flr(7, "abcd"));
return 0;
}
This code gives following output:
[root#s1 sf]# ./a.out
test 1: 0
test 2: 3
test 3: 1
test 4: 2
test 5: 4
1. 0 is the position of `a` in the first case
2. 3 is the position of `-` in second case.
3. 1 is the position of `x` in third case.
4. 2 is the position of the second `a`.
5. 4 is the position of the `\0`
So the function returns the position of smallest element of a character pointer pointed by a and it will consider n elements. (Thats why it returned the position of x in the third case).
But when multiple smallest element available, it does not seems to be work in a predictable way, as it does not return the first occurrence, nor the last.
It should do a error checking for out of bound cases. Which may lead to problem in future.
so i'm running tests on this.
int flr(int n, char a[])
{
#define A(i) a[((i) + k) % n]
int l[n], ls = n, z[n], min = 0;
for (int i = 0; i < n; i++)
{
l[i] = i;
z[i] = 1;
}
for (int k = 0; ls >= 2; k++)
{
min = l[0];
for (int i=0; i<ls; i++) min = A(l[i])<A(min) ? l[i] : min;
for (int i=0; i<ls; i++) z[A(l[i])!=A(min) ? l[i] : (l[i]+k+1)%n] = 0;
for (int ls_=ls, i=ls=0; i<ls_; i++) if (z[l[i]]) l[ls++] = l[i];
}
return ls == 1 ? l[0] : min;
}
int main()
{
int in = 10;
char array[] = {0, 1, 1, 1, 1, 1, 0, 1, 1, 0};
int res = flr(in, array);
printf("expecting res to be 6;\tres = %d\n", res);
system("pause");
return 0;
}
output was res=9;

Resources