vmp
vmp

Reputation: 1

Comparison of string with character array in c

I am trying to write a code for encoding and decoding purpose.Once we have the dictionary,the dictionary formed is stored in an array of structure. The structure for this is below

typedef struct Tuple {
    char a;
    char* cod;
} result;

The original string is character array

char str[100];

Now we need a method to compare the characters in the original array with the formed dictionary. The dictionary formed is something like this

a ---0
b ---1
c ---01

Example: original string is aabcab, then encode should be 0010101

The code for comparing the string with the dictionary data is as follows, but when the code is executed it results as follows:[Warning] passing argument 2 of 'strcmp' makes pointer from integer without a cast [enabled by default].

Help would be appreciated.

   for(i=0; i<strlen(str);i++)//read the original string;
   {
        j=0; 
        while(j<number_of_elements_in_dictionary)// for above example=3
        {
            if (strcmp(str[i],values[j]->a)==0) //compare original string character with the //dictionary
            {
                printf("%s", values[j]->cod);//print corresponding code from //dictionary
                j++; //check with the next value of the dictionary
            }
        }          
    }
    printf("last=%s", str_en);//To print the dictionary data corresponding to //the original string data

#include<string.h>
#include<stdio.h>
#include<limits.h>
#include<stdlib.h>
typedef struct node
{
        char ch;
        int freq;
        struct node *left;
        struct node *right;
}node;

typedef struct Tuple {
    char a;
    char* cod;
}result;
/*Declaring heap globally so that we do not need to pass it as an argument every time*/
/* Heap implemented  here is Min Heap */
node * heap[1000000];
result * values[200];
int heapSize;
	char * str;
	char str_en[100];
// str_en[0] = '\0';
/*Initialize Heap*/
void Init()
{
        heapSize = 0;
        heap[0] = (node *)malloc(sizeof(node));
        heap[0]->freq = -INT_MAX;
}
/*Insert an element into the heap */
void Insert(node * element)
{
        heapSize++;
        heap[heapSize] = element; /*Insert in the last place*/
        /*Adjust its position*/
        int now = heapSize;
        while(heap[now/2] -> freq >= element -> freq) 
        {
                heap[now] = heap[now/2];
                now /= 2;
        }
        heap[now] = element;
}
node * DeleteMin()
{
        /* heap[1] is #ifndef

#elif

#endifthe minimum element. So we remove heap[1]. Size of the heap is decreased. 
           Now heap[1] has to be filled. We put the last element in its place and see if it fits.
           If it does not fit, take minimum element among both its children and replaces parent with it.
           Again See if the last element fits in that place.*/
        node * minElement,*lastElement;
        int child,now;
        minElement = heap[1];
        lastElement = heap[heapSize--];
        /* now refers to the index at which we are now */
        for(now = 1; now*2 <= heapSize ;now = child)
        {
                /* child is the index of the element which is minimum among both the children */ 
                /* Indexes of children are i*2 and i*2 + 1*/
                child = now*2;
                /*child!=heapSize beacuse heap[heapSize+1] does not exist, which means it has only one 
                  child */
                if(child != heapSize && heap[child+1]->freq < heap[child] -> freq ) 
                {
                        child++;
                }
                /* To check if the last element fits ot not it suffices to check if the last element
                   is less than the minimum element among both the children*/
                if(lastElement -> freq > heap[child] -> freq)
                {
                        heap[now] = heap[child];
                }
                else /* It fits there */
                {
                        break;
                }
        }
        heap[now] = lastElement;
        return minElement;
}
void encode(result *value, int s)
{
int pos,i,j;
pos=1;
	 values[pos]=value;//Im here
	 values[pos]->a =value->a;
	 values[pos]->cod=value->cod;
	                
                printf("RESULT= %c and %s", values[pos]->a, values[pos]->cod);
        
                pos++;
                
            /*the problem exists here while executing the following for-loop, the code doesn't execute due to this for loop*/
            
               for(i=0; i<strlen(str);i++){
               	j=0;
               	while(j<4)
				   {
				   	if(str[i]==values[j]->a)
				   	{
				   		printf("%s", values[j]->cod);
				   		j++;
				  	}
				   }		   }
				     
				  printf("last=%s", str_en);
				  
  
  }
