Boshqa ikkita satrdan keng tarqalgan harflardan iborat yangi satr yarating

Men C dasturlash uchun yangi. Menda vazifa bor. Foydalanuvchi ikki qatorni kiritadi. Nima qilishim kerak, faqat ikkita satrning umumiy harflaridan iborat bo'lgan yangi mag'lubiyat hosil qilish. Misol uchun: agar berilgan bo'lsa:

str1 = "ABCDZ"
str2 = "ADXYZ"

yangi satr quyidagi kabi ko'rinadi: "ADZ" . Buni ishlashga qodir emasman. O'ylaymanki, yaxshi (oddiy) algoritm bo'lishi kerak, lekin men bu uchun juda ko'p vaqt talab qildim, shuning uchun uni to'ldirishni istayman ... yordamingizga muhtoj bo'l!

Hozirgacha qilgan ishim:

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);
        }
    }
}

Ushbu kodni qanday qilib tugatish kerakligini bilmayman. Har qanday taklif uchun minnatdor bo'lardim!

1
xat 2 marta takrorlanganda nima bo'lishi mumkin? namuna str1 = "AABCDZ" va str2 = "ADXYZ"
qo'shib qo'ydi muallif MOHAMED, manba
Katta va kichik harflar hisobga olinsinmi? str1 = "ABCDZ" va str2 = "adxyz" misollari qanday bo'lishi mumkin?
qo'shib qo'ydi muallif MOHAMED, manba
strchr() dan foydalanishingiz mumkin, u sizning algoritmingizni osonlashtiradi
qo'shib qo'ydi muallif MOHAMED, manba
qo'shib qo'ydi muallif unwind, manba
Men sizning namunangizga harflar tartibda ko'rilganini payqadim. Misollar: "ADZ" -> "AZ" = "AZ" aniq. Ammo "ZDA" -> "AZ" bo'lishi mumkin "AZ" "ZA" yoki ""
qo'shib qo'ydi muallif ChrisCM, manba
Ikki satr alifbo tartibida tartiblangan. Bu men mashg'ulotda ta'kidlangan.
qo'shib qo'ydi muallif Mr. L, manba
Oh va ha! har bir harf bir marta paydo bo'ladi!
qo'shib qo'ydi muallif Mr. L, manba
Bolalar, javoblar uchun minnatdorchiliklarim kerak edi, ammo buning uchun zarur bo'lgan barcha narsa algoritmdir: menda string mavjud: str1 = "ABCDXYZ". Bundan tashqari, bu ikkita satr bor: str2 = ABCDZ va str3 = ADXYZ. "ABCDXYZ" dan str2 va str3-da ko'rinmaydigan har bir harfni olib tashlashni istayman, shunday qilib str1 quyidagi tarzda ko'rinadi: strchr funksiyasini ishlatmasdan "ADZ". Men shunday bir narsa haqida o'yladim: qtr = arr; (ptr = arr; ptr
qo'shib qo'ydi muallif Mr. L, manba

6 javoblar

Chiqish qatori uzunligi ikkita kirish majmuasini qisqartirishi mumkin emas. Siz strchr() dan foydalanishingiz mumkin.

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;
}

Bu erda N va M kiritilgan satrlar uzunligi O ( N x M ) ishlashi mavjud. Sizning kirishingiz alfavit va noyob bo'lgani sababli, O ( N + M ) eng yomon vaziyat ishiga erishish mumkin. Birlashma aylanasiga o'xshash biror narsani qo'llaysiz.

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
qo'shib qo'ydi
Sizning sharhingizda nimani tavsiflaysiz, sizning savolingizda tasvirlab beradigan narsa emas va u commonChars() funktsiyangizga kirishlar bilan mos kelmaydi. Siz faqat 2 ta kirishni taqdim qilasiz, 3 emas. Sizning ikkinchi funktsiyangiz sizning so'rovingizni qondirmasligini aniqlay olasizmi?
qo'shib qo'ydi muallif jxh, manba
Sizning javobingiz uchun tashakkur, lekin men siz taqdim etgan birinchi va ikkinchi misollarni to'liq tushunmadim. Buni hal qilish uchun algoritmga kerak: menda string mavjud: str1 = "ABCDXYZ". Bundan tashqari, bu ikkita satr bor: str2 = ABCDZ va str3 = ADXYZ. "ABCDXYZ" dan str2 va str3-da ko'rinmaydigan har bir harfni olib tashlashni xohlayman, shuning uchun str1 quyidagicha bo'ladi: "ADZ" strchr funktsiyasidan foydalanmasdan.
qo'shib qo'ydi muallif Mr. L, manba
#include 
#include 
#include 

#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;
}
0
qo'shib qo'ydi

Men shunday qilaman:

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;
}

Men C ni qilmaganman, bu to'g'ri deb umid qilaman

0
qo'shib qo'ydi
bu mashqda realloc funktsiyasidan foydalanishim taqiqlanadi:/rahmat.
qo'shib qo'ydi muallif Mr. L, manba

Char-kitoblarni ishlatish uchun uzr so'rayman, faqat uni tezda bajarishga harakat qilardi. Algoritm orqasidagi g'oyalar aniq bo'lishi kerak, ayrim turlarni o'zgartirishingiz mumkin, loop tugatish shartlari, sizning maqsadlaringiz uchun C ++ elementlarini olib tashlashingiz mumkin. Muhim bo'lgan kodning orqasidagi fikr.

#include 
#include 
#include 
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.
}
0
qo'shib qo'ydi

Ushbu ishni toza bajarish uchun strpbrk() funktsiyasidan foydalanishingiz mumkin.

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

Belgilarda belgilarni toping Str2 ning bir qismi bo'lgan har qanday harfning str1-dagi birinchi marta yoki markerni hech qanday mos kelmasa null ko'rsatgichga qaytaradi.

Qidiruvda biron bir satrning yakunlovchi null-belgilarini o'z ichiga olmaydi, lekin u erda tugaydi.

#include 
#include 

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;
}
0
qo'shib qo'ydi

Shunday qilib, men o'z muammomni hal qildim. Oxir-oqibat, boshqa bir algoritmdan foydalanganman, shuning kabi, @ BLUEPIXY va user315052 nima taklif qilganiga juda o'xshaydi. Yordam berishga harakat qilganlarga rahmat! Juda chiroyli va foydali veb-resurs!

Here is my code. Someone who'll find it useful can use it. Note: (1) str1 & str2 should be sorted alphabetically; (2) each character should appear only once in each given strings;

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;

}
0
qo'shib qo'ydi