Iterate an array from the middle then the beginning - c

I want to iterate through any array starting at an index that's close to the middle, go to the end then go to the beginning.As an example:
#include <stdio.h>
int main(){
int a[]= {1, 2, 3, 4, 5, 6, 7,};
int i = 0;
for (i = 2; i < 6; i++){
if (i == 6){
i = 0;
}
printf("%d\n", a[i]);
}
return 0;
}
How can I "reassign" the index to be zero when it reaches the end (index 6)

Here is a simple write-up. Not tested so adjust as needed. The idea is have the counter start at 0 and add the value of start each time using modulus to make it relative.
int a[]= {1, 2, 3, 4, 5, 6, 7};
int length = sizeof(a)/sizeof(a[0]);
int start = length/2;
for (int i = 0; i < length; i++)
{
printf("%d\n", a[(i+start)%length]);
}
And props to #SouravGhosh for pointing out modulus in the comments before I got this answer up.

If I well understood the question you want two for loops, one starting from the middle of your array and going to the end of the array and the second starting from the middle (minus one) and decreasing to the beginning of the array.
This is the code you can use, it is quite easy and works fine for me:
#include <stdio.h>
int main() {
int a[] = { 1, 2, 3, 4, 5, 6, 7, };
int max = (int)(sizeof(a)/sizeof(a[0]));
int middle = (int)(max / 2);
int i;
for (i = middle; i < max ; i++) {
printf("%d\n", a[i]);
}
for (i = middle - 1; i >= 0; i--) {
printf("%d\n", a[i]);
}
}

Related

Why do array element values not change?

int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i <= 9; i++) {
int tmp = a[i];
a[i] = a[9 - i];
a[9 - i] = tmp;
}
for (int i = 0; i <= 9; i++) {
printf("%d", a[i]);
}
The result of it is: 1234567890,
but why not 10987654321
since it switch values in the first for loop,
but why can not change it when the next for loop runs
I have tried to move "int tmp" outside of the loop, but of no use at all.
Your loop:
for(int i=0;i<=9;i++){
int tmp= a[i];
a[i] = a[9-i];
a[9-i] = tmp;
}
Each iteration it swaps elements.
On the first iteration, it swaps a[0] and a[9]. On the second a[1] and a[8] and so on.
But what about the 10th iteration?
Well, it swaps a[9] and a[0]. But you already swapped those, so it's just swapping them back the way they were.
If you stop after 5 iterations, so you're only swapping each pair once, your code will behave the way you expect.
To illustrate the suggestion from #user4581301 in comments, see below. We get begin and end pointers to the first and last elements in the array, respectively. Our loop continues as long as the begin pointer is less than the end pointer. If end is greater than begin it means we've gone past halfway. If they're equal, it means our array had an odd number of elements, and we've hit the middle one. That middle element wouldn't need to be swapped, so either way we're done.
The update in the loop increments begin and decrements end, moving inward one place from each end of the array.
#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *begin, *end;
for (begin = &arr[0], end = &arr[9]; begin < end; ++begin, --end) {
int temp = *begin;
*begin = *end;
*end = temp;
}
for (size_t i = 0; i < 10; ++i) {
printf("%d\n", arr[i]);
}
}
Because you are swapping every pair twice.
Iterate it to half of the array. If you are not able to spot the error kindly dry run it on paper, you will get the answer.
#include <stdio.h>
int main() {
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < 5; i++) {
int tmp = a[i];
a[i] = a[9 - i];
a[9 - i] = tmp;
}
for (int i = 0; i < 10; i++) {
printf("%d", a[i]);
}
}

Check if array is subset of another array

