0
votes

so here it goes: I need to get two strings from the user, string1 and string2, then remove the "words" in string1 which are also present in string2 and print string1.

I can tokenize them but then I'm out of ideas / knowledge, need help :)

int main()
{
    char string1[100];                  //declaration of array for 1st input
    const char *tokens1[100];           //declaration of array of pointers
    char *token_ptr1;                   //pointer var to store tokens

    char string2[100];                  //declaration of array for 1st input
    const char *tokens2[100];           //declaration of array of pointers
    char *token_ptr2;                   //pointer var to store tokens

    int i=0;


    //input from user:
    printf("Enter string1: ");
    gets(string1);
    printf("\n");
    printf("Enter string2: ");
    gets(string2);

    printf("\n");

    //using strtok function to tokenize string1

    token_ptr1=strtok(string1," ");

    printf("Tokens1: \n");       //loop to store tokens in array of pointers and printing tokens

    while (string1!='\0')
    {
        if (token_ptr1=='\0') {  break;  }
        printf("%s\n",token_ptr1);

        tokens1[i]=token_ptr1;

        token_ptr1=strtok(NULL, " ");

        i++;
    }

    //string1 is tokenized and stored in tokens1


}

After this I have tried various ways to remove the common words to no avail

EDIT: Another problem within the same question:

EXAMPLE INPUT1: this is a string234

-- EXAMPLE INPUT2: 234

-- EXAMPLE OUTPUT: this is a string

using the tokenizing method the string "string234" is saved in the array of pointers, how to approach this program now? Checking individual characters using simple arrays?

4

4 Answers

0
votes

The naive way would be to tokenize both strings and them loop through each token from string1 and compare with string2. If tokens match, you remove the token1 by marking it.

Tokenize the second string and create an array to mark each token from string1. If match is found you mark token1 index and at the end you print only the tokens not marked. I could use a match function like this:

int match(int ind1, int ind2){
    while(string1[ind1]!='0'){
        if (string2[ind2]==string1[ind1]){
            ind2++;
            ind1++;
        }else{
            break;
        }
    }
    // Check if string2 also ended at same position
    if (string1[ind1]==string2[ind2]) return 1;
    return 0;
}

Haven't tested it, but I think it's right. Hope it helps!

0
votes

I am considering that you will not change i, because its contains the number of token.

strstr(str1,str2), returns a pointer to the first occurrence in str1 of the entire sequence of characters specified in str2, or a null pointer if the sequence is not present in str1.

char * ptr;
for ( j = 0 ; j < i ; j++){
    ptr = strstr (string2,tokens1[j]);
    if(ptr){
        token1[j] = '\0';
    }
}

for (j = 0 ; j < i ; j++){
    if(strlen(token1[j]) > 0){
        puts(token1[j]);
    }
}

Hope this helps.. :)

Note: I didn't compile it, just wrote the code here. And I am away from C coding for past 1.5 year. Used a lot in programming contests. So please point any mistakes and let me know :)

0
votes

First you've got a nice infinite loop if it compiles at all. You're comparing a constant character pointer string1 to a character, which is pointless and wrong.

while (string1 !≃ '0')

It should be

while (token_ptr1 != NULL)

And then you should skip the next line as well.

You shall be prepared for the last word in each string followed by a newline instead of a space, if you don't want to miss those:

strtok(string1, " \n");
strtok(NULL, " \n");

Having a separate temporary tokenx_ptr for both loops is redundant, you can use a single one in both loops.

Next, you need to track how many words you've found in each string. You can either store i after both loops to n1 or n2, or store the NULL value from the last failed strtok into the array as well. I'm going for the second approach.

Then it's a matter of an ugly O(n2) double loop to print the tokens from tokens1 array that are not present in the tokens2 array.

int i1 = 0;
while (tokens1[i1] != NULL) {
    int i2 = 0;
    int found = 0;
    while (tokens[i2] != NULL) {
        if (strncmp(tokens1[i1], tokens2[i2], 100) == 0) {
            found = 1;
            break;
        }
        i2++;
    }
    if (!found)
        printf("%s ", tokens1[i1);
    i1++;
}
0
votes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int cmp(const void *a, const void *b){
    return strcmp(*(const char**)a, *(const char**)b);
}

int main(){
    char string1[100];
    char *token_ptr1;
    char string2[100];
    const char *tokens2[100];
    char *token_ptr2;

    char result[100]={0};
    char *wordp, word[100];
    const char *delimiter = " \t\n";
    int i, len, ndw;//Number of delete words

    printf("Enter string1: ");
    fgets(string1, sizeof(string1), stdin);//include newline
    //printf("\n");
    printf("\nEnter string2: ");
    fgets(string2, sizeof(string2), stdin);

    for(ndw=0, token_ptr2=strtok(string2, delimiter);token_ptr2;token_ptr2=strtok(NULL, delimiter)){
        tokens2[ndw++] = token_ptr2;
    }
    qsort(tokens2, ndw, sizeof(*tokens2), cmp);

    token_ptr1 = string1;
    token_ptr2 = result;
    while(*token_ptr1 != '\0'){
        len = strspn(token_ptr1, delimiter);
        strncpy(token_ptr2, token_ptr1, len);//delimiter remain.
        token_ptr1 += len;
        token_ptr2 += len;
        len = strcspn(token_ptr1, delimiter);
        strncpy(word, token_ptr1, len);
        word[len] = '\0';
        wordp = word;
        if(NULL == bsearch(&wordp, tokens2, ndw, sizeof(*tokens2), cmp)){
            strncpy(token_ptr2, token_ptr1, len);
            token_ptr2 +=len;
        }
        token_ptr1 += len;
    }
    *token_ptr2 = '\0';
    printf("%s", result);

    return 0;
}