The C Programming Language, 2nd Edition, by Kernighan and Ritchie
Exercise 2.04 on page 48
Write an alternate version of squeeze(s1,s2)
that deletes each character in the string s1
that matches any character in the string s2
.
Solution by Vidhan Gupta
/* Write an alternate version of squeeze (s1, s2) that deletes each character in s1 that matches any character in the string s2 */ #include <stdio.h> #include <string.h> void squeeze(char s1[], char s2[]); int main(int argc, char const *argv[]) { char s1[] = "Hello I'm a fello programmer "; squeeze(s1, "leo"); printf("%s\n", s1); return 0; } void squeeze(char s1[], char s2[]) { int i, j, k; for (i = 0; s2[i] != '\0'; i++) { for (j = 0, k = 0; s1[j] != '\0'; j++) if (s1[j] != s2[i]) s1[k++] = s1[j]; s1[k] = '\0'; } }
OUTPUT: H I'm a f prgrammr
Solution by Richard Heathfield
/* * Exercise 2-4 Page 48 * * Write an alternate version of squeeze(s1,s2) that deletes each * character in s1 that matches any character in the string s2. * */ /* squeeze2: delete all characters occurring in s2 from string s1. */ void squeeze2(char s1[], char s2[]) { int i, j, k; int instr2 = 0; for(i = j = 0; s1[i] != '\0'; i++) { instr2 = 0; for(k = 0; s2[k] != '\0' && !instr2; k++) { if(s2[k] == s1[i]) { instr2 = 1; } } if(!instr2) { s1[j++] = s1[i]; } } s1[j] = '\0'; } /* test driver */ #include <stdio.h> #include <string.h> int main(void) { char *leftstr[] = { "", "a", "antidisestablishmentarianism", "beautifications", "characteristically", "deterministically", "electroencephalography", "familiarisation", "gastrointestinal", "heterogeneousness", "incomprehensibility", "justifications", "knowledgeable", "lexicographically", "microarchitectures", "nondeterministically", "organizationally", "phenomenologically", "quantifications", "representationally", "straightforwardness", "telecommunications", "uncontrollability", "vulnerabilities", "wholeheartedly", "xylophonically", /* if there is such a word :-) */ "youthfulness", "zoologically" }; char *rightstr[] = { "", "a", "the", "quick", "brown", "dog", "jumps", "over", "lazy", "fox", "get", "rid", "of", "windows", "and", "install", "linux" }; char buffer[32]; size_t numlefts = sizeof leftstr / sizeof leftstr[0]; size_t numrights = sizeof rightstr / sizeof rightstr[0]; size_t left = 0; size_t right = 0; for(left = 0; left < numlefts; left++) { for(right = 0; right < numrights; right++) { strcpy(buffer, leftstr[left]); squeeze2(buffer, rightstr[right]); printf("[%s] - [%s] = [%s]\n", leftstr[left], rightstr[right], buffer); } } return 0; }
Solution by Xggggg
void squeeze(char s[], const char cs[]) { int i, j, k; for (i = 0, j = 0; s[i] != 0; i++) { for (k = 0; cs[k] != '\0'; k++) if (s[i] == cs[k]) break; if (cs[k] == '\0') s[j++] = s[i]; } s[j] = '\0'; }
Solution by Amarendra Godbole
void squeeze2(char s[], char t[]) { int i, j, k; for (k = 0; t[k] != '\0'; k++) { for (i = j = 0; s[i] != '\0'; i++) if (s[i] != t[k]) s[j++] = s[i]; s[j] = '\0'; } }
Alternative version that uses a LUT.
/* KnR exercise 2-4 solution, by Chris Chadwick - big10p1967@gmail.com Write an alternate version of squeeze(s1,s2) that deletes each character in the string s1 that matches any character in the string s2. */ #include <stdio.h> void squeeze(char s1[], char s2[]); int main(void) { char s1[] = "Write an alternate version of squeeze(s1,s2)" "that deletes each character in the string s1" "that matches any character in the string s2."; char s2[] = "aeiouAEIOU"; /* As a demo, we will delete all vowels from s1 */ printf("%s\n\nDelete all vowels...\n\n", s1); squeeze(s1, s2); printf("%s\n\n", s1); return 0; } /* Deletes all chars contained in s2 from s1 This function uses a look-up table (LUT) that indicates whether any given ASCII char is contained in s2, or not. That is: s2lut[c] == 0 - Char c is not contained in s2 s2lut[c] == 1 - Char c is contained in s2 This ensures execution efficiency when s1 and/or s2 are long strings, as using the LUT obviates the need to scan through s2 for every char in s1. */ void squeeze(char s1[], char s2[]) { if (!s1[0] || !s2[0]) return; /* Nothing to do if either string is empty */ char s2lut[256], c; int i; int ri; /* Index of s1 to read char from */ int wi; /* Index of s1 to write char to */ for (i = 0; i < 256; i++) s2lut[i] = 0; i = 0; while (c = s2[i++]) s2lut[c] = 1; ri = wi = 0; while (s1[ri]) { if (s2lut[s1[ri++]]) s1[wi] = s1[ri]; else s1[++wi] = s1[ri]; } s1[wi] = '\0'; }
Solution by codybartfast
enum bool { NO, YES }; void squeeze(char s1[], char s2[]) { int i, j; for (i = j = 0; s1[i] != '\0'; i++) if(! contains(s2, s1[i])) s1[j++] = s1[i]; s1[j] = '\0'; } int contains(char str[], char c) { int i = 0; while (str[i] != '\0') if (c == str[i++]) return YES; return NO; }
Solution by Miguel Degrossoli
/* Exercise 2-4. Write an alternative version of "squeeze(s1, s2)" that deletes * each character in "s1" that matches any character in the string "s2". */ #include <stdlib.h> #include <stdio.h> #define MAXLEN 40 /* maximum size of the strings */ #define YES 1 #define NO 0 void mygetline(char s[], int lim); void squeeze(char s1[], char s2[]); int main() { int c, i, lim; char s1[MAXLEN + 1], s2[MAXLEN + 1]; lim = MAXLEN; printf("Enter s1: "); mygetline(s1, lim); printf("Enter s2: "); mygetline(s2, lim); squeeze(s1, s2); printf("Resulting string is \"%s\"\n", s1); exit(0); } void mygetline(char s[], int lim) { int c, i; for (i = 0; i < lim && (c = getchar()) != '\n' && c != EOF; ++i) s[i] = c; s[i] = '\0'; } void squeeze(char s1[], char s2[]) { int i, j, n, found; for (i = j = 0; s1[i] != '\0'; ++i) { found = NO; for (n = 0; s2[n] != '\0'; ++n) if (s1[i] == s2[n]) found = YES; if (!found) s1[j++] = s1[i]; } s1[j] = '\0'; }
Produces result:
miguel@Miguel-Notebook:~/Desenvolvimento/C$ ./exercise_2-4 Enter s1: aNbifcgeh jckoldmen! Enter s2: abfghjklmn Resulting string is "Nice code!"
Solution by peppe dilillo
void squeeze2(char s1[], char s2[]){ int i, j, k; for ( i = j = 0; s1[i] != '\0'; ++i ){ k = 0; while ( s2[k] != s1[i] && s2[k] != '\0') k++; if ( s2[k] == '\0' ) s1[j++] = s1[i]; } s1[j] = '\0'; }
Solution by Foowar
/* * exericse 2-4: * * Write an alternate version of squeeze(s1, s2) that deletes each character * in s1 that matches any character in the string s2. */ #include <stdio.h> void squeeze(char *s1, const char *s2) { int i, j, k; for (i = j = 0; s1[i] != '\0'; ++i) { for (k = 0; s2[k] != '\0'; ++k) { if (s1[i] == s2[k]) { k = -1; break; } } if (k != -1) { s1[j++] = s1[i]; } } s1[j] = '\0'; }