I was wondering how to repeat an array in C any number of times.
Let's say I have an array like: int Array[4] = [1, 2, 3, 4]
Is there a simple way to get an array: int Array2[8] = [1, 2, 3, 4, 1, 2, 3, 4]
by doing some operation on Array[4]?
I'm pretty sure this is a bad idea, which will hit you in the foot later, but maybe try
#define VALUES 1, 2, 3, 4
int a[] = { VALUES, VALUES, VALUES, VALUES };
You can try this...to get an idea on how you can do it.
for(int i=0;i<8;i++) {
array2[i]=array[i%4];
}
This should be a good way to repeat an array in C any number of times because your explanation is not a good one. The modulo operation returns integers from [0,REPEAT) so doing +1 you have integers in [1,REPEAT].
Here is the code:
#define N 5
#define REPEAT 2
int main(){
int arr[N];
for(int i = 0;i<N;i++){
arr[i] = (i % REPEAT) + 1;
printf("%d\n",arr[i]);
}
return 0;
}
Output:
1
2
1
2
1
The simplest way to do this might be to use a VLA, sized to whatever you require, and filled by using the modulus operator. Disadvantages include the inability to return such an array from a function, and silent failure when the VLA can't be allocated for some reason. Of course, VLA's were introduced in C99, and then made optional in C11. Though they are commonly available, you may opt for the next method.
Perhaps a more reliable approach uses a function that allocates space for the new array. If malloc() fails, a null pointer is returned, so it is the responsibility of the caller to check this. It is also the callers responsibility to free the allocation when through with it.
#include <stdio.h>
#include <stdlib.h>
void print_arr(size_t, int *);
int * expand_array(size_t, int *, size_t);
int main(void)
{
int input_arr[] = {1, 2, 3, 4};
size_t input_arr_sz = sizeof input_arr / sizeof *input_arr;
size_t new_arr_sz = 17;
/* Method 1: VLA */
int new_arr_1[new_arr_sz];
for (size_t i = 0; i < new_arr_sz; i++) {
new_arr_1[i] = input_arr[i % input_arr_sz];
}
print_arr(new_arr_sz, new_arr_1);
/* Method 2: function with malloc() */
int *new_arr_2 = expand_array(input_arr_sz, input_arr, new_arr_sz);
if (new_arr_2) {
print_arr(new_arr_sz, new_arr_2);
}
free(new_arr_2);
return 0;
}
void print_arr(size_t sz, int *arr)
{
for (size_t i = 0; i < sz; i++) {
printf("%3d", arr[i]);
}
putchar('\n');
}
int * expand_array(size_t input_sz, int *arr, size_t output_sz)
{
int *new_arr = malloc(sizeof *new_arr * output_sz);
if (new_arr) {
for (size_t i = 0; i < output_sz; i++) {
new_arr[i] = arr[i % input_sz];
}
}
return new_arr;
}
Program output:
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1
I figured it out!
So if I have an array: int Array[4] = [1, 2, 3, 4];
To repeat it I used two for loops as such:
int Array2[8];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
Array2[i*4 + j] = Array[j];
}
}
The i*4 + j made it so I could count past four in the assignment of Array2
Related
Problem
Given a sequence of N integer values(possible values of N: 3, 5, 7, 9, 11 ...). Using at most one conditional operator(or conditional ternary operation), the program must determine whether it is true that every three elements the sequence increases and then decreases(sine sequence). Loops in a program can only be used to enumerate elements of a sequence.
Example
* *
* * * *
* * *
What I think
int compare_num(int num1, int num2)
{
return (int)(((num1 + num2) - sqrt((num1 - num2) * (num1 - num2))) / 2);
}
bool_t is_increasing2(int arr[], int size)
{
int tmin = arr[0];
int res = 0;
for (int i = 0; i < size - 1; i++)
{
tmin = compare_num(arr[i + 1], tmin);
res = tmin ^ arr[i + 1];
}
return res;
}
int main(void)
{
int arr[] = {10, 9, 8, 7, 6, 5};
int arr2[] = {1, 2, 3, 4, 5};
int res = is_increasing2(arr2, N);
if (res == 0)
{
printf("Decreasing\n");
}
else
{
printf("Increasing\n");
}
return 0;
}
I use this code to check, that sequence is increasing or not. But now I need to use it to check, that my sine sequence is sine and I can't use more ternary or if/else operators
There is what I have to real problem
bool_t is_increasingSine2(int arr[], int size){
int tmax = 0;
int res = 0;
for(int i = 0; i < size; i += 3){
for(int j = i; j < i + 2 && j < size - 1; j++){
tmax = compare_num(arr[j], arr[j + 1]);
res = tmax ^ arr[j + 1];
}
//There if res == 0 part of sine is increasing otherwise not, but what to do next???
}
return 0;
}
You do not need any conditional operators for this problem, but we will use one in the printf since it is suggested.
Rephrasing the problem as a requirement that each of the first two elements must be less than the one that follows it and each of the next two must be greater than the one that follows it makes it fairly simple to test:
#include <stdio.h>
#include <stdlib.h>
/* Given array Array with N elements, return true iff each of the first two
elements is less than the one following it, each of the next two is greater
than the one following it, and then repeating in a cycle until the end of
the array.
*/
static _Bool TestCriterion(int Array[], size_t N)
{
/* Iterate through each element of the array except the last (the one
with index N-1), since there is no element following the last element
to compare it to.
*/
for (size_t i = 0; i < N-1; ++i)
{
/* Set phase to 0 for the first two elements, 1 for the next two,
then 0, 1, 0, 1… Note that while "i & 2" has the value 0 or 2,
assigning it to a Boolean produces a value of 0 or 1.
*/
_Bool Phase = i & 2;
/* For phase 0, test whether the element with index i is less than
the element with index i+1, and return false (0) if it is not. For
phase 1, compare element i+1 with element i.
*/
if (! (Array[i+Phase] < Array[i+1-Phase]))
return 0;
}
// All elements passed the test, so return true (1).
return 1;
}
/* Compute the number of elements in an array by dividing the size of the
array by the size of an element.
*/
#define NumberOf(a) (sizeof (a) / sizeof *(a))
int main(void)
{
int Array[] = { 1, 2, 3, 2, 1, 2, 3, 2, 1 };
printf("%s.\n", TestCriterion(Array, NumberOf(Array)) ? "Passes" : "Fails");
}
I'm trying to jump from an element to another element with a specified number for jumping and how many times it jumps, for example, k=4, and if it reaches the end it goes back from where it started. For example, as in the code, the array for a[Max] will be like {1,4,7,1}
#define Max 100
int main() {
int i=0,n,k,counter,j=0;
char v[Max]={1,2,3,4,5,6,7,8};
int a[Max];
k=4;
counter=k+1;
int size=strlen(v);
while(counter!=0) {
for(i=0;i<size;i=i+k-1){
a[j]=(int)v[i];
j++;
counter--;
}
}
}
You shouldn't be using a string or strlen() for this. Use an int array and you can get the size of your int array by using sizeof. Here, sizeof(v) will tell you the number of bytes allocated for your array, which in this case is 36 (Assuming ints are 4 bytes). Then you can divide by the number of bytes of an integer with sizeof(int) to get the number of elements in your array, 9.
You're segfaulting because you're writing outside the bounds of your array. You don't need that outer loop and should remove it entirely.
To get the wrapping around of your array, use the modulus operation (%) with the size of your array. Understanding The Modulus Operator %
#include <stdio.h>
#define MAX 100
int main() {
int i = 0, ii = 0, k = 4, counter = k - 1, j = 0;
int v[]= {1, 2, 3, 4, 5, 6, 7, 8, 9};
int a[MAX];
int size = sizeof(v) / sizeof(int);
for (i=0; counter >= 0; i += k - 1) {
a[ii++] = v[j];
counter--;
j = (j += 3) % size;
}
for (int i = 0; i < k; i++) {
printf("%d\n", a[i]);
}
}
Output:
1
4
7
1
I think I'm close to being able to complete this program, but I'm not entirely sure how to continue.
Basically, I have three arrays. Array 3 is empty, and Array 1 and Array 2 have values that are up to the users discretion. I want to merge Array 1 and Array 2 into Array 3 in such a way that they're alternating between even and odd positions in Array 3.
So, for example:
Array 1 = [1,2,3,4,5]
Array 2 = [10,20,30,40,50]
And Array 3 = [0,0,0,0,0,0,0,0,0,0]
I want the end result to look like so:
Array 3 = [1,10,2,20,3,30,4,40,5,50]
That's what I mean when I say I want Array 1 to fill odd values, and Array 2 to fill even values.
This is what the relevant piece of code I have so far looks like:
void EvenOdd(int n, int *ap1, int *ap2, int *ap3) {
// "n" is set to 5.
ap1 = arr1;
ap2 = arr2;
ap3 = arr3;
int i;
int j;
int k;
for (i = 0; i < n * 2; i++) {
for (j = 0; j < n; j++) {
if ((i + 1) % 2 != 0)
ap3[i] = ap1[j];
}
for (k = 0; k < n; k++) {
if ((i + 1) % 2 == 0)
ap3[i] = ap2[k];
}
}
}
arr1, arr2, and arr3 are all global arrays.
Every time I run the program, it only assigns the last values of Array 1 and Array 2 to the positions in Array 3, like so:
Array 1 = [1,2,3,4,5]
Array 2 = [6,7,8,9,10]
And Array 3 = [5,10,5,10,5,10,5,10,5,10]
This all suggests to me that the two for loops inside of the first one keep running for "i" until they reach the end of their array every time, which is why the last values are consistently assigned, but I'm not sure how to fix this to have the intended result.
I would go for something like this
void EvenOdd(int n, int*ap1, int*ap2, int*ap3){
// "n" is set to 5.
ap1=arr1;
ap2=arr2;
ap3=arr3;
int i;
for(int i = 0; i < 2 * n; i++)
{
if(i%2)
{
*ap3= *ap2;
ap1++;
}
else
{
*ap3= *ap1;
ap2++;
}
ap3++;
}
}
Problem:
That's what I mean when I say I want Array 1 to fill odd values, and
Array 2 to fill even values
Actually, in the case of indices, array1 fills the even indices and array2 fills the odd indices. Luckily, your code works in this regard because you check the parity of i + 1, and not i.
Every time I run the program, it only assigns the last values of Array
1 and Array 2 to the positions in Array 3, like so:
The i-loop is responsible to fill the destination array. But you have two other loops nested inside it, which rewrite ap[i] over and over with the value in even and odd indices of ap1 and ap2. The last value that remains in ap[i] is when the j-loop and k-loop ends. That is why, you see repeated values filled inside ap3 from the end of ap1 and ap2.
Solution:
You simply need a single i-loop that fills the destination array after checking the parity of i.
for (int i = 0; i < 2 * n; ++i)
ap3[i] = i % 2 ? ap2[i / 2] : ap1[i / 2];
An other way would be
#include <stdio.h>
void EvenOdd(int n, int *ap1, int *ap2, int *ap3) {
for (int i = 0; i < 2 * n; i++)
if(i % 2 == 0)
ap3[i] = ap1[i / 2];
else
ap3[i] = ap2[i / 2];
}
int main() {
int arr1[5] = {1, 2, 3, 4, 5};
int arr2[5] = {10, 20, 30, 40, 50};
int arr[10];
EvenOdd(5, arr1, arr2, arr);
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
return 0;
}
Output
1 10 2 20 3 30 4 40 5 50
You could do something like this:
int ap1[5] = {1, 2, 3, 4, 5};
int ap2[5] = {10, 20, 30, 40, 50};
int ap3[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int j = 0;
int k = 0;
for (int i = 0; i < 10; i++) {
if (i % 2 != 0) { // if i is odd
ap3[i] = ap2[j++]; // set ap3 to jth value in ap2; j becomes j+1
} else { // if i is even
ap3[i] = ap1[k++]; // likewise, but ap1 and k becomes k+1
}
}
for (int i = 0; i < 10; i++) {
printf("%d ", ap3[i]);
}
Output is 1 10 2 20 3 30 4 40 5 50.
Your issue is that the nested loops are unnecessary and infact rewriting values when you don't want them to.
Given:
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
I want to split the 2d array (struct MATRIX) into the an array of struct MATRIX
given a chunksize CS:
assume cs to be 2,
the answer would be
Seg[0]:
1 2
1 2
1 2
Seg[1]:
3 4
3 4
3 4
....
Seg[3]:
7 8
7 8
7 8
Here is my Matrix Struct:
typedef struct MATRIX {
int nrow;
int ncol;
int **element;
} MATRIX;
and here is the function the seperates them:
void SegmentMatrix(MATRIX input,MATRIX* segs,int Chunksize, int p) {
int i,j,r;
//Allocate segs
for (i = 0; i<p;i++)
{
CreateMatrix(&(segs[i]),input.nrow ,Chunksize,0);
}
//Now Copy the elements from input to the segs
//where seg0 takes from 0 to cs cols of a, and all their rows, and seg1 takes from cs to 2cs ...
printf("Stats:\n\t P: %d\t CS: %d\n",p,Chunksize);
for (r = 0; r<p; r++) {
for (i = 0; i<input.nrow;i++) {
for (j = r*Chunksize; j<r*Chunksize+Chunksize-1; j++) {
//I tried (&(segs[r]))->element... Doesn't work, produces wrong data
segs[r].element[i][j] = input.element[i][j];
}
}
PRINTM(segs[r]);
}
}
Note that PRINTM basically prints the matrix, it knows the limits by checking segs[r].nrow and ncol
and CreateMatrix takes the following inputs (&matrix, number of rows, number of colums, filltype) and mallocs from within.
filltype:
0- generates zeroth matrix
1- generates identity
else A[i][j] = j; for simplicity
The problem is that the if i print the matrices Segs[i], they all come down with their default value given by CreateMatrix, and not the newly added values.
CLARIFICATION:
Okay, so if you guys check that last PRINTM in SegmentMatrix function, it outputs the matrices as if the for loops didn't happen, aka, i can delete the for loops and would get the same output..
did i do something wrong in this line (taken from the SegmentMatrix)
Segs[r].element[i][j] = input.element[i][j];
I don't see why and what you are manipulating with multiplication by ChunkSize and r (which is uninitialized anyway), I'd suggest simplifying the code (rule of thumb: if it seems messy, it's too complex). All you need is a 3-dimensional array to store the array of chunks, and modulo arithmetic plus integer division to insert into the appropriate column of the appropriate chunk:
/* the variable-sized dimension of the `chunks' argument is w / chsz elements big
* (it's the number of chunks)
*/
void split(int h, int w, int mat[h][w], int chsz, int chunks[][h][chsz])
{
/* go through each row */
for (int i = 0; i < h; i++) {
/* and in each row, go through each column */
for (int j = 0; j < w; j++) {
/* and for each column, find which chunk it goes in
* (that's j / chsz), and put it into the proper row
* (which is j % chsz)
*/
chunks[j / chsz][i][j % chsz] = mat[i][j];
}
}
}
Demonstration, a. k. a. how to call it:
int main(int agrc, char *argv[])
{
const size_t w = 8;
const size_t h = 3;
const size_t c = 2;
int mat[h][w] = {
{ 1, 2, 3, 4, 5, 6, 7, 8 },
{ 1, 2, 3, 4, 5, 6, 7, 8 },
{ 1, 2, 3, 4, 5, 6, 7, 8 }
};
int chunks[w / c][h][c];
split(h, w, mat, c, chunks);
for (int i = 0; i < w / c; i++) {
for (int j = 0; j < h; j++) {
for (int k = 0; k < c; k++) {
printf("%3d ", chunks[i][j][k]);
}
printf("\n");
}
printf("\n\n");
}
return 0;
}
Question was unclear . so i thought he wanted just to know how to achieve this.
So i wrote this simple Pseudo code . Otherwise accept my apologize :
matrix[i] matrix
//matrixes total column size should be bigger big 2d array column size
first condition check: sum(matrix[i].colsize)>=big2d.colsize
//in this simple code raw sizes must be equal
second condition: for all i matrix[i].rawsize=big2d.rawsize
//if columns sizes will be equal the algorithm could be simplified , does not mean optimized
//splitting big2d into matrixes
for (int br=0;br<big2d.rawsize;br++){
i=0;//store matrix index
int previndex=0;//store offset for next matrix
for(int bc=0;bc<big2d.colsize;bc++){
matrix[i].val[bc-previndex][br]=big2d.val[bc][br]; //assign (bc,br)
if(bc-previndex==matrix[i].colsize-1){
i++; //move to next matrix;//if we not have next matrix then break;
previndex=bc+1;
}
/*if it be for equal chunks matrixes offset can be calculated this way too
matrix[bc/chunk].val[bc%chunk][br]=big2d.val[bc][br];
*/
}//loop columns
}//loop raws
How would you write something that selects all possible combinations of triples from an array {1, 2, 3, ..., N-1, N} without duplicates? This is from a recently-held programming competition. N is a multiple of 3.
Example using array {1,2,3,4,5,6}:
C_1 = { {1,2,3}, {4,5,6} }
C_2 = { {1,2,4}, {3,5,6} }
C_3 = { {1,2,5}, {3,4,6} }
are all valid, but
C_bad1 = { {1,2,3}, {3, 4, 5} }
C_bad2 = { {1,2,4}, {3, 5, 6}, {1, 2, 5} }
are not.
you have (N!) / ( ((3!)^(N/3)) * ((N/3)!)) position (prove) . you can just use recursive algorithm for provide all possible combinations of triples from an array {1, 2, 3, ..., N-1, N} without duplicates.
but for produce one of them you can use any idea such as user1952500 idea(though This algorithm also generates (N/3)! position duplicate) or every, for example you invariant last-(N-6)-member and put your solution for first-6-member in start of your result.(this algorithm do not generate duplicate position)
recursive solution:
void combtriples(int begin)
{
for(int i=1;i<=(n/3);i++)
for(int j=1;j<=(n/3);j++)
for(int k=1;k<=(n/3);k++)
{
if ((mark[i]<3) && (mark[j]<3) && (mark[k]<3))
{
count-position++;
c[count][3]=begin;
c[count][4]=begin+1;
c[count][5]=begin+2;
mark[i]++;
mark[j]++;
mark[k]++;
count-member-flase=count-member-flase+3;
if (count-member-flase > 0)
{
combtriples(begin+3);
}
}
}
}
int main()
{
int mark[];
int c[][];
count-position=0;
count-member-flase=0;
combtriples(1);
return 0;
}
Since N is a multiple of 3 we can solve it using a trick:
Generate all permutations of the numbers in ascending order
For each permutation,
partition the numbers into sets of 3 directly (0-2, 3-6,..., N-2..N)
That should give you your result without much fancy work.
EDIT: I was waiting for someone to spot the issue with the above and it was indeed spotted. The way to fix repetitions is to have an additional step:
Step 3: If any triple is lexicographically unsorted form discard the set. Else continue.
#include <stdio.h>
#define SEL_NUM 3
#define LIST_SIZE 6
void printset(int *list, int *map, int size);
void select(int *list, int *map, int n, int size, int start);
int main(int argc, const char **argv) {
int list[LIST_SIZE] = {1, 2, 3, 4, 5, 6};
int map[LIST_SIZE] = {0};
select(list, map, SEL_NUM, LIST_SIZE, 0);
return 0;
}
void select(int *list, int *map, int n, int size, int start) {
if (n == 0) {
printset(list, map, size);
return;
}
for (int i = start; i < size; i++) {
map[i] = 1;
select(list, map, n - 1, size, i + 1);
map[i] = 0;
}
}
void printset(int *list, int *map, int size) {
int list1[SEL_NUM], list2[SEL_NUM], list1cnt = 0, list2cnt = 0;
for (int i = 0; i < size; i++)
if (map[i])
list1[list1cnt++] = list[i];
else
list2[list2cnt++] = list[i];
for (int i = 0; i < list1cnt; i++)
printf(" %d ", list1[i]);
printf(" -- ");
for (int i = 0; i < list2cnt; i++)
printf(" %d ", list2[i]);
printf("\n");
}
Let's consider how many such distinct triplet-sets exist for N. First define T = floor(N/3) as the number of triplets in each set supported by N elements. Then note that since duplicate triplets are not desired, the triplets in each triplet set can be sorted ascending by first element without loss of generality. Then the total number of triplet-sets for N is:
product as t: 0 -> T-1 of ( (N - 3*t - 1) * (N - 3*t - 2) / 2 )
From this formula it is straightforward to see how to build the (brute-force) algorithm to generate the triplets.
Update: The above works only for N % 3 == 0. I am working on a generalization now. Forced; see comment by OP
Cases:
N<3 yields 0
N=3 yields 1
N=6 yields (5 * 4 / 2) * (2 * 1 / 2) = 10
N=9 yields (8 * 7 / 2) * (5 * 4 / 2) * (2 * 1 / 2) = 28 * 10 = 280
As you are in a programming competition, I assume you dont need any code.
Update #2:
Note that to automatically eliminate duplicates, the first element of each triplet must be forced to the lowest numbered unselected element .