So I have this code that I'm trying to figure out how to read without running it yet I can't seem to find out the pattern and the way to do so. I was hoping someone could give me an explanation of how to read it.
#include <stdio.h>
void mystery(int z[], int size);
void main()
{
int i;
int z[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (i = 0; i < 10; i++)
printf("%d", z[i]);
printf("\n\n");
mystery(z, 10);
for (i = 0; i < 10; i++)
printf("%d", z[i]);
printf("\n\n");
mystery(z, 7);
for (i = 10; i < 7; i++)
printf("%d", z[i]);
printf("\n\n");
}
void mystery(int z[], int n)
{
int i, temp;
for (i = 1; i < n / 2; i = i + 2)
{
temp = z[i];
z[i] = z[n - 1 - i];
z[n - 1 - i] = temp;
}
return;
}
When running it, the code reads
1 2 3 4 5 6 7 8 9 10
1 9 3 7 5 6 4 8 2 10
The key is that you understand this loop:
for (i = 1; i < n / 2; i = i + 2)
{
temp = z[i];
z[i] = z[n - 1 - i];
z[n - 1 - i] = temp;
}
i + 2 means the step (the increment). The step is 2 rather than 1 in this case which means that i will increase like 1, 3, 5, 7... up to n / 2. The content of the loop just switches the outer elements of the bounds i.e. the first iteration the elements 2 and 9 will switch places.
Because the start of the loop is i=1(and not i=0) the first element is not affected by the loop. Remember arrays start at 0, so the second element has index 1 and that's where the loop starts: At the second element. And since the step is 2, only every second element will switch. I hope this answers your question.
Related
I have written this code in order to implement the Counting Sort in C. However it does not seem working properly.
I create an array of 10 elements and then I apply the steps of counting sort. Basically it orders the first elements, and then as last elements it uses the last elements of the original array. I am not understanding where is the problem.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
// create an array of 100 random elements
// int my_array[10];
int my_array[] = { 10, 10, 9, 9, 6, 5, 4, 3, 2, 1 };
srand(time(NULL));
int i;
int N = 10;
/* for (i = 0; i < 10; i++) {
my_array[i] = rand() % 100 + 1;
} */
// print the array
for (i = 0; i < 10; i++) {
printf("%d\n", my_array[i]);
}
// define the minimum and the maximum as the first element of the array
int min_array = my_array[0];
int max_array = my_array[0];
printf("--------------\n");
// find the minimum and the maximum of the array
for (i = 0; i < N; i++) {
if (my_array[i] < min_array) {
min_array = my_array[i];
}
else if (my_array[i] > max_array) {
max_array = my_array[i];
}
}
// check if it worked
printf("max_array %d\n", max_array);
printf("min_array %d\n", min_array);
//
int range_array;
range_array = max_array - min_array + 1;
int count_array[range_array + 1];
for (i = 0; i < range_array; i++)
count_array[i] = 0;
int j = 0;
for (int i = 0; i < 10; i++) {
count_array[my_array[i] - min_array] = count_array[my_array[i] - min_array] + 1;
}
int z = 0;
for (i = min_array; i < max_array; i++) {
for (j = 0; j < count_array[i - min_array]; j++)
my_array[z++] = i;
// z = z + 1;
}
for (i = 0; i < N; i++) {
printf("%d\n", my_array[i]);
}
}
And one possible output:
10 10 9 9 6 5 4 3 2 1
--------------
max_array 10
min_array 1
--------------
1 2 3 4 5 6 9 9 2 1
So as you can see the numbers from 1 to 9 are ordered, while the last one, 10, is not ordered, and it uses the first numbers, so 1 and 2.
When rebuilding the array, you want to include the elements with a value of max_array.
i<max_array
should be
i<=max_array
As a side note, you never use the last element of count_array, so it should be one element smaller.
int count_array[range_array + 1];
should be
int count_array[range_array];
(Spotted by #user3386109)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm totally beginner and I have problem in C. So I have array:
A[5] = {14, 2, 7, 3, 2};
And I want make something like this:
A[6] = {1, 4, 2, 7, 3, 2};
From 14 to 1, 4. Any idea how to do that?
So I making the problem from Cs50. Here is a link: https://docs.cs50.net/2018/x/psets/1/credit/credit.html
And here is my code:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
int main(void)
{
long long cc_number = 0;
do
{
printf("Number: ");
cc_number = get_long_long();
}
while(cc_number <= 0);
int num_of_digits = 0;
long long valid = cc_number;
while(valid > 0)
{
valid /= 10;
num_of_digits++;
}
if (num_of_digits != 13 && num_of_digits != 15 && num_of_digits != 16 ) //checking if number have more or less than 13,15,16 digits
{
printf("Number is invalid!\n");
}
long long k = 1; //create array for store each number from the card
int A[16], d, num = 0;
for(num = 0; num < 16; num++)
{
d = (cc_number/(1*k)) % 10;
A[num] = d;
k *=10;
}
///////////////////////////////////////////////////////////////////////
if (num_of_digits == 16)
{
for (int i = 0; i < 16; i = i + 2)
{
A[i] *= 2; // multiplay each second digit by 2
printf("this is %i\n", A[i]);
}
}
else if (num_of_digits == 15 || num_of_digits == 13 )
{
int sum = 0;
for (int i = 1; i < 15; i = i + 2)
{
int y = A[i];
A[i] *= 2; // multiplay each second digit by 2
if (A[i] > 9) // try to split digit from array
{
y = A[i] % 10;
A[i] /= 10;
}
sum += A[i];
printf("this is %i\n", A[i]);
}
printf("this is sum %i\n", sum);
}
///////////////////////////////////////////////////////////////////////////
}
And this is what i want to do:
For the sake of discussion, let’s first underline every other digit,
starting with the number’s second-to-last digit:
378282246310005
Okay, let’s multiply each of the underlined digits by 2:
7•2 + 2•2 + 2•2 + 4•2 + 3•2 + 0•2 + 0•2
That gives us:
14 + 4 + 4 + 8 + 6 + 0 + 0
Now let’s add those products' digits (i.e., not the products themselves) together:
1 + 4 + 4 + 4 + 8 + 6 + 0 + 0 = 27
Now let’s add that sum (27) to the sum of the digits that weren’t multiplied by 2:
27 + 3 + 8 + 8 + 2 + 6 + 1 + 0 + 5 = 60
Yup, the last digit in that sum (60) is a 0, so my card is legit!
Assuming you want to create an array of single digit integers from array of multi-digit integers
#include <stdio.h>
#define MAX 1024
void printarr(int *a, int n) { // function to print array
for(int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int main() {
int a[5] = {14, 2, 7, 3, 2};
int b[MAX];
int k = 0;
printarr(a, 5);
char s[MAX]; // char buffer to store char array
for(int i = 0; i < 5; i++) {
sprintf(s, "%d", a[i]);// convert int to char array
int j = 0;
while(s[j]!='\0') { // for each digit, create a new integer
b[k++] = s[j++] - '0';
}
}
printarr(b, k);
return 0;
}
Output:
14 2 7 3 2
1 4 2 7 3 2
Else for specific case
#include <stdio.h>
#define MAX 1024
void printarr(int *a, int n) { // function to print array
for(int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int main() {
int a[5] = {14, 2, 7, 3, 2};
int b[6];
printarr(a, 5);
b[0] = 1;
b[1] = 4;
for(int i = 2; i < 6; i++) {
b[i] = a[i - 1];
}
printarr(b, 6);
return 0;
}
Output:
14 2 7 3 2
1 4 2 7 3 2
Here is a solution that does not use strings.
First of all, we have to determine how long the new array will be. To this end, we determine how many digits each entry has. For n > 0 the number of digits is ⌊log10(n) + 1⌋.
After that, we extract the digits. 123 can be split into its digits by using integer division / and modulo % (remainder of integer division):
123 % 10 = 3 least significant digit
123 / 10 = 12
repeat
12 % 10 = 2 second least significant digit
12 / 10 = 1
repeat
1 % 10 = 1 third least significant digit
1 / 10 = 0
end
As you can see, the digits are extracted from the back, therefore we also fill the output array from the back.
#include <stdio.h>
#include <math.h>
int digitCount(int n) {
if (n)
return (int) log10(n) + 1;
return 1;
}
int main() {
int inputLength = 5;
int input[] = {14, 1, 9, 0, 5819};
int outputLength = 0;
for (int i = 0; i < inputLength; ++i)
outputLength += digitCount(input[i]);
int output[outputLength];
int o = outputLength;
for (int i = inputLength - 1; i >= 0; --i) {
int n = input[i];
do {
output[--o] = n % 10;
n /= 10;
} while (n);
}
while (o < outputLength) {
printf("%d ", output[o++]);
}
}
clang -lm file.c && ./a.out prints 1 4 1 9 0 5 8 1 9.
In Question, When an array X of size n and a degree k are input,
Write a program that calculates the k-th moving average of array X.
The kth-order moving average of the array X consisting of primitive data values is the average of the last k elements up to the i-th point of X.
That is, A [i] = (X [i-k + 1] + X [i-k + 2] + ... + X [i]) / k.
If the number of the preceding element (including itself) is smaller than k,
Calculate as an average.
For example, if array X is as follows and k is 3, X = 1 3 2 10 6 8
The third moving average is as follows.
A = 1 2 2 5 6 8 A [1] = (1 + 3) / 2, A [2] = (1 + 3 + 2) / 3
However, the program must have the execution time of O (n), not O (nk).
Round off the decimal point in the average calculation and obtain it as an integer.
For exact rounding, do not use% .f, but round it using the int property.
int main()
{
int i, n1, k;
int *array1;
scanf("%d", &n1);
array1 = (int *)malloc(sizeof(int)*n1);
scanf("%d", &k);
for (i = 0; i < n1; i++)
{
scanf("%d", &array1[i]);
}
double tmp = 0;
for (int i = 0; i < n1; i++)
{
tmp += array1[i];
if (i >= k)
{
tmp -= array1[i - k];
}
if (i >= k - 1)
{
double average = tmp / k;
printf("%2lld ", llrint(average));
}
return 0;
}
The program does not work because the problem is not understood.
I would like to know how to solve it.
add) Thank you for answer but the output required by the problem is as follows.
Input : 9 4 (n = 9, k = 3)
2 7 4 5 6 8 2 8 13
Output : 2 5 4 5 6 6 5 6 8
After Modifying your code
int main()
{
int i, n1, k;
int *array1, *array2;
scanf("%d", &n1);
array1 = (int *)malloc(sizeof(int)*n1);
scanf("%d", &k);
for (i = 0; i < n1; i++)
{
scanf("%d", &array1[i]);
}
double tmp = 0;
for (int i = 0; i < n1; i++)
{
tmp += array1[i];
// now tmp contains exactly k + 1 elements sum
// so subtract elements outside of k sized window(leftmost element)
if(i >= k) {
tmp -= array1[i - k];
}
if(i >= k - 1) {
double average = tmp / k;
printf("%lf\n", average);
}
}
return 0;
}
I am trying to create a sorting method based on selection sort algorithm
With this current code, the array [10, 9, 8 .. 1] is "sorted" to
[9, 8 .. 2, 10, 1]
I mean like, it doesn't even put 10 in the right place
10 9 8 7 6 5 4 3 2 1
"sorted" to
9 8 7 6 5 4 3 2 10 1
What's the problem ?
void selectionSort(int array[], int length)
{
int i = 0, j = 0, temp = 0, swap = 0;
for(i = 0; i < length; i++)
{
temp = i;
for(j = 0; j < length; j++)
{
if(array[temp] > array[j])
{
temp = j;
}
}
swap = array[temp];
array[temp] = array[i];
array[i] = swap;
}
}
The inner loop should be written like
for(j = i + 1; j < length; j++)
^^^^^^^^^
After each iteration of i, the array upto i , should be sorted. You can print the array after each iteration of i and can see the logical error.
I have a global integer pointer array, which is created this way
int * array;
array = (int *) malloc(size * sizeof(int));
I also have a sorting algorithm, which is supposed to sort 4 first numbers of the array which size is larger than 4 (16 in this case). sizeOfArray is defined as 4 in this case:
int temp,i,j;
for(i=0;i<sizeOfArray;i++){
for(j=i;j<sizeOfArray;j++){
if(array[i] > array[j]){
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
}
Output is really weird for some reason:
Unsorted: 7,6,9,3
Sorted: 3,6,5,1
The weirdest part is if I change algorithm to sort numbers in a descending order, it seems to work:
if(array[i] < array[j])
Unsorted: 10,0,1,8
Sorted: 10,8,1,0
What's causing this? I'm completely lost.
Here is your code wrapped to make an MCVE How to create a Minimal, Complete, Valid Example?:
#include <stdio.h>
#include <stdlib.h>
static void print(int n, int a[n])
{
for (int i = 0; i < n; i++)
printf("%2d", a[i]);
putchar('\n');
}
int main(void)
{
int size = 16;
int *array = (int *) malloc(size * sizeof(int));
array[0] = 7;
array[1] = 6;
array[2] = 9;
array[3] = 3;
int sizeOfArray = 4;
printf("Before:");
print(sizeOfArray, array);
int temp, i, j;
for (i = 0; i < sizeOfArray; i++)
{
for (j = i; j < sizeOfArray; j++)
{
if (array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
printf("After: ");
print(sizeOfArray, array);
return 0;
}
The output from this program is:
Before: 7 6 9 3
After: 3 6 7 9
Since this is not the same as the output you get, there must be a difference — a crucial difference. Since you don't show the code that initializes the array, nor show the code that demonstrates that the first 4 elements have the unsorted values, nor show the code that demonstrates the sorted values are wonky, it is not possible to say for certain what is wrong — but the problem is not in the code you show.
I've not fixed the code to check that the memory allocation succeeds; nor have I modified the code to release the allocated space. Both should be done.
The code does use C99 features; it is trivial to revise it not to do so:
static void print(int n, int *a)
{
int i;
for (i = 0; i < n; i++)
and move the definition of sizeOfArray before the assignments.
I am sure this will work for your sorting array...in 2nd iteration sizeofarray-1 will work for loop j...
int temp,i,j;
for(i=0;i<sizeOfArray;i++)
{
for(j=0;j<sizeOfArray-1;j++)
{
if(array[i] > array[j])
{
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
}
Let's do some iterations of your code with the values you provide : 7,6,9,3. Also, let's assume that sizeOfArray = 4.
For i = j, your condition will never be executed, because array[i] = array[j].
For i = 0 and j = 1 => 7 > 6 => array = {6, 7, 9, 3}
For i = 0 and j = 2 => 6 < 9 => array = {6, 7, 9, 3}
For i = 0 and j = 3 => 6 > 3 => array = {3, 7, 9, 6}
For i = 1 and j = 2 => 7 < 9 => array = {3, 7, 9, 6}
For i = 1 and j = 3 => 7 > 6 => array = {3, 6, 9, 7}
For i = 2 and j = 3 => 9 > 7 => array = {3, 6, 7, 9}
Thus, I obtained the four first elements of your array sorted correctly (which contains size elements and I assume that size = 16).
If you're not sure about the value of sizeOfArray or size, I suggest you to print them and to check if it's really the value you want.
Hope this helps you.