Why do array element values not change? - arrays

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]);
}
}

Related

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.

C Updating of Arrays

with reference to this question - https://www.geeksforgeeks.org/arrange-given-numbers-form-biggest-number-set-2/
For some reason, if I do not update the elements in the second array, the elements in the first array does not get updated correspondingly.
int array[] = {1, 34, 3};
int newArrayWithSamePower[3] = {11, 34, 33};
// Sort initial array based on power array elements
for (int i = 0; i <= 2; i++) {
for (int j = i + 1; j <= 2; j++) {
if (newArrayWithSamePower[j] > newArrayWithSamePower[i]) {
int temp2 = newArrayWithSamePower[i];
newArrayWithSamePower[i] = newArrayWithSamePower[j];
newArrayWithSamePower[j] = temp2;
// Unsure why array indexes go haywire if you dont update power array
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
for (int i = 0; i <= tempIndex; i++) {
printf("%d\n", array[i]);
}
Expected output: {34, 3, 1}
However, if I do not update the power array, the output will become {3, 1, 34}.
if (newArrayWithSamePower[j] > newArrayWithSamePower[i]) {
int temp2 = newArrayWithSamePower[i];
newArrayWithSamePower[i] = newArrayWithSamePower[j];
newArrayWithSamePower[j] = temp2;
If you do not swap elements of newArrayWithSamePower array within the loop, then on different indexes the if (newArrayWithSamePower[j] > newArrayWithSamePower[i]) condition will be true, thus array will be swapped differently. The algorithm works in place - it has to modify elements to work properly.

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...

Iterate an array from the middle then the beginning

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]);
}
}

Issue with selection sort and using a findMin method in C

so I'm having an issue with a selection sort that I made in C. When implemented in one function, I can get the selection sort to work. However, when I do what my assignment asks, and use a findMin function that returns the minimum index an array, it doesn't sort it completely. I've tried to debug it using print statements but I can't seem to figure out what is going wrong.
Here is the sorting method I am using with the findMin method:
void sortMin2(int A[]) {
int outer;
int minIndex;
for(outer = 0; outer < 5; outer++) {
minIndex = findMin(A, outer, 5);
if(minIndex != outer) {
swap(&A[minIndex], &A[outer]);
}//end if
} // end for
}
int findMin(int A[], int i, int j) {
int k; // for loop
int index = 0;
for(k = (i + 1); k < (j+1); k++) {
if(A[k] < A[index]) {
index = k;
} // end if
} // end for
return index;
} // end findMin
void swap(int *i, int *j) {
int temp = *i;
*i = *j;
*j = temp;
} // end swap
And here is my output when I run it on an array of five values:
Array Before: 4, 10, 9, 1, 3,
4, 10, 9, 1, 3,
1, 10, 9, 4, 3,
10, 1, 9, 4, 3,
10, 1, 3, 4, 9,
10, 1, 3, 9, 4,
Array after: 4, 1, 3, 9, 10,
Now, here is my selection sort method that does work find (ie. properly sorts it).
void selectionSort2(int A[]) {
int outer; // for loops
int inner;
int minimum = 0;
//int minIndex = 0;
for(outer = 0; outer < 5; outer++) {
//minIndex = findMin(A, 0, 19);
minimum = outer;
for(inner = outer + 1; inner < 5; inner++) {
if(A[minimum] > A[inner]) {
minimum = inner;
} // end if
} // end inner for
if(minimum != outer) {
swap(&A[minimum], &A[outer]);
} // end if
} // end outer for
}
Does anyone see why my sortMin2 function doesn't actually sort it?
Some thingies, inside the code, are not in the right sense.
Why in findMin(...) method, the for loop has k < (j+1) as terminating condition. Don't you think, it should be k < j? Since j + 1 will lead to 6, hence the loop will go till j = 5, which will lead to undefined behaviour(as it is more than the bounds of the array A). Array indices start from 0. Since the size is 5, hence the indices are in the range of 0 - 4.
Moreover, the value of index is never changing. It always starts from 0 in every iteration. Instead it should be int index = i, inside the findMin(...) function, as in Selection Sort we find the smallest element, and put it on the left hand side, to it's rightful position, hence next time, we start from a place, one ahead of this location.
And inside the sortMin2(...) function, you failed to call swap(...), in case you have the new index to swap values with.
Here is the modified version, of the snippet:
int findMin(int A[], int i, int j) {
int k; // for loop
int index = i;
for(k = (i + 1); k < (j); k++) {
if(A[k] < A[index]) {
index = k;
} // end if
} // end for
return index;
} // end findMin
void swap(int *i, int *j) {
int temp = *i;
*i = *j;
*j = temp;
} // e
void display(int A[])
{
int i = 0;
for (i = 0; i < 5; ++i)
printf("%d\t", A[i]);
printf("\n");
}
void sortMin2(int A[]) {
int outer = 0;
int minIndex = -1;
for(outer = 0; outer < 5; outer++) {
minIndex = findMin(A, outer, 5);
if(minIndex != outer) {
swap(&A[minIndex], &A[outer]);
display(A);
}//end if
} // end for
}

Resources