I have two arrays.
1,3,5,7,9
{3,5} or {1.9}.
(left to right order)
So the second array is a subset of the first array
But not a subset if the second array is {5.3} or, {9.1}
(right to left order.)
My code is
#include <stdio.h>
void subset(int set11[], int set12[])
{
int length1;
int set1[] = {1, 5, 3, 9, 7, 0, 5};
length1 = sizeof(set1) / sizeof(int);
int length2;
int set2[] = {5, 9};
length2 = sizeof(set2) / sizeof(int);
int i = 0;
int j = 0;
int count = 0;
for (i = 0; i < length1; i++)
{
if (set1[i] == set2[j])
{
count = 1;
}
}
printf(" is \n");
if (count == 1)
{
printf("is subset");
}
else
{
printf("not subset");
}
}
int main()
{
int set11[] = {1, 5, 3, 9, 7};
int set12[] = {5, 9};
subset(set11, set12);
printf("");
return 0;
}
I get output in all cases only not subset.
Applied some changes in logic. refer comments.
#include <stdio.h>
#include <stdbool.h>
void subset(int set11[], int set12[])
{
int length1;
int set1[] = {1,3,5,7,9};
length1 = sizeof(set1) / sizeof(int);
int length2;
int set2[] = {3,5};
length2 = sizeof(set2) / sizeof(int);
int i = 0;
bool isSubset = true; //will indicate weather the second array is subset or not
// int j = 0; //
int startPosition = 0; // will decide the starting position for searching in the main array. {set 2}
// int count = 0; //not needed; we will represent it with bool variable 'isSubset'.
for (i = 0; i < length2; i++) //Iterating through the subset array
{
bool isFound = false;
for (int j=startPosition;j<length1;j++){ //Iterating through the original array {set 1}
if (set2[i]==set1[j]){ //if element from second array is found in first array then...
isFound = true; //found the element
startPosition = j+1; //increasing the starting position for next search in the first array.
printf("\t%d found at %d\n",set2[i],j);
break;
}
}
if(isFound==false){ //if not found then this is not subarray.
printf("\t%d not found\n",set2[i]);
isSubset = false;
break;
}
}
// printf(" is \n");
if (isSubset)
{
printf("subset");
}
else
{
printf("not subset");
}
}
int main()
{
int set11[] = {1, 5, 3, 9, 7};
int set12[] = {5, 9};
subset(set11, set12);
printf("");
return 0;
}
You can run a nested loop to get hold of all the matching elements in the subset array
for (i = 0; i < length1; i++)
{
for(k = 0; k < length2; k++)
{
if (set1[i] == set2[k])
{
count == 1;
}
}
}
Outer loop is for the for the First array
Inner loop to check for the element at any position in the subset/second array
set1[] = {1, 5, 3, 9, 7, 0, 5};
set2[] = {5, 9};
If we run a nested loop we will get all the subsets regardless of their positions in the second array(set2)
it wont matter if the set2 is {5,9} or {9,5} in any case the counter variable will increase.

Unable to traverse array fully in C

I had this question to solve:
Find the length of increasing subarrays in the given array and print length of each segment in a new line
Here's what I have done so far:
#include <stdio.h>
int main(){
int c = 0;
int a[] = {1, 3, 2, 4, 5, 7};
for (int i = 0; i < 6; i++) {
if (a[i] > a[i-1]) {
c++;
}
else {
printf("%d\n", c);
c=1;
}
}
return 0;
}
My expected answer is:
2
4
but I am getting only 2, on increasing i to 7, I am getting correct answer, am I doing something wrong in traversing the array because the length is 6 and i<6 should have given the correct answer
Apologies in advance if the question is too trivial, just getting started.
It's simple. Because you have included in this line:
if (a[i] > a[i-1])
i starts with a 0 but a[-1] doesn't exist.
To fix your code:
#include <stdio.h>
int main(void){
int c = 0;
int a[] = {1, 3, 2, 4, 5, 7};
for (int i = 1; i < 6; i++) {
if (a[i] > a[i-1])
c++;
else {
printf("%d\n", c);
c=1;
}
}
return 0;
}
It is possible to do it with a single printf in the loop if you loop over all values from 0 to the array length, and treat the first and last iterations as special cases:
#include <stdio.h>
int main(void){
int c = 0;
int a[] = {1, 3, 2, 4, 5, 7};
const int len = sizeof a / sizeof a[0];
for (int i = 0; i <= len; i++) {
if (i < len && (i == 0 || a[i] > a[i-1])) {
c++;
} else {
printf("%d\n", c);
c = 1;
}
}
return 0;
}
The i < len makes sure that the code does not access a[len], which is out of bounds. When i equals len the code reaches the else part to print the length of the final segment.
The i == 0 makes sure that the code does not access a[-1], which is out of bounds, but we want it to increment c for the first entry in the array.
The code can be simplified a bit by initializing c = 1 and starting the loop at i = 1. By doing that, the first element of the array has already been accounted for:
#include <stdio.h>
int main(void){
int c = 1;
int a[] = {1, 3, 2, 4, 5, 7};
const int len = sizeof a / sizeof a[0];
for (int i = 1; i <= len; i++) {
if (i < len && a[i] > a[i-1]) {
c++;
} else {
printf("%d\n", c);
c = 1;
}
}
return 0;
}
The code will run slightly faster if the code inside the loop is simplified as much as possible, eliminating the i < len test inside the loop, and terminating the loop when i reaches len (i.e. continue the loop if i < len), but that will require the length of the final segment to be printed separately after the for loop has terminated:
#include <stdio.h>
int main(void){
int c = 1;
int a[] = {1, 3, 2, 4, 5, 7};
const int len = sizeof a / sizeof a[0];
for (int i = 1; i < len; i++) {
if (a[i] > a[i-1]) {
c++;
} else {
printf("%d\n", c);
c = 1;
}
}
printf("%d\n", c);
return 0;
}
If there is a requirement for the code to work when the overall sequence has zero length, then the final printf would print the wrong value 1. That could be dealt with either by setting c to 0 when len is 0, or by skipping the final printf if len is 0. (It depends whether you want to print anything at all when the overall sequence has zero length.)

