CSharpBeginner
CSharpBeginner

Reputation: 611

C: Same chars from two strings

I have two strings:

char *str1 = "this is a test";
char *str2 = "ts bd a";

I'm trying to write a function that returns a new string with the same chars from the two string without duplicates (also ' ' is duplicate). eg.:

char *retStr = GetSameChars(str1, str2); //returns "ts a";

How can I do that?

What I'm tried:

char *GetSameChars(char str1[], char str2[]) {
    int found = -1, i , j = 0, biggest, index = 0;
    char *retArr, *star = '*';
    int str1Len, str2Len, count = 0;
    str1Len = strlen(str1);
    str2Len = strlen(str2);
    biggest = str1Len > str2Len ? str1Len : str2Len;

    retArr = (char *)malloc(sizeof(char) * count);

    for (i = 0; i < str1Len; i++) {
        for (j = 0; j < str2Len; j++) {
            if (str1[i] == str2[j] && found == -1) {
                count++;
                found = j;
            } else
            if (str2[j] == str2[found])
                str2[j] = star; //Throw an exception
        }
        found = -1;
    }

    retArr = (char *)malloc(sizeof(char) * count);
    j = 0;

    for (i = 0; i < str2Len; i++)
        if (str2[i] != '*')
            retArr[j++] = str2[i];

    for (i = 0; i < str2Len; i++)
        printf("%c", retArr[i]);
}

When I tried the line str2[j] = star; I got an exception.

What is my mistake?

Upvotes: 0

Views: 91

Answers (2)

cdlane
cdlane

Reputation: 41870

My recommendations would be: keep it simple; get to know the C standard library; write less, test more.

Some specific problems with your code: you pass the wrong variable to malloc(); you estimate the answer to fit in the size of the larger of the two strings but it will actually fit into the smaller of the two; you modify an argument string str2[j] = star -- you should be treating the arguments as readonly; you malloc() retArr twice unnecessarily, leaking the first one when you allocate the second; your algorithm simply doesn't work.

Although a lookup table, as others have suggested, would be more efficient, let's use the standard library routine strchr() to solve this problem:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *getSameChars(const char *string1, const char *string2) {

    size_t string1_length = strlen(string1);
    size_t string2_length = strlen(string2);
    size_t shortest = string1_length < string2_length ? string1_length : string2_length;

    char *common_pointer, *common = malloc(shortest + 1);

    *(common_pointer = common) = '\0';

    for (size_t i = 0; i < string1_length; i++) {
        // character found in both input strings, but not yet in common string
        if (strchr(string2, string1[i]) != NULL && strchr(common, string1[i]) == NULL) {
            *common_pointer++ = string1[i];
            *common_pointer = '\0';
        }
    }

    return common;
}

int main() {
    char *stringA = "this is a test";
    char *stringB = "ts bd a";

    char *result = getSameChars(stringA, stringB);

    printf("%s\n", result);

    free(result);

    return(0);
}

Upvotes: 2

monkeyStix
monkeyStix

Reputation: 620

Your code complains because you are trying to assign a pointer to a char, to get the value inside a pointer you need to use the * operator like so:

*star;

a good way to check if a letter have already appeared(if you want to use it on all of the ascii table then 128) is to use a lookup table. first you will need to declare an array the length of all letters in the alphabet like so:

char lut[26];

If it is a global variable then it will be set to 0, then all you need to do is go to the index of the char you got and mark it as 1, a simple if will later be able to determine if a letter has already appeard. example:

lut[toupper(somechar) - 'A'] = 1;

In this example you set the char in the lookup table that is equivalent to the somechar variable as 1, marking it has already appeared.

hope this helps.

Upvotes: 0

Related Questions