创建一个新字符串,其中包含来自其他两个字符串的常用字母

时间:2013-05-29 14:41:21

标签: c string letters

我是C编程的新手。我有一项任务要做。 用户输入两个字符串。我需要做的是创建一个新字符串,该字符串只包含这两个给定字符串的常用字母。 例如: 如果给出:

str1 = "ABCDZ"
str2 = "ADXYZ"

新字符串将如下所示:"ADZ"。 我无法使它发挥作用。我认为必须有一个更好(更简单)的算法,但是我已经为这个算法留了太多时间,所以我想完成它...需要你的帮助!

到目前为止,我所做的是:

char* commonChars (char* str1, char* str2)
{
    char *ptr, *qtr, *arr, *tmp, *ch1, *ch2;
    int counter = 1;
    ch1 = str1;
    ch2 = str2;
    arr = (char*) malloc ((strlen(str1)+strlen(str2)+1)*(sizeof(char))); //creating dynamic array
    strcpy(arr, str1);
    strcat(arr,str2);
    for (ptr = arr; ptr < arr + strlen(arr); ptr++)
    {
        for (qtr = arr; qtr < arr + strlen(arr); qtr++) // count for each char how many times is appears
        {
            if (*qtr == *ptr && qtr != ptr)
            {
                counter++;
                tmp = qtr;
            }
        }
        if (counter > 1)
        {
            for (qtr = tmp; *qtr; qtr++) //removing duplicate characters
                *(qtr) = *(qtr+1);
        }
        counter = 1;
    }
    sortArray(arr, strlen(arr)); // sorting the string in alphabetical order
    qtr = arr;
    for (ptr = arr; ptr < arr + strlen(arr); ptr++, ch1++, ch2++) //checking if a letter appears in both strings and if at least one of them doesn't contain this letter -  remove it
    {
        for (qtr = ptr; *qtr; qtr++)
        {
            if (*qtr != *ch1 || *qtr != *ch2)
                *qtr = *(qtr+1);
        }
    }
}

不知道如何完成此代码..我会感谢任何建议!

6 个答案:

答案 0 :(得分:1)

输出数组不能长于两个输入数组中较短的一个。 您可以使用strchr()

char * common (const char *in1, const char *in2) {
    char *out;
    char *p;

    if (strlen(in2) < strlen(in1)) {
        const char *t = in2;
        in2 = in1;
        in1 = t;
    }

    out = malloc(strlen(in2)+1);
    p = out;
    while (*in1) {
        if (strchr(in2, *in1)) *p++ = *in1;
        ++in1;
    }
    *p = '\0';
    return out;
}

这具有O(N x M)性能,其中NM是输入字符串的长度。由于您的输入是字母和唯一的,因此您可以实现O(N + M)最差情况下的性能。你应用类似于合并循环的东西。

char * common_linear (const char *in1, const char *in2) {
    char *out;
    char *p;

    if (strlen(in2) < strlen(in1)) {
        const char *t = in2;
        in2 = in1;
        in1 = t;
    }

    out = malloc(strlen(in2)+1);
    p = out;
    while (*in1 && *in2) {
        if (*in1 < *in2) {
            ++in1;
            continue;
        }
        if (*in2 < *in1) {
            ++in2;
            continue;
        }
        *p++ = *in1;
        ++in1;
        ++in2;
    }
    *p = '\0';
    return out;
}

答案 1 :(得分:0)

我会做这样的事情:

char*   commonChars(char* str1, char* str2) {
   char*  ret = malloc(strlen(str1) * sizeof(char));
   int    i = j = k = 0;

   for (; str1[i] != '\n'; i++, j++) {
       if (str1[i] == str2[j]) {
          ret[k] = str1[i];
          k++;
       }
    }
  ret[k] = '\0';
  ret = realloc(ret, k);
  return ret;
}

我已经有一段时间不做C了,希望这是正确的

答案 2 :(得分:0)

很抱歉奇怪的使用char数组,只是想快速完成它。算法背后的想法应该是显而易见的,你可以修改一些类型,循环结束条件,删除C ++元素等等。这是代码背后的理念,这很重要。

#include <queue>
#include <string>
#include <iostream>
using namespace std;


bool isCharPresent(char* str, char c) {
    do {
        if(c == *str) return true;
    } while(*(str++));

    return false;
}