How to check if two arrays have the same set of digits in C?

I want to check if two integer type arrays have the same set of digits. For example, if array 1 is 5 1 2 3 3 4 6 1, and array 2 is 1 2 3 4 5 6, the program returns 1. If any number from either array isn't in the second one, the program returns a 0.
I tried doing something like this, but I can't get it to work:
#include <stdio.h>
int main()
{
int i, j, a[8]={5, 1, 2, 3, 3, 4, 6, 1}, b[6]={1, 2, 3, 4, 5, 6}, x=0;
for(i=0; i<6; i++)
{
for(j=0; j<8; j++)
{
if(a[j]==b[i])
{
x=1;
continue;
}
else
{
x=0;
break;
}
}
}
return x;
}
EDIT:
Thank you Some programmer dude
#include <stdio.h>
void sort(int arr[], int n)
{
int i, j, a;
for (i=0; i<n; i++)
{
for (j=i+1; j<n; j++)
{
if (arr[i]>arr[j])
{
a=arr[i];
arr[i]=arr[j];
arr[j]=a;
}
}
}
}
int main()
{
int i, j, k;
int a[8]={5, 1, 2, 3, 3, 4, 6, 1};
int b[6]={1, 2, 3, 4, 5, 6};
int na=8, nb=6;
for(i=0; i<na; i++) // removing duplicates from a
{
for(j=i+1; j<na; j++)
{
if(a[i]==a[j])
{
for(k=j; k<na; k++)
{
a[k]=a[k+1];
}
na--;
j--;
}
}
}
for(i=0; i<nb; i++) // removing duplicates from b
{
for(j=i+1; j<nb; j++)
{
if(b[i]==b[j])
{
for(k=j; k<nb; k++)
{
b[k]=b[k+1];
}
nb--;
j--;
}
}
}
sort(a, na);
sort(b, nb);
if(na!=nb)
return 0;
for(i=0; i<na; i++)
{
if(a[i]!=b[i])
return 0;
}
return 1;
}
You have several ways you can approach this, you can use two sets of nested loops swapping the order you loop over the two arrays validating each element is found in the other. Two full sets of nested loops are needed as you have a 50/50 chance any single outlier will be contained in either of the arrays. This is the brute-force method and has the potential worst-case number of iterations.
Since an outlier is what drove the need for looping with one arrays as outer and the other inner and then swapping a repeating, e.g. to catch 5, 1, 2, 3, 3, 4, 6, 1 and 1, 2, 3, 4, 5, 6, 7, if you can catch the outlier with another method that requires fewer iterations you can make your algorithm more efficient.
An outlier would be detected in a comparison of the min and max from each array, and to find min and max only requires a single linear traversal of each array. Much better than the worst-case nested loop over all elements.
The min and max check provide a way to shorten your work, but do not eliminate the need to press forward with a second set of nested loops if the result is inconclusive at that point. Why? Consider the following sets, where the min and max are equal, but one element within the range is not included in both arrays, e.g.:
int a[] = { 5, 1, 2, 3, 3, 4, 6, 112 },
b[] = { 1, 2, 3, 4, 5, 6, 7, 112 };
The only way the 7 will be detected is by nested loop with the array containing 7 being the outer loop.
So you could write a short function to test for the common set as:
#include <stdio.h>
#include <limits.h>
int commonset (int *a, int *b, int sza, int szb)
{
int maxa = INT_MIN, maxb = INT_MIN,
mina = INT_MAX, minb = INT_MAX;
for (int i = 0; i < sza; i++) { /* find max/min of elements of a */
if (a[i] > maxa)
maxa = a[i];
if (a[i] < mina)
mina = a[i];
}
for (int i = 0; i < szb; i++) { /* find max/min of elements of b */
if (b[i] > maxb)
maxb = b[i];
if (b[i] < minb)
minb = b[i];
}
if (maxa != maxb || mina != minb) /* validate max & mins equal or return 0 */
return 0;
for (int i = 0; i < sza; i++) { /* compare of each element between arrays */
int found = 0;
for (int j = 0; j < szb; j++)
if (a[i] == b[j]) {
found = 1;
break;
}
if (!found)
return 0;
}
for (int i = 0; i < szb; i++) { /* compare of each element between arrays */
int found = 0;
for (int j = 0; j < sza; j++)
if (a[j] == b[i]) {
found = 1;
break;
}
if (!found)
return 0;
}
return 1;
}
Adding a short example program:
int main (void) {
int a[] = { 5, 1, 2, 3, 3, 4, 6, 1 },
sza = sizeof a / sizeof *a,
b[] = { 1, 2, 3, 4, 5, 6 },
szb = sizeof b / sizeof *b,
result;
result = commonset (a, b, sza, szb);
if (result)
puts ("arrays have common set of numbers");
else
puts ("arrays have no common set of numbers");
return result;
}
Example Use/Output
$ ./bin/arr_commonset
arrays have common set of numbers
$ echo $?
1
With b[] = { 1, 2, 3, 4, 5, 6, 7 }:
$ ./bin/arr_commonset
arrays have no common set of numbers
$ echo $?
0
With a[] = { 5, 1, 2, 3, 3, 4, 6, 112 } and b[] = { 1, 2, 3, 4, 5, 6, 7, 112 }:
$ ./bin/arr_commonset
arrays have no common set of numbers
$ echo $?
0
There are probably even ways to combine the two and shave off a few iterations, and, if you have a guaranteed range for your input sets, you can use a simple frequency array for each and then two simple linear iterations would be needed to increment the element that corresponds to the index for each value in the array, and then a third linear iteration over both frequency arrays comparing that like indexes either both are non-zero or both are zero to confirm the common set -- that is left to you.
Look things over and let me know if you have any further questions.

