Adjusting position in array to maintain increasing order - c

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 }

Related

Sorting algorithm with 10 elements

I have to make a program that asks the user to input an array of 10 elements with numbers from 0 to 9.
Then the array is sent to the function. This function will sort each number in the array as follows:
I don't know how to reposition the numbers.
Here is my implementation of
Joel Gregory's comment:
This function creates an unedited array, copies original's contents to it, then loops from first index to last. It will be used as the basis of checking for any matches for the indexes.
In each iteration, the function searches the unedited array if any of it's elements matches the index number. If yes, it replaces the initial value to the index value. Else, zero is assigned. And so on until the last index.
void swap(int *original, int max_elements) {
int index = 0, matcher = 0, unedited[max_elements];
// copies original to unedited
memcpy(unedited, original, max_elements * sizeof(int));
for (--index; ++index < max_elements; ) {
// searches the original array for matches with the current index
// loops until it finds a match or it reaches the maximum number of elements
for (matcher = 0; unedited[matcher] != index && ++matcher < max_elements;);
// if there is match, the initial value is changed with it's index value, else zero is the new value.
original[index] = (matcher != max_elements) ? index : 0;
}
}
Output:
Original: 1 1 7 8 2 8 1 6 3 2
Sorted: 0 1 2 3 0 0 6 7 8 0

Custom Function with array input printing wrong result in certain cases?

I needed to make a function that takes an array as input (and its dimensions X,Y or ROW,COL) and calculates the sum of all lines (storing each sum in a cell of the newarray.
For an input of NxN array seems to be working perfectly.
For an input of KxN array where K>N seems to be working perfectly.
int* linesum(int *ar,int X,int Y)
{
int i,j,lsum=0;
int *new=malloc(X*sizeof(int));
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
lsum+=*(ar+i*X+j);
}
*(new+i)=lsum;
lsum=0;
}
return new;
}
lsum+=*(ar+i*X+j);
should be
lsum += *(ar+i*Y+j);
or
lsum += *(ar+i+j*X);
The difference between these two is the chosen memory layout. i counts the current row, while j counts the current column. There are now two possible (simple) memory layouts for the matrix (assume X=3 and Y=4 as an example):
0 1 2 3
4 5 6 7
8 9 10 11
or
0 3 6 9
1 4 7 10
2 5 8 11
where numbers are the indexes of the linear array storing the matrix elements. In the first case you get the the next element of a given row by simply adding 1, but you need to jump 4 (the number of columns Y) to get to the next row.
In the second case you need to jump X=3 (the number of rows) to get to the next element in a given row, but if you want to get to the next row, you simply have to add 1.
These two layouts give you the two different pointer arithmetics shown above. You decided the layout when you initialized your array, which you haven't posted, so I cannot know which one is correct in your case.
Note that from a performance viewpoint (if your matrix is very large) the first case is better for your particular access pattern, because the array can be read element by element, while the second layout would require repeatedly jumping Y elements in memory.
You could also use double arrays / pointers to get around such pointer arithmetic. Also I guess it would be good to avoid new as a variable name, even if this is C. If somebody would try to compile your code with a C++ compiler it would throw errors, because new is a reserved keyword there.

What does ++ do after the array in this function?

void doSomething()
{
int hist[5] = { 0 };
int num_bins = 5;
int indices[10] = { 0, 0, 2, 3, 3, 3, 3, 4, 4, 4 };
int num_indices = 10;
int i;
for (i = 0; i < num_indices; i++)
{
hist[indices[i]]++;
}
for (i = 0; i < num_bins; i++)
{
printf("%d ", hist[i]);
}
printf("\n");
}
Assume I have correct libraries this is a conceptual question from class. I am wondering how the answer comes out to 2 0 1 4 3 for the array.
The line
hist[indices[i]]++
Says "go to the element of the hist array at index indices[i], then increment it." If you think of the array as a list of counters, this says to increment the counter at position indices[i].
This code builds a histogram of the frequencies of various numbers in an array. The idea behind the above code is to iterate over the array and increment the frequencies of each element.
Hope this helps!
The elements in indices range from 0 to 4, which are all valid index of the 5 elements array hist. (That's why the array is named indices, as it's for indexing)
So for instance, i is 2, then indices[i] is 2.
hist[indices[i]]++;
is equivalent to
hist[2]++;
For small questions like this you should try to write down the state of every element of each array on a piece of paper and execute your code step by step. You could also write the code to print useful information in runtime.
If after that you still can't figure it out then it's worth asking here. Otherwise you won't be learning much.
This program increments the 0's in
hist
as it indexes appear in
indices[10]
eg.
when you have the first for interation
hist[indices[0]]++ // hist[0]++ --> 0++;
It looks like "2 0 1 4 3" is a count of how many items exists in the array. 2 0's, 0 1's, 1 2, 4 3's and 3 4's. So the query is counting how many instances of each number are in the array and then printing out that result.
So the statement:
hist[indices[i]]++
find the value of indices[], then increments the int in the hist[] array by 1 giving you a count of how many of those elements are in the array.
1.As you have partially initialized your array, compiler sets other values to 0
2.hist[indices[i]]++; this statement increments the value of hist[i], for the current value of i
3.the value of i is denoted by your array indices[]
4.try having values grater than 5 in your array named indices[].

How to perform split and join functions on Array in 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

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