Weird results while printing elements of integer array - arrays

I just have to make a simple program, where I have an array given with random numbers, then I have to do some things with the array and then print the elements at the end. But I don't know what's happening here.
First I wanted to make a code, just to print the elements and see if it works before doing anything else.
#include <stdio.h>
int main(void) {
int nums[] = {12, 3, 54, -4, 56, 4, 7, 3};
//.....
for(int i = 0; nums[i]; i++) {
printf("nums[%d] = %d\n", i, nums[i]);
}
return 0;
}
And the result was:
nums[0] = 12
nums[1] = 3
nums[2] = 54
nums[3] = -4
nums[4] = 56
nums[5] = 4
nums[6] = 7
nums[7] = 3
nums[8] = -427200144
nums[9] = 32765
I ran the code more times, and the 8th and 9th element is always kinda random... But I mean I don't even have that many numbers, what's wrong here??
Also I tried with other random numbers and sometimes it works fine...
int nums[] = {2, -10, 64, 100, 22, 4};
nums[0] = 2
nums[1] = -10
nums[2] = 64
nums[3] = 100
nums[4] = 22
nums[5] = 4
Can someone explain what's happening here?
Edit: Meanwhile I realized this method is bad, since if the number in the array is 0, then my condition is false so the for cycle stops, but I'm curious, what's happening here, so I gonna post this anyways.

I recommend
for(int i = 0; i < sizeof(nums) / sizeof(*nums); i++) {
printf("nums[%d] = %d\n", i, nums[i]);
}
sizeof(nums) is the total size of the array (in bytes).
sizeof(*nums) is size of one element of the array (in bytes).
Therefore, sizeof(nums) / sizeof(*nums) represents the number of elements and that is what should be the condition in the loop.
Another option is having a separate variable that contains number of elements in the array, but it's less convenient than the first method I described.

Related

How can I get the index of a given combination?

