Finding how to remove largest and second largest in array in c - c

The assignment is as followed and is coded in Keil which is an ide for c.
unsigned short data[100] = {
58473, 33594, 38638, 26741, 13018, 29262, 16377, 12354, 46079,
57240, 48949, 34054, 16212, 58485, 6198, 38678, 22525, 51012,
43489, 8861, 54291, 21524, 7166, 22698, 39899, 27113, 30443,
14888, 27935, 40035, 48710, 18067, 36008, 12644, 56319, 15852,
54685, 61789, 57030, 4763, 10655, 24656, 60363, 23712, 28474,
31274, 39647, 56166, 8219, 47413, 22201, 3129, 25630, 36027,
4499, 56525, 32743, 9380, 22102, 51009, 16309, 16589, 26322,
65279, 22780, 26002, 41101, 26082, 13389, 59504, 15784, 33416,
57970, 8519, 57819, 34406, 40864, 31575, 52154, 60214, 39910,
43107, 64825, 40284, 60148, 27287, 38245, 49930, 54062, 50668,
30553, 27904, 38960, 49407, 10508, 62147, 33019, 3047, 33750, 18024};
Write functions to preform the following operations on the array. You must pass the array to functions in order to receive full credit.
Find the index of the largest number, FindInexOfLargest().
Remove a specified entry, given an index, in the array, RemoveEntry(). Note that data appearing in the array after the removed entry is to be shifted to the left, so that data[i] becomes data[i+1].
Remove the largest entry in an array, RemoveLargestEntry(). The array is mutated to remove the largest entry. The value of the largest entry is returned by the function.
Remove the second largest entry in an array, RemoveSecondLargestEntry(). The function should return the numerical value of the second largest entry in an array, and remove that value.
The functions written for 3 and 4 should use the functions written in 1 and 2. For full credit, no loops should appear in the functions written in part 3 and 4.
This is my code that isn't working right and I can't find out where the mistake is. It's a logical error somewhere I just don't know where.
unsigned short int data[100] = {
58473, 33594, 38638, 26741, 13018, 29262, 16377, 12354, 46079,
57240, 48949, 34054, 16212, 58485, 6198, 38678, 22525, 51012,
43489, 8861, 54291, 21524, 7166, 22698, 39899, 27113, 30443,
14888, 27935, 40035, 48710, 18067, 36008, 12644, 56319, 15852,
54685, 61789, 57030, 4763, 10655, 24656, 60363, 23712, 28474,
31274, 39647, 56166, 8219, 47413, 22201, 3129, 25630, 36027,
4499, 56525, 32743, 9380, 22102, 51009, 16309, 16589, 26322,
65279, 22780, 26002, 41101, 26082, 13389, 59504, 15784, 33416,
57970, 8519, 57819, 34406, 40864, 31575, 52154, 60214, 39910,
43107, 64825, 40284, 60148, 27287, 38245, 49930, 54062, 50668,
30553, 27904, 38960, 49407, 10508, 62147, 33019, 3047, 33750, 18024};
// ***** 2. Global Declarations Section *****
// FUNCTION PROTOTYPES: Each subroutine defined
unsigned short int FindIndexOfLargest(unsigned short int class[], unsigned short int start, unsigned short int end);
unsigned short int RemoveEntry(unsigned short int class[], unsigned short int size, int position);
unsigned short int RemoveLargestEntry(unsigned short int class[], unsigned short int size);
unsigned short int RemoveSecondLargest(unsigned short int class[], unsigned short int start, unsigned short int end);
// ***** 3. Subroutines Section *****
int main (void) {
printf("Largest: %u\n", FindIndexOfLargest(data, 0, 100));
printf("Removing: %u\n", RemoveEntry(data, 100, 7));
printf("Removing Largest: %u\n", RemoveLargestEntry(data, 100));
printf("Removing Second Largest: %u\n", RemoveSecondLargest(data, 0, 100));
}
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = class[i]; // new maximum
}
}
return (class[i]);
}
unsigned short int RemoveEntry(unsigned short int class[], unsigned short int size, int position) {
unsigned short int c;
for (c = (position - 1) ; c < (size - 1) ; c++ ) {
class[c] = class[c+1];
}
return class[c];
}
unsigned short int RemoveLargestEntry(unsigned short int class[], unsigned short int size) {
return RemoveEntry(class, size, FindIndexOfLargest(class, 0, 100));
}
unsigned short int RemoveSecondLargest(unsigned short int class[], unsigned short int start, unsigned short int end) {
unsigned short int Largest = FindIndexOfLargest(class, start, end);
unsigned short int firstLarge = FindIndexOfLargest(class, start, (Largest-1));
unsigned short int secondLarge = FindIndexOfLargest(class, (Largest+1), end);
if (firstLarge > secondLarge) {
return RemoveEntry(class, end, firstLarge);
}
else {
return RemoveEntry(class, end, secondLarge);
}
}

There is one mistake in FindIndexOfLargest function Change it to:
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = class[i]; // new maximum
}
}
return (largest); //NOTE CHANGE HERE:Return largest number
}
As the function name suggest if you want to return the index of largest number then change it to:
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = i; // NOTE CHANGE HERE:new maximum index
}
}
return (largest); //NOTE CHANGE HERE:Return largest index
}

As pointed out by Vagish There is a mistake in the function FindIndexOfLargest you are doing this
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = class[i]; // new maximum
}
}
return (largest); // This is returning the largest no rather than returning the index
}
so do it like this
unsigned short int FindIndexOfLargest(unsigned short int class[],unsigned short int start, unsigned short int end){
unsigned short int largest,i,index;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(class[i] > largest){
largest = class[i]; // new maximum
index=i;
}
}
return (index); //This is returning the index of the largest
}
There is also the problem in the Remove Entry function do it like this
unsigned short int RemoveEntry(unsigned short int class[], unsigned short int size, int position) {
unsigned short int c;
for (c =position; c <size;++c ) {
class[c] = class[c+1];
}
size-=1;
return size; //Return size of new array after removing the data
}
Well then there remains the last function, please try to find the logical error there and if not able let us know :)
Hope these answer helps

unsigned short int FindIndexOfLargest(unsigned short int tempArr[],unsigned short int start, unsigned short int end){
unsigned short int largest,i;
largest = 0; // smallest possible value
for(i=0; i<end; i++){
if(tempArr[i] > tempArr[largest]){
largest = i; // new maximum
}
}
return (largest); //Change return value class[i] to largest;
}
void RemoveEntry(unsigned short int class[], unsigned short int size, int position) {
unsigned short int c;
for (c = (position - 1) ; c < (size - 1) ; c++ ) {
class[c] = class[c+1];
}
//return class[c]; <<< array pass by pointer,so no need to return; *change unsigned short int to void.
void RemoveLargestEntry(unsigned short int tempArr[], unsigned short int size) {
RemoveEntry(class, size, FindIndexOfLargest(tempArr, 0, 100)); // This is the same with RemoveEntry function;
}
unsigned short int RemoveSecondLargest(unsigned short int tempArr[],unsigned short int start, unsigned short int end) {
unsigned short int Largest,PositionLargest,SecondLargest,PositionSecondLargest;
Largest = tempArr[FindIndexOfLargest(tempArr[],0,end)];
RemoveLargestEntry(tempArr,end); /*Remove largest and sencond largest number in the Array */
SecondLargest = FindIndexOfLargest(tempArr,0,end);
RemoveLargestEntry(tempArr,end-1);
tempArr[99] = Largest; // Add number at the end of the array;
return(SecondLargest);
}
Function 4 is only for your provide array. If the situation where the number in the array is less than 100(e.g 30),function 4 will be useless.

Related

Program which displays the all signed short numbers

*EDIT: I Deleted by mistake the remarks I wrote on that using short & char is kind of obsolete / not efficient in modern programming. this one is just for practice basic stuff.**
This program creates and prints the series of signed short values starting from their equivalent in the unsigned short "space/world" starting at value 0 .
**example : on a machine where short is 16 bit :
unsigned short : 0 1 2 .... 65535
=> signed short : 0 1 2 ... 32766 -32767 -32766 -32765 ... -2 -1
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
//Initialize memory pointed by p with values 0 1 ... n
//Assumption : the value of n can be converted to
// short int (without over/under-flow)
unsigned int initArr (short int *p, unsigned int n);
int main (void)
{
const unsigned int lastNumInSeq = USHRT_MAX;
short *p_arr = (short *) malloc ( (lastNumInSeq + 1) * sizeof (short));
short int lastValSet = initArr (p_arr, lastNumInSeq); //returns the "max" val written
// for (unsigned i = 0; i < numOfElem; i++)
// printf ("[%d]=%d \n", i, (*(p_arr + i)));
printf ("lastValSet = %d *(p_arr + lastNumInSeq) = %d ",
lastValSet,*(p_arr + lastNumInSeq ));
return 0;
}
unsigned int initArr (short *p, unsigned int n)
{
unsigned int offset,index = 0;
while (index <= n){
offset = index;
*(p + offset) = ++index -1 ;
}
return offset;
There are some other cleanups needed.
The function signature should change from
short initArr (short *p, unsigned int n);
to
unsigned int initArr (short *p, unsigned int n);
The variable 'lastValSet' should change its type to unsigned int.
This comment is also confusing:
//Assumption : the value of n can be converted to
// short int (without over/under-flow)
It should be something like:
//Assumption : the value of n which is of type int can be converted to
// short int (without over/under-flow) up to 32767 which is the
// max value for a variable of short type.

C bit manipulation DES permute

I was having trouble with implementing the DES algorithm in Python, so I thought I'd switch to C. But I've ran into an issue, which I haven't been able to fix in hours, hopefully you can help me. Here's the source:
int PI[64] = {58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7};
unsigned long getBit(unsigned long mot, unsigned long position)
{
unsigned long temp = mot >> position;
return temp & 0x1;
}
void setBit(unsigned long* mot, int position, unsigned long value)
{
unsigned long code = *mot;
code ^= (-value ^ code) & (1 << position);
*mot = code;
}
void permute( unsigned long * mot, int * ordre, int taille )
{
unsigned long res;
int i = 0;
unsigned long bit;
for (i = 0; i < taille; i++)
{ setBit(&res, i, getBit(*mot, ordre[i] - 1)); }
*mot = res;
}
int main(int argc, char *argv[])
{
unsigned long bloc = 0x0123456789ABCDEF;
permute(&bloc, PI, 64);
printf(" end %lx\n", bloc);
return 1;
}
I made this permutation manually and with my Python program, and the result of this permutation should be 0xcc00ccfff0aaf0aa but I get 0xffffffffcc00ccff (which is, somehow, half correct and half broken). What is going on? How to fix this?
I added UL at the end of my hex word, and I used uint64_t instead of unsigned long int. When I changed -value, I got either fffffffffffffff or 0, but with UL and uint64_t I'm getting the correct result, which probably means, as you guys suggested, that my unsigned longs were not 64-bit longs. Thanks !

I have seg fault in my counting sort

Here is my code, for some reason I have to use unsigned long. The gdb tells me that I have
seg fault. Can one can help me? I could not find it by myself. The most interesting thing is that if I change the type to int from unsigned long, there is no seg fault.
Code is here:
#include <stdio.h>
int counting_Sort (unsigned long ary[], unsigned long array_size,unsigned long max){
unsigned long counting[max+1];
unsigned long j;
for(j=0;j<max+1;j++){
counting[j]=0;//initize to zero
}
unsigned long i;
for(i=0;i<array_size;i++){
counting[ary[i]]++;
}
unsigned long q;
for(q=1;q<max+1;q++){
counting[q]=counting[q-1]+counting[q];
}
for(q=0;q<max+1;q++){
counting[q]=counting[q]-1;
}
unsigned long outputAry[array_size];
unsigned long d;
for(d=(array_size-1); d>=0;d--){
outputAry[counting[ary[d]]]=ary[d];// SEG FAULT IS HERE
counting[ary[d]]--;//AND HERE
}
unsigned long m;
//for(m=0; m<array_size;m++){
// printf("%lu\n",outputAry[m]);
// }
return 0;
}
int main(){
unsigned long array[7]={2,6,4,0,1,7,9};
printf("before sorting the order is: \n");
unsigned long i;
for(i=0;i<7;i++){
printf("%lu\n",array[i]);
}
printf("after sorting, the new order is: \n");
counting_Sort(array,7,9);
getchar();
return 0;
}
You've found the place, just not the reason.
unsigned long d;
for(d=(array_size-1); d>=0;d--){
d is an unsigned integer, which means d>=0 is always true. The loop never ends, and that's the reason of segmentation fault.
One way is to change d to a singed type:
int d;
But if that's not what you want, change the for loop to:
for (d = 0; d <= array_size - 1; d++){

Cycle through certain range in array in C

I have this code
int x = 0
int MAX = 21;
int MIN = 18;
char *arr[40];
do{
char* current = cycle(x,arr)
x++;
}while(x<10000000)
My cycle() currently cycles through entire array
unsigned char *cycle(int counter, unsigned char *packets[40]){
int tmp = counter % 40;
return packets[tmp];
}
But I want it to cycle in array just in [MIN,MAX] range.
So the return values in while loop are: arr[18], arr[19], arr[20], arr[21], arr[18], arr[19]...
Any idea how to implement this? I don't want solutions using global variable.
Thanks for help!
Try something like this:
sometype cycle_range(int counter, sometype array[], unsigned min, unsigned max) {
sometype* first = array+min;
unsigned length = max-min+1;
return first[counter % length];
}
This works just like your solution, but it starts min elements further in array and loops over max-min+1 elements instead of 40.
(sometype is unsigned char* in your case, but you can substitute another type here if you want)
unsigned char *cycle(int counter,int min, int max, unsigned char *packets[40]){
int tmp = (counter % (max - min + 1)) + min;
return packets[tmp];
}

How to extract a number/byte from an array in C?

Here i have written a code which produces next 8 numbers from sequence.
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
I want to know how can i extract each byte/number of the array and return each number/byte ??Please help me out.
EDIT:Here's my code.Basically i want to read a file and compare the contents to check if the data read matches with generated sequential data.Here the buffer contains same data as temp_data is producing(ie 10 numbers like 0x07060504030201 next 0f0e0d0c0b0a0908 etc).I want to comapre buffer's data and the function's data.Can anyone suggest me how can i do.I am stuck.Any changes are appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<inttypes.h>
int main(void){
FILE *fp;
char *buffer,c;
size_t filesize,buffer_size;
int i;
unsigned long long int expected_data=1976943448883713;
fp=fopen("seqdata.c","r");
if(fp==NULL){
fputs("Error\n",stderr);
exit(1);
}
fseek(fp,0L,SEEK_END);
filesize=ftell(fp);
printf("Size of seqdata file is:%u \n",filesize);
fseek(fp,0L,SEEK_SET);
buffer=(char*)malloc(sizeof(char)*filesize);
if(buffer == NULL){
fputs("\nMemory error ",stderr);
}
buffer_size=fread(buffer,sizeof(char),filesize,fp);
for(i=0;i<buffer_size;i++){
printf("%c",*(buffer +i));
}
printf("No of elements read from file are:%u \n",buffer_size);
fseek(fp,0L,SEEK_SET);
int current_pos = 0;
while(current_pos < buffer_size){
if(*(buffer +current_pos) != expected_data)
{
fputs("Error\n",stderr);
exit(1);
}
else{
printf("data matching \n");
current_pos++;
expected_data=next_exp_data(expected_data);
}
}
fclose(fp);
free(buffer);
return 0;
}
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
It's machine dependent, but this usually works one of two ways:
union {
unsigned char b [8];
long long i;
} v;
v .i = seq_gen_value;
for (int j = 0; j < 8; ++j)
printf ("%d, ", v .b [j]);
On a little endian machine (x86, vax, etc.) the bytes come out with the least significant first. On a big endian machine, they come out with the most significant first.
By the way, it would be more useful to encode the "magic numbers" so that they can be more easily understood what they mean. For example, instead of 1976943448883713, write it as 0x7060504030201.
I think that your function do something like
return 1976943448883713 + 8 * 2260630401189896
And I think your question is not clear enough, like what array you want to return each its number? If you want to return array temp_data, it very easy. You can do that by
int next_exp_data(unsigned long long int expected_data, unsigned long long int temp_data[])
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
Call this function with the second params is a array int with size 10.
And another thing, I don't think that this function need the 1st param, because it's not be used within the function, so you can remove that from functions params list
int next_exp_data( unsigned long long int temp_data[])
{
int i=0;
unsigned long long int expected_data;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return expected_data; //dont use (expected_data), it will make things slower.
}
Comparing numbers in C is done using ==, !=, <= , >= , <, or >.
I didn't read your code as it's horrible formatted and doesn't seem relevant to your question as posed in the title.

Resources