Jump to: navigation, search

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';
}
Personal tools