int main ()
{
    char str1[] = {'h', 'i', 't', 'h', 'e', 'r', 'e', '\0'};
    char str2[] = {'a', 'h', 'i', '\0'};
    string result = "";

    char* charIt = &str1[0];

    do {
        if(isCharPresent(str2, *charIt))
            result += *charIt;
    } while(*(charIt++));


    cout << result << endl; //hih is the result.  Minor modifications if dupes are bad.
}

答案 3 :(得分:0)

你可以使用strpbrk()函数来干净地完成这项工作。

const char * strpbrk ( const char * str1, const char * str2 );
char * strpbrk (       char * str1, const char * str2 );

在字符串中找到字符 返回指向str2中任何字符的str1中第一个匹配项的指针,如果没有匹配则返回空指针。

搜索不包括任何一个字符串的终止空字符,但在那里结束。

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

int main ()
{
  char str[] = "ABCDZ";
  char key[] = "ADXYZ";

  char *newString = malloc(sizeof(str)+sizeof(key));
  memset(newString, 0x00, sizeof(newString));

  char * pch;
  pch = strpbrk (str, key);

  int i=0;
  while (pch != NULL)
  {
     *(newString+i) = *pch;
     pch = strpbrk (pch+1,key);
     i++;
  }

  printf ("%s", newString);
  return 0;
}

答案 4 :(得分:0)

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

#define min(x,y) ((x)<(y)? (x) : (y))

char* commonChars (const char *str1, const char *str2){
    //str1, str2 : sorted(asc) and unique
    char *ret, *p;
    int len1, len2;
    len1=strlen(str1);
    len2=strlen(str2);
    ret = p = malloc((min(len1, len2)+1)*sizeof(char));

    while(*str1 && *str2){
        if(*str1 < *str2){
            ++str1;
            continue;
        }
        if(*str1 > *str2){
            ++str2;
            continue;
        }
        *p++ = *str1++;
        ++str2;
    }
    *p ='\0';

    return ret;
}

char *deleteChars(const char *str, const char *dellist){
    //str, dellist : sorted(asc) and unique
    char *ret, *p;
    ret = p = malloc((strlen(str)+1)*sizeof(char));

    while(*str && *dellist){
        if(*str < *dellist){
            *p++=*str++;
            continue;
        }
        if(*str > *dellist){
            ++dellist;
            continue;
        }
        ++str;
        ++dellist;
    }
    if(!*dellist)
        while(*str)
            *p++=*str++;
    *p ='\0';

    return ret;
}

int main(void){
    const char *str1 = "ABCDXYZ";
    const char *str2 = "ABCDZ";
    const char *str3 = "ADXYZ";
    char *common2and3;
    char *withoutcommon;

    common2and3 = commonChars(str2, str3);
    //printf("%s\n", common2and3);//ADZ
    withoutcommon = deleteChars(str1, common2and3);
    printf("%s\n", withoutcommon);//BCXY

    free(common2and3);
    free(withoutcommon);
    return 0;
}

答案 5 :(得分:0)

所以我找到了解决问题的方法。最后,我使用了另一种算法,结果与@ BLUEPIXY 和@ user315052 建议的算法非常相似。谢谢所有试图帮助的人!非常好用的网络资源!

这是我的代码。找到它有用的人可以使用它。 注意: (1)str1&amp; str2应按字母顺序排序; (2)每个字符在每个给定的字符串中只出现一次;

char* commonChars (char* str1, char* str2)
{
    char *ptr, *arr,*ch1, *ch2;
    int counter = 0;
    for (ch1 = str1; *ch1; ch1++)
    {
        for(ch2 = str2; *ch2; ch2++)
        {
            if (*ch1 == *ch2)
                counter++;
        }
    }
    arr =  (char*)malloc ((counter+1) * sizeof(char));
    ch1 = str1;
    ch2 = str2;
    ptr = arr;
    for (ch1 = str1; *ch1; ch1++,ch2++)
    {
    while (*ch1 < *ch2)
    {
        ch1++;
    }
    while (*ch1 > *ch2)
    {
        ch2++;
    }
    if (*ch1 == *ch2)
    {
        *ptr = *ch1;
        ptr++;
    }
    }
    if (ptr = arr + counter)
        *ptr = '\0';
    return arr;

}