How many times a digit show up

Please help me. I don't get why the out put is in "occurs" is "30", instead of '3'.. It's as if I'm multiplying the answer with '10', but I'm not.. Maybe the answer to my problem is right in to my code but Can someone explain why and how? please.. Thank you very much in advance..
Please take a look at my code.
#include <stdio.h>
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int occur[10] = {NULL};
int max = 0;
int most;
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
occur[arr[j]]++;
if(occur[arr[j]] > max)
{
max = occur[arr[j]];
most = arr[j];
}
}
}
printf("Most frequent: %d\ occurs: %d\n", most, max);
return 0;
}
I am getting the correct answer in "Most Frequent". But the "occurs" is 30, instead of just 3 because 7 occurs 3 times.
It becomes 30 because there is an outer loop which executes 10 times.
I'm guessing that you want to get the most frequent number in the array and how many times it occurred that's why you have an outer loop. This will not work if you have a number in your array that is greater than 9 which will result in index out of bounds problem in occur array. You should change your implementation to this:
#include <stdio.h>
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int max = 0;
int most;
for(int i = 0; i < 10; i++)
{
int tmp = arr[i], count = 0;
// if the current number is the current max number then skip
if(tmp == max)
continue;
for(int j = 0; j < 10; j++)
{
// increment count if number in index j is equal to tmp number
count += arr[j] == tmp ? 1 : 0;
}
// [this condition will depend on the requirement.]
// replace max and most if the count of tmp number is greater than your
// current max
if(count > max){
max = count;
most = tmp;
}
}
printf("Most frequent: %d\ occurs: %d\n", most, max);
return 0;
}
This is not tested so if there are any problems, please feel free to edit.
You ARE multiplying max by 10 since you are doing everything 100 times (instead of 10) because of your totally redundant for i loop.
Specifically your problem is you are incrementing the values in occurs 10 times (instead of once). Since most doesn't use the incremented values it doesn't have problem.
The faster, O(2n-1) complexity solution
#include <stdio.h>
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int occur[10] = {NULL};
int max = 0;
for(int i = 0; i < 10; ++i)
++occur[arr[i]];
for (int i = 1; i < 10; ++i)
if (occur[i] > occur[max])
max = i;
printf("Most frequent: %d\ occurs: %d\n", max, occur[max]);
return 0;
}
Yet faster, in O(n)... I had a feeling that..
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int occur[10] = {NULL};
int max = 0;
for(int i = 0; i < 10; ++i)
if (++occur[arr[i]] > occur[max])
max = arr[i];
printf("Most frequent: %d\ occurs: %d\n", max, occur[max]);
return 0;
}
I will not argue that your O(n^2) operations algorithm is not the ideal way to do the task.
But moving one line of code will fix your code.
Your loop:
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
occur[arr[j]]++;
Fix:
for(int i = 0; i < 10; i++)
{
occur[arr[i]]++;
for(int j = 0; j < 10; j++)
{
I'll let you figure out how you can do this in O(2n) operations or less...

Resources