I have a sequence of arrays of numbers with 5 elements each, from 0 to 8, and I have to order than using that combination, I mean:
i=0, {0,0,0,0,0}
i=1, {0,0,0,0,1}
i=2, {0,0,0,0,2}
i=3, {0,0,0,0,3}
i=4, {0,0,0,0,4}
i=5, {0,0,0,0,5}
i=6, {0,0,0,0,6}
i=7, {0,0,0,0,7}
i=8, {0,0,0,0,8}
i=9, {0,0,0,1,1}
...
i=1285, {7,8,8,8,8}
i=1286, {8,8,8,8,8}
so if I give {0,0,1,1,2} to the function it's returns 7.
I thought about using the Combinatorial number system
but I'm missing something that I don't know what it is, the code below just doesn't work
#include <stdio.h>
#include <stdlib.h>
#define size 1287
int combination[9][5] = {
{0, 0, 0, 0, 0},
{1, 1, 1, 1, 1},
{2, 3, 4, 5, 6},
{3, 3, 6, 15, 21},
{4, 10, 20, 35, 56},
{5, 15, 35, 70, 126},
{6, 21, 56, 126, 252},
{7, 28, 84, 210, 462},
{8, 36, 120, 330, 792}
};
int getKey(int array[]){
int key=0;
int tempArray[9] = {0};
for(int i=0;i<5;i++){
tempArray[array[i]]++;
}
int j=0;
for(int i=0;i<9;i++){
if(tempArray[i]!=0){
while(tempArray[i]!=0){
array[j++] = i;
key += combination[i][5-j];
tempArray[i]--;
}
}
}
return key;
}
int main(){
int it[5];
for(it[0] = 0 ;it[0]<9;it[0]++){
for(it[1]=it[0];it[1]<9;it[1]++){
for(it[2]=it[1];it[2]<9;it[2]++){
for(it[3]=it[2];it[3]<9;it[3]++){
for(it[4]=it[3];it[4]<9;it[4]++){
printf("{%d %d %d %d %d} = %d\n",it[0],it[1],it[2],it[3],it[4],getKey(it));
}
}
}
}
}
return 0;
}
Obs: I'm using counting sort to keep the lexicographic order, in theory I will receive unsorted arrays.
I will give you the Answer I wrote for the previous version of this question which you posted yesterday and deleted. (And that's bad form, by the way.)
Let's call the binomial coefficient C(n, k) = n!/(k!(n-k)!)
The number of unordered strings of m letters drawn from an alphabet of s symbols is C(m+s-1, s-1). Let's call that D(m, s). In this case, D(5, 9) = C(5+9-1, 9-1) = C(13, 8) = 1287
Let's sort each string, then number them:
aaaaa 1
aaaab 2
aaaac 3
...
aaaai 9
aaabb 10
aaabc 11
...
If a string contains 5 a's, its number is D(5, 1) = C(5+1-1, 1-1) = C(5, 0) = 1.
If a string contains 4 a's, its number is 1 plus a number determined by the non-a letter, which goes up to D(1,8) = C(1+8-1,8-1) = C(8, 7) = 8. So they go up to 1+8=9.
If a string contains 3 a's, its number is 9 plus a number determined by the non-a letters, which goes up to D(2,8) = C(9,7) = 36, so 9+36=45.
If a string contains 2 a's, its number is in [46,165].
If a string contains 1 a, its number is in [166, 495].
If a string contains no a, its number is in [496, 1287].
So how about the string "aabgg"? It's number is (45)+(8)+(7)+(6)+(5)+(4)+(1)=76
No collisions, and the calculation of the index is O(sm(s+m)), which is not too bad for m=5 and s=9.
EDIT: to clarify, let's define
E(j, m, s) = D(0,s-1)+D(1,s-1)+...+D(m-j-1,s-1)
Suppose a string of m letters drawn from an alphabet of s symbols contains j of the first letter of the alphabet. There are E(j,m,s) strings in the catalogue before the first such string. For instance, before the first string that begins with exactly two a's ("aabbb"), there are E(2, 5, 9)=45 strings.
To get to "aabbb" we must count out 45 strings.
To get from "aabbb" to the next string that contains exactly one b ("aabcc"), we must count out E(1, 3, 8) = 8 strings.
From there to the next string that contains no c ("aabdd"), E(0, 2, 7) = 7 strings.
No d ("aabee"): E(0, 2, 6) = 6
No e ("aabff"): E(0, 2, 5) = 5
No f ("aabgg"): E(0, 2, 4) = 4
And we must count "aabgg" itself: 1
well, I think this look like oct number 1...8
0 = {00000}
1 = {00001}
2 = {00002}
8 = {00010}
if this what you mean
I think this algorithm is the best
int get_key(int a[5]){
int idx, rval=0;
for(i=4; i<=0; i--)
rval += powl(a[i], i);
return rval;
}

What is the formula to calculate this sequence?

I've been facing a problem with this particular question in C.
The question is:
Write a program to generate the first n terms in the series --- 2,5,9,..,20,27
I'm stuck in the for-loop part. Like, for other terms
example: series --- 5,9,17,29,45,...
I can calculate the remaining series by the formula:
for(i=0; i<n; i++)
{
a=a+(4*i); //a is initialized to 5
printf("%d", a);
}
Thank you.
It looks like the (i+1)-st element is created from the i-th by adding an increasing number:
a0 = 2, d0 = 3
a1 = 2+3 = 5, d0 = 4
a2 = 5+4 = 9, d0 = 5
a3 = 9+5 = 14, d0 = 6
a4 = 14+6= 20, d0 = 7
a5 = 20+7= 27, d0 = 8
...and so on
You can compute this result by incrementing d as you walk through the loop, and adding it to the previous value of a.
According to the Online Encyclopedia of Integer Sequences, elements of this sequence could be computed using this closed-form expression:
n*(n+3)/2
Note: The above division always produces an integer value because one of n or n+3 will be even.
Is this what you expect?
#include <stdio.h>
int main(void)
{
int a = 2, n = 10;
for(int i = 0; i < n; i++)
{
printf("%d, ", a);
a = a + i + 3;
}
printf("etc\n");
return 0;
}
Output
$ gcc main.c -o main.exe; ./main.exe;
2, 5, 9, 14, 20, 27, 35, 44, 54, 65, etc
If I understand you correctly you're looking for
a=2;
n=5; /* to generate numbers up to 27 */
for (i=3;i<n+3;i++)
{
a+=i;
printf("%d",a);
}
It's n+3 because you would begin with 3 and count n times up from there.

How does XOR work in C to find a number occurring odd number of times?

int getOddOccurrence(int ar[], int ar_size) {
int i;
int res = 0;
for (i=0; i < ar_size; i++)
res = res ^ ar[i];
return res;
}
/* Diver function to test above function */
int main() {
int ar[] = {2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2};
int n = sizeof(ar)/sizeof(ar[0]);
printf("%d", getOddOccurrence(ar, n));
return 0;
}
Like in above code, how is xor working to get number of occurrences of an odd number in an array?
This code does not count the number of occurrences of an odd number. Instead, it finds a single number in an array that occurs an odd number of times.
Your test array has these numbers:
2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2
Their counts are as follows:
2 - 4 times
3 - 2 times
4 - 4 times
5 - 3 times
Only 5 is listed an odd number of times.
XOR has these two properties:
Y ^ 0 = Y
X ^ X ^ Y = Y
for any value of X and Y. In other words, XOR-ing any number Y with zero leaves the value unchanged, and XOR-ing a number X twice with any value Y leaves that original value unchanged. The order of operations does not matter. Since res starts at zero, XOR-ing together all numbers from your array produce 5 - the only value that is not XOR-ed an even number of times.
It doesn't count them. It's using an efficient 'trick' to identify the single instance of a number with odd occurrences in a list. This trick would not work if there were multiple or no numbers that occur an odd number of times.
If you xor a number with itself, it equals 0. This property holds true even across multiple operations, ie, 3 ^ 4 ^ 3 ^ 4 = 0. Therefore, in such a sequence the end result is going to equal any number that doesn't 'cancel out'. i.e. 3 ^ 4 ^ 3 = 4.
It does not. res += ar[i] & 1; does count, however.
Xor does not generate a carry, so it cannot count further than 1 bit:
I1 I2 I1^I2
0 0 0
0 1 1
1 0 1
1 1 0
I1: bit[k] of res
I2: bit[k] of ar[i]
k = 0 ... (sizeof(int) * CHAR_BIT - 1) (number of bits in int - 1)
It does however, yield the linear parity (parity across all bits at the same position (i.e. parity for all bits 7, all bits 6, ...). The result of any bit in res is 1 if the sum of all bits in ar with the same bit-index is odd.
Combined with a parity across each byte, it results in a matrix where a single bit error can be detected and corrected, while a two bit error can be detected (yet not corrected).
This was used in earlier days as a (weak) forward error correction for some transmission protocols. Nowadays, there are better, but much more processing intensive, algorithms like hamming code.
Edit:
Other comments and answers suggest this is to find the single value with odd appearance. As this puts quite some constraints on the input, it is of no actual usage and purely artificial. However, the application above is definitvely for real (or has been).
Hi here is my code to find two odd numbers and this was my lab task in my college. Hope you will get the concept.
void printTwoOdd(int arr[], int size)
{
int xor2 = arr[0]; /* Will hold XOR of two odd occurring elements */
int set_bit_no; /* Will have only single set bit of xor2 */
int i;
int n = size - 2;
int x = 0, y = 0;
/* Get the xor of all elements in arr[]. The xor will basically
be xor of two odd occurring elements */
for(i = 1; i < size; i++)
xor2 = xor2 ^ arr[i];
/* Get one set bit in the xor2. We get rightmost set bit
in the following line as it is easy to get */
set_bit_no = xor2 & ~(xor2-1);
/* Now divide elements in two sets:
1) The elements having the corresponding bit as 1.
2) The elements having the corresponding bit as 0. */
for(i = 0; i < size; i++)
{
/* XOR of first set is finally going to hold one odd
occurring number x */
if(arr[i] & set_bit_no)
x = x ^ arr[i];
/* XOR of second set is finally going to hold the other
odd occurring number y */
else
y = y ^ arr[i];
}
printf("\n The two ODD elements are %d & %d ", x, y);
}
and here is main method
void main()
{
int arr[] = {4, 2, 4, 5, 2, 3, 3, 1};
int arr_size = sizeof(arr)/sizeof(arr[0]);
printTwoOdd(arr, arr_size);
getchar();
}

Moving average in static array in C

I have an array of 10 elements, and I need to make that array into its moving average equivalent.
Using 3 elements each time (eg average of elements at indices 0-2, then 1-3 and so on up to indices from 10 then back to 0 and 1 to make the new array have exactly 10 elements as well).
What is the best approach to this without using pointers to wrap the array around (ring buffer).
Just do some bounds checking and wrap the index in code.
The example code below can be made more efficient, but it's written like this for clarity (sort of). Also there may be some minor mistake since I'm typing into StackOverflow rather than compiling it.
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int averages[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for (int i = 0; i < 10; i++)
{
int a = i;
int b = i + 1 > 9 ? i - 10 + 1;
int c = i + 2 > 9 ? i - 10 + 2;
int count = array[a] + array[b] + array[c];
int average = count / 3; // note this will truncate any decimal part
averages[i] = average;
}

How can I average a subset of an array and store the result in another array?

I have a C array fftArray[64] that contains values that I want averaged and placed into another array frequencyBar[8]. Getting the average of the entire array would be easy enough using a for statement.
int average, sum = 0;
for (i = 0; i < 64; i++)
{
sum += fftArray[i];
}
average = sum/64;
But I just can't seem to figure out how to get the average from fftArray[0] through fftArray[8] and store this in frequencyBar[0], the average of fftArray[9] through fftArray[16] and store this in frequencyBar[1], etc. Can anyone help me out with this? Thanks
This looks like a homework assignment, so, rather than give you the outright answer, I'd rather just point you in the right direction...
use a nested loop (one inside the other). One loop cycles 0-7, the other one 0 - 63. Use the smaller one to populate your sliced averages.
or better yet use the % operator to see when you've gone through 8 elements and do an average of your total, then reset the total for the next set. Then you'll have learned how to use the % operator too! :)
[EDIT]
ok, if not homework then something like this... I haven't written C in 5 years, so treat this as pseudo code:
//assuming you have a fftArray[64] with data, as per your question
int i,sum,avCounter,total;
int averages[8];
for(i=0 , avCounter=0, total=0 ; i<64; ){
total += fftArray[i];
if(++i % 8 == 0){ //%gives you the remainder which will be 0 every 8th cycle
averages[avCounter++] = total / 8
total = 0; //reset for next cycle
}
}
I think this will work better than a nested loop... but I'm not sure since % is division which is more processor heavy than addition... however... I doubt anyone would notice :)
int i, j;
for (i = 0; i < 8; i++) {
int sum = 0;
for (j = 0; j < 8; j++) {
sum += fftArray[ 8*i + j ];
}
frequencyBar[i] = sum / 8;
}
Bonus exercise: Optimize this code for speed on your chosen platform.
TF,
DISCLAIMER: This code is just off the top of my head... it hasn't even been compiled, let alone tested.
// returns the average of array[first..last] inclusive.
int average(int[] array, int first, int last) {
int sum = 0;
for (i = first; i <= last; i++)
sum += array[i];
return sum / (last - first + 1); // not sure about the +1
}
Then what you'd do is loop through the indexes of your frequencyBar array [0..7], setting frequencyBar[i] = average(array, first, last);... the tricky bit is calculating the first and last indexes... try i*8 and (i+1)*8 respectively... that may not be exactly right, but it'll be close ;-)
Cheers. Keith.
EDIT: Bored... waiting for my test results to come back. No news is good news, right? ;-)
It turns out that passing the length is a fair bit simpler than passing the last index.
#include <stdio.h>
int sum(int array[], int first, int length) {
int sum = 0;
for (int i = first; i < first+length; i++)
sum += array[i];
return sum;
}
double average(int array[], int first, int length) {
double total = sum(array, first, length);
#ifdef DEBUG
printf("DEBUG: [%2d..%2d] %d", first, first+length-1, array[first]);
for (int i = first+1; i < first+length; i++)
printf(" + %d", array[i]);
printf(" = %d / %d = %f\n", (int)total, length, total/length);
#endif
return total / length;
}
int main(int argc, char* argv[]) {
int array[] = { // average
1, 2, 3, 4, 5, 1, 2, 3, // 2.625
4, 5, 1, 2, 3, 4, 5, 1, // 3.125
2, 3, 4, 5, 1, 2, 3, 4, // 3
5, 1, 2, 3, 4, 5, 1, 2, // 2.875
3, 4, 5, 1, 2, 3, 4, 5, // 3.375
1, 2, 3, 4, 5, 1, 2, 3, // 2.625
4, 5, 1, 2, 3, 4, 5, 1, // 3.125
2, 3, 4, 5, 1, 2, 3, 4 // 3
};
double frequency[8];
for (int i = 0; i < 8; i++)
frequency[i] = average(array, i*8, 8);
for (int i = 0; i < 8; i++)
printf("%f ", frequency[i]);
printf("\n");
}
Watch your sum doesn't wrap around if fftArray has large value in!

Resources