How to perform split and join functions on Array in C? - c

How can I perform join and split functions on array elements in C?
For example, let's say I have two arrays:
int value[]= {0,1,2,3};
int id[] = {1,1,3,3};
// I want to join the elements of "value" array whoz value of "id" are same.
//In my case 0,1 elements from "value" array has the same "id" value that is 1,1
//and 2,3 from "value" has same "id" value 3,3. So it will join {01,23}
//And if i want to perform split function it will give me back{0,1,2,3}
I did the same thing in perl script but i am not sure how can I get this functionality in C?

C doesn't have built-in "dynamic" arrays like those of many higher-level languages.
You must allocate the needed storage yourself using malloc(), then copy the desired data element by element into the new array.
Also I can't quite understand the desired operations that you describe ... "Join elements of value whose value of id are the same" doesn't make sense.
Do you want to compute the intersection of the arrays? But they're clearly not sets, so that doesn't sound right either.

The following will do what you want:
#include <stdlib.h>
#include <stdio.h>
int main(){
int i,v;
int ID_SIZE=7;
int value[]={0,1,2,3,1,4, 7};
int id[]= {1,1,3,3,2,2,10};
//Discover largest and smallest ids in order to allocate memory
int min=0,max=0,length;
for(i=1;i<ID_SIZE;++i){
if(id[i]<id[min]) min=i;
if(id[i]>id[max]) max=i;
}
//Replace ids with values
min=id[min];
max=id[max];
length=max-min+1;
int **unions;
int *append;
append=(int *)calloc(length,sizeof(int));
for(i=0;i<length;++i)
append[i]=-1; //Initial insertion point for each id is at 0
//Create 2D array unions[IDS HERE][VALUES HERE]
unions=(int **)calloc(length,sizeof(int*));
for(i=0;i<length;++i)
unions[i]=(int *)calloc(ID_SIZE,sizeof(int));
//Join arrays
for(i=0;i<ID_SIZE;++i){
printf("Inserting %d into %d at %d\n",value[i],id[i],append[id[i]-min]+1);
unions[id[i]-min][++append[id[i]-min]]=value[i];
}
for(i=0;i<length;++i){
if(append[i]>=0){
printf("Id %d has: ",i+min);
for(v=0;v<=append[id[i]-min];++v)
printf("%d ",unions[i][v]);
printf("\n");
}
}
return 0;
}
It creates two dynamic arrays.
One array, called append keeps track of how many values have been found for each id.
The other array, called unions stores the result of the computation.
In the case of the input I define in the program, the following is returned:
Inserting 0 into 1 at 0
Inserting 1 into 1 at 1
Inserting 2 into 3 at 0
Inserting 3 into 3 at 1
Inserting 1 into 2 at 0
Inserting 4 into 2 at 1
Inserting 7 into 10 at 0
Id 1 has: 0 1
Id 2 has: 1 4
Id 3 has: 2 3
Id 10 has: 7

Related

Knapsack with a few twist

i'm struggling a bit to make my program work, it's a school homework we have to do for the holidays and basically this is what we have to do :
We are trying to fill a knapsack to it's maximum capacity while maximising it's value with objets from a given list.
i won't bore you with the details so i'll just go straight to where i'm currently having an issue.
i have a 2d dynamic array, i'm trying to check if a line of said array doesn't contain one of the elements in another array and if it does then i need to put everything on that line in a second array.
let's say i have this code :
int **exc, rexc, *lexc, i=0;
printf("\nHow many exclusion :");
scanf("%d", &rexc);
exc = malloc( sizeof(int *) * rexc);
for(i=0;i<rexc;i++){
printf("\nHow many elements in exclusion %d : ", i);
scanf("%d", &lexc[i]);
exc[i] = malloc( sizeof(Objet) * lexc[i]);
printf("\n the elements are :");
for(j=0;j<lexc[i];j++){
scanf("%d",&exc[i][j]);
}
}
With this i have initialized and filled my array.
Now i have another array with values let's say it's something like
inter[1]={5,6}
impos[1]={3,7}
And let's say our 2d array looks like this :
exc[3][3]={3,6,2}{2,7,1}{5,2,4}
What i need to do is search through my 2d array, if any line contain 3 or 7 ( it cannot contain both, i check that by using a function that make sure that there's no problem before running this function ), then every other elements of that line need to be added to the inter[] array.
How i thought i'd make this work was by doing something like this :
int count=0,i=0, j=0, k=0;
while(count<cimp){
for(i=0;i<rexc;i++){
for(j=0;j<lexc[i];j++){
if (exc[i][j] = impos[count])
for (k=0;k<lexc[i];k++){
if(k!=j){
inter[cinter+1]=exc[i][k];
cinter++;
}
}
}
count++;
}
cinter/cimp is a variable where i stored the number of elements in inter/impos.
the result i'm getting is kinda funky tho here's an output :
How many exclusion : 3
How many elements in exclusion 1 : 3
the elements are : 3 6 2
How many elements in exclusion 2 : 3
the elements are : 2 7 1
How many elements in exclusion 3 : 3
the elements are : 5 2 4
How many obligatory elements : 1
Which are : 5
Forbidden list : 5 0 6 2 5 2 5 5 7 1 5 1 5 5 2 4 5 4 5
I'm still getting used to C, hope i could get any help from you guys and sorry for making it such a long post !

3rd Array element does not print out when using a pointer variable to assign array element values

SO I was reading a book on C and came across a piece of code which I couldn't fully understand, so I decided to run it out and see the result for myself. Basically, I understand that an array variable acts like a pointer, in the sense, that it points to the first element of the array, for instance.
char quote[]="This is a nice cookie!"
Here quote which is an array variable, is basically a pointer to the first element of the array i.e. the letter T(Hope I am correct so far).
Building on this, when I write the below piece of code, I understand the following points.
At the declaration time, contestants is an array with 3 members in it - 1, 2 and 3
Then I use *choice as an array variable which in other words is a pointer to the first element of array contestants- which is now (1).
Now I begin dynamically assigning values to the members of the contestants array.
contestansts[2]=*choice
puts the value 0 in the 3rd member of the array i.e.: contestants[2].
So far, so good.
Now, the next for loop was not there in the book. I included it in the code myself, to see what are the elements of the array. When I run the code, as an output I get-
I will pick contestant number 2
The members of the array contestants are:
Member 0 has the value 2
Member 1 has the value 3
My question is- I do not understand how the member 1 has the value 3. According to the code, shouldn't members 1 and 2 both have the same value(2).
Any help would be highly appreciated.
I am using Sublime Text and the Mac terminal to run this(if needed).
#include<stdio.h>
int main()
{
int contenstants[]={1,2,3};
int *choice=contenstants;
contenstants[0]= 2;
contenstants[1]=contenstants[2];
contenstants[2]=*choice;
printf("\n I will pick contestant number %i\n", contenstants[2] );
//Print array members
printf(" The members of the array Contenstants are:\n");
for(int i=0;i<contenstants[2];i++)
{
printf(" Member %i\t has the value %i\t", i, contenstants[i] );
printf("\n");
}
return 0;
}
int contenstants[]={1,2,3};
int *choice=contenstants; // choice -> {1,2,3}
contenstants[0]= 2; // choice -> {2,2,3}
contenstants[1]=contenstants[2]; // choice -> {2,3,3}
contenstants[2]=*choice; // choice -> {2,3,2}
The output you get is totally logical!
In the first step you assign the value 2 to contenstants[0], which is also *choice.
The reason why you are only getting two numbers on the output is, that you loop for(int i=0;i<contenstants[2];i++), which is equivalent to for(int i=0;i<2;i++), which loops over element number 0 and element number 1.
It is 3 because you are doing
contenstants[1]=contenstants[2];
and then contenstants[1] is not modified later so it has value 3;
To answer your question in comment:
Condition in your for loop is not correct
--------------v not correct
for(int i=0;i<contenstants[2];i++)
You want
for(int i=0;i<3;i++)
Although using hardcoded 3 is also not a good idea. But it goes with your other code.

Adjusting position in array to maintain increasing order

I have undergone one problem in C in logic creation.What i have to do is:
1)I have array a[215] = {0,1,2,3,4,5}.Now i have to add two minimum elements of this array and then position the newly element obtained in the same array such that it will maintain the increasing order of the array(a[],which was already sorted array).
(2)I also have to take care that the two minimum added elements must not participate in sorting and addition again, they must be fixed at their position once if they are already added, but the newly obtained element by addition can participate in addition and sorting again.
eg:
we add two minimum element 0 and 1, 0+1=1, so "1" is the result obtained by addition, now this "1" must be positioned in a[] such that still there should be increasing order.
so :
0 1 1(added here) 2 3 4 5
Now we have to again find the minimum two nodes (please read the comment (2) again to understand well) .We cannot add 0 abnd 1 again because they have already participated in in the addition. so this time we will add 1 and 2(this one is at index three, please don't get confused wwith the one at index two). so we get 1+2=3
0 1 1 2 3 3 4 5 we again positioned 3 to maintain increasing order.
we repeat again: for element at index 4 and 5(because we have already done addition for element at index 0,1 and 2,3) we will get 3+3=6, again position it in a[].
0 1 1 2 3 3 4 5 6 this time 6 is greater then 4 and 5 so it will appear after 5 to maintain increasing order.
At last we will get a[] like this:
a[ ]= [0 1 1 2 3 3 4 5 6 9 15].
so the addition held was between index 0,1 and 2,3 and 4,5 and 6, 7 and 8,9 and at last we have 15 which is last one, so here we stops.
Now coming to how much i have already implemented :
I have implemented this addition part, which do addition on array a[ ] = [0 1 2 3 4 5].
And puts the newly obtained element at last index(which is dataSize in my code, please see data[dataSize++]=newItem).
Each time i call the function PositionAdjustOfNewItem(data,dataSize); giving the array(which also contains the newly obtained element at last index)as first argument and the newly obtained size as second argument.Here is the code below:
for(i=0;i<14;i++)
for(j=1;j<15;j++)
{
// This freq contains the given array (say a[]=[0 1 2 3 4 5] in our case and
// it is inside the struct Array { int freq}; Array data[256]; )
newItem.freq = data[i].freq + data[j].freq;
data[dataSize++]=newItem;
PositionAdjustOfNewItem(data,dataSize); // Logic of this function I am not able to develop yet. Please help me here
i=i+2;
j=j+1;
}
I am not able to implement the logic of function PositionAdjustOfNewItem(), which pass the array data[], which contains all the elements and the newly added element at last index and in second argument i pass the newly obtained size of array after putting the newly obtained element at last index.
Each time when i add two elements i call this PositionAdjustOfNewItem() passing the newly added elements at last and newly obtained size. which is supposed to be sorted by this function PositionAdjustOfNewItem().
This PositionAdjustOfNewItem() have as least complexity as possible.The part above the code was just to make you aware of mechanish i am using to add elements, You have nothing to do there, I need your help only in getting the logic of PositionAdjustOfNewItem().
(Even i already done it with qsort() but complexity is very high). so need any other way?
How about something like this:
NOTE: In your example, you are dealing with an array of some structure which has freq as a field. In my example, I am using simple integer arrays.
#include <stdio.h>
#include <string.h>
int a[] = {0,1,2,3,4,5};
int main(void) {
int i,j;
// Initialize a new array big enough to hold the result.
int* array = new int[15];
memcpy(array, a, 6*sizeof(int));
int length=6;
// Loop over consecutive indeces.
for (i=0; i+1<length; i+=2) {
// Get the sum of these two indeces.
int sum=array[i]+array[i+1];
// Insert the sum in the array, shifting elements where necessary.
for (j=length-1; j>i+1; j--) {
if (sum >= array[j]) {
// Insert here
break;
} else {
// Shift
array[j+1]=array[j];
}
}
array[j+1]=sum;
// We now have one more element in the array
length++;
}
// Display the array.
printf("{ ");
for (j=0; j<length; j++) {
printf("%d ", array[j]);
}
printf("}\n");
}
To insert the sum, what is done is we traverse the array from the end to the front, looking for the spot it belongs. If we encounter a value less then the sum, then we simply insert it after this value. Otherwise (i.e. value is greater than the sum), we need to insert it before. Thus, the value needs to be shifted one position higher, and then we check the previous value. Continue until we find the location.
If you only need the PositionAdjustNewItem method, then this is what it would look like:
void PositionAdjustOfNewItem(int* array, int length) {
int newItem = array[length-1];
for (int j=length-2; j>i+1; j--) {
if (sum >= array[j]) {
// Insert here
break;
} else {
// Shift
array[j+1]=array[j];
}
}
array[j+1]=sum;
}
When you run it, it produces the output you expect.
$ ./a.out
{ 0 1 1 2 3 3 4 5 6 9 15 }

Scanning values into a matrix without using [ ] C language

I have a problem. I was asked to write a program that transposes a matrix, without using []...for example, i know that if it was a one dimensional array, i could say that array[3] is the same as *(array+3)...but how do i do that with a matrix?
here's my code for scanning:
void scan_matrix(matrix mat1,int number_of_rows, int number_of_columns)
{
int row_index,column_index;
for(row_index=0;row_index<number_of_rows;row_index++)
{
printf("Enter the values of row %d\n",row_index);
for(column_index=0;column_index<number_of_columns;column_index++)
scanf("%d",WHAT GOES HERE?????);
}
}
If mat1 is a simple pointer, then this should do the job for you :
for(row_index=0;row_index<number_of_rows;row_index++)
{
printf("Enter the values of row %d\n",row_index);
for(column_index=0;column_index<number_of_columns;column_index++)
scanf("%d", (mat1 + row_index*number_of_columns + column_index));
}
The program uses the fact that matrices (2-d arrays) are in fact stored as 1-dimensional arrays in memory.
Lets take a 2d matrix :
1 2 3
4 5 6
This is stored in memory as :
1 2 3 4 5 6
So, the correct variable is accessed by using a way to map the logical positions of array elements with the actual positions. All we need is to find out the relation which turns out to be :
Pos = Row*Num_Of_Col + Col
if mat is two dimensional int array like : mat[3][3]
then scanf code would be : scanf("%d",(*(mat+row_index)+column_index));
a[3] : *(a+3)
a[3][3] : (*(a+3)+3)

mergesort algorithm

First let me say that this is hw so I am looking for more advice than an answer. I am to write a program to read an input sequence and then produce an array of links giving the values in ascending order.
The first line of the input file is the length of the sequence (n) and each of the remaining n lines is a non-negative integer. The
first line of the output indicates the subscript of the smallest input value. Each of the remaining output lines is a triple
consisting of a subscript along with the corresponding input sequence and link values.
(The link values are not initialized before the recursive sort begins. Each link will be initialized to -1 when its sequence value is placed in a single element list at bottom of recursion tree)
The output looks something like this:
0 3 5
1 5 2
2 6 3
3 7 -1
4 0 6
5 4 1
6 1 7
7 2 0
Where (I think) the last column is the subscripts, the center is the unsorted array, and the last column is the link values. I have the code already for the mergeSort and understand how it works I am only just confused and how the links get put into place.
I used vector of structures to hold the three values of each line.
The major steps are:
initialize the indexes and read the values from the input
sort the vector by value
determine the links
sort (back) the vector by index
Here is a sketch of the code:
struct Element {
int index;
int value;
int nextIndex; // link
}
Element V[N + 1];
int StartIndex;
V[i].index = i;
V[i].value = read_from_input;
sort(V); // by value
startIndex = V[0].index;
V[i].nextIndex = V[i + 1].index;
V[N].nextIndex = -1;
sort(V); // by index

Resources