I need to make duplicate of all words in string, and a space should be inserted between repeated words.
Definition of word: array of characters separated by: digits, period, comma, space, tab, or newline. So a word can contain every character besides these mentioned.
EXAMPLES:
char str[]="one.two three";
char str[]="!4A7 3---";
OUTPUT:
"one one.two two three three"
"! !4A A7 3--- ---"
Code:
#include <stdio.h>
char *make_duplicate(char *str) {
int i = 1;
char *s = str;
while (*s != '\0') {
if (*str == 48 || *str == 49 || *str == 50 || *str == 51 || *str == 52 ||
*str == 53 || *str == 54 || *str == 55 || *str == 56 || *str == 57 ||
*str == 44 || *str == 46 || *str == 9 || *str == 10 || *str == 32)
i ;
s ;
}
return str;
}
int main() {
char str[]="one.two three";
// char str[]="!4A7 3---";
printf("%s", make_duplicate(str));
return 0;
}
Numbers in my code are ASCII values of characters that cannot be part of word.
In my code I find how many words are in string. How could I after that make that number of duplicates in string?
- Note: is not allowed to use functions from the
string.h
,stdlib.h
libraries, as well as thesprintf
andsscanf
functions from the stdio.h library. It is not allowed to create auxiliary strings or strings.
CodePudding user response:
Create a look-up table for word-delimiters.
Use look-up table to decide whether to duplicate a word or not.
Constraints :
- signature
char* make_duplicate (char*);
is fixed. - no axillary strings are allowed, for making copies & generating output.
- signature
#include <stdio.h>
int dlt[256] = {0};
static inline int strLen (char* const str)
{
int slen = 0;
while (str[slen ]);
return slen;
}
char* make_duplicate (char* str) {
int slen = strLen (str);
//str buffer has sufficient spare memory
for (char* ap = str, *zp = str slen 1; ;) {
*zp = *ap ;
if ('\0' == *zp ) break;
}
char* aptr = NULL;
char* zptr = str slen 1;
char* dptr = str;
while (1) {
if (dlt[(unsigned char) *zptr]) { // delimiter found
if (aptr) { // there is a word
*dptr = ' '; // separate word with space
while (aptr < zptr) // duplicate the last word
*dptr = *aptr ;
aptr = NULL;
}
} else if (!aptr) //not a delim; now we're in a word
aptr = zptr;
*dptr = *zptr;
if ('\0' == *zptr ) break;
}
return str;
}
int main ()
{
// word delimiters (digits, period, comma, space, tab, or newline)
char word_delims[] = "0123456789., \t\n";
dlt[0] = 1; // to cover nulchar
for (int dc = 0; word_delims[dc] != '\0'; dc)
dlt[ (unsigned char) word_delims[dc]] = 1;
#define INPUT_STRINGS 5 // one place to decide how many inputs
char str[INPUT_STRINGS][128] = {"one.two three",
"!4A7 3---",
"0123456789., \t\n",
"TheOnlyString",
"A"
};
for (int si = 0; si < INPUT_STRINGS; si) {
printf ("\nOriginal :\t[%s]\n", str[si]);
printf ("Repeated Words:\t[%s]\n", make_duplicate (str[si]));
}
return 0;
}
CodePudding user response:
Since you cannot use any auxiliary string, I assume you are supposed to modify the string argument in place, assuming the array is long enough. Here is a simple solution that meets the constraints:
#include <stdio.h>
int isdelim(char c) {
switch (c) {
case '\0':
case '.': case ',': case ' ': case '\t': case '\n':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return 1;
default:
return 0;
}
}
// duplicates words, assuming str is long enough
char *make_duplicate(char *str) {
size_t delta = 0;
char *p = str;
char *dest;
char *wptr = NULL;
for (;;) {
if (isdelim(*p)) { // delimiter found
if (wptr) { // add duplicated word length
delta = 1 p - wptr;
wptr = NULL;
}
} else {
if (!wptr) { // not a delim; now we're in a word
wptr = p;
}
}
if (*p == '\0')
break;
}
if (delta > 0) {
while (p > str) { // shift string to make space for dups
p--;
p[delta] = *p;
}
dest = str;
p = str delta;
wptr = NULL;
while (dest < p) {
if (isdelim(*p)) { // delimiter found
if (wptr) { // duplicate a word
*dest = ' '; // separate word with space
while (wptr < p) // duplicate the last word
*dest = *wptr ;
wptr = NULL;
}
} else {
if (!wptr) { // not a delim; now we're in a word
wptr = p;
}
}
*dest = *p ;
}
}
return str;
}
int main() {
char str1[32] = "one.two three";
char str2[32] = "!4A7 3---";
printf("%s\n", make_duplicate(str1));
printf("%s\n", make_duplicate(str2));
return 0;
}
Output:
one one.two two three three
! !4A A7 3--- ---