void print(node *temp,char *code, int s)//, char *buf)
{
	 
	int i,pos=1,j;
        if(temp->left==NULL && temp->right==NULL)
        {
                printf("\n\nchar %c code %s\n",temp->ch,code);
                result * value = (result *) malloc(sizeof(result));
                value->a=temp->ch;
                value->cod= code;
              encode(value,s);
               
		return;
            
               
        }
        int length = strlen(code);
        char leftcode[512],rightcode[512];
        strcpy(leftcode,code);
        strcpy(rightcode,code);
        leftcode[length] = '0';
        leftcode[length+1] = '\0';
        rightcode[length] = '1';
        rightcode[length+1] = '\0';
        print(temp->right,rightcode,s);
        print(temp->left,leftcode,s);
     
    }    

/* Given the list of characters along with their frequencies, our goal is to predict the encoding of the
   characters such that total length of message when encoded becomes minimum */ 
int main()
{
	char buf[250];

	char character[26]; 
	 int i = 0,j=0,count[26]={0}; 
    char c = 97;
        Init();
      int distinct_char=0 ;
     
        char ch;
        int freq;       
        int iter;
    
        printf("enter the string");
        scanf("%s", str);
        printf("string=%s",str);
        for (i=0; i<strlen(str);i++)
        {
        	 
        for(j=0;j<26;j++)
            {
            if (tolower(str[i]) == (c+j))
                {
                    count[j]++;
                }
        }
    }
    for(j=0;j<26;j++)
        {
			if(count[j]>0)
			{

            printf("\n%c -> %d",97+j,count[j]);
            distinct_char++;
            character[j] = 97+j;    
			}

    	}
    	printf("\n number of distinct_characters=%d\n", distinct_char);  
	
	 
	     if(distinct_char==1)
        {
              printf("char %c code 0\n",c);
              return 0;
        }
        
         for(j=0;j<distinct_char;j++)
        {
        	printf("\ncharacter= %c and the frequency=%d", character[j],count[j]);
        	 node * temp = (node *) malloc(sizeof(node));
                temp -> ch = character[j];
                temp -> freq = count[j];
                temp -> left = temp -> right = NULL;
                Insert(temp);
            
        } 
        for(i=0;i<distinct_char-1 ;i++)
        {
                node * left = DeleteMin();
                node * right = DeleteMin();
                node * temp = (node *) malloc(sizeof(node));
                temp -> ch = 0;
                temp -> left = left;
                temp -> right = right;
                temp -> freq = left->freq + right -> freq;
                Insert(temp);
        }
        node *tree = DeleteMin();
       
        
        char code[512];
        code[0] = '\0';
 
   print(tree,code, distinct_char);
  

}

Upvotes: 0

Views: 232

Answers (2)

Freddie Chopin
Freddie Chopin

Reputation: 8860

Maybe not completely "on-topic", but your code would improve dramatically if you'd use a look-up table method. The input characters - coming from str should be used as indexes to the array with dictionary - you'd then only need one loop that traverses through the input string. To deal with the fact that char can have 256 values, out of which you need only a few you can:

  • use only part of char values as indexes - before actual indexing subtract some value (first printable char you wish to encode) and compare the result with max index in the LUT,
  • waste some memory and include all 256 indexes in the LUT,
  • use another LUT to transform characters from input to indexes in LUT - this way you can map all characters you don't support to one common output element,
  • ...

This way you wouldn't have any comparisons in your code - just indexing (;

Upvotes: 0

Jan
Jan

Reputation: 293

As the warning suggests, you're missing a pointer here. strcmp's signature reads

int strcmp(const char *s1, const char *s2);

but both parameters are actually of type char (the array indexing makes a char from a char*, just as regular dereferencing does and the second parameter is a char anyway).

However, what you really want is comparing a single character from a string with another character. You can just use the regular relational operators:

if(str[i] == values[j]->a) 
{
    // ...
}

Note that this is just answering your precise question but your code may be wrong or ineffective anyway.

Upvotes: 1

Related Questions