Reputation:
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?
string.h
, stdlib.h
libraries, as well as the sprintf
and sscanf
functions from the stdio.h library. It is not allowed to create auxiliary strings or strings.Upvotes: 0
Views: 190
Reputation: 144951
Since you cannot use any auxiliary string, I guess 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; // wptr is NULL already
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--- ---
Upvotes: 1
Reputation: 3071
Create a look-up table for word-delimiters.
Use look-up table to decide whether to duplicate a word or not.
Constraints :
char* make_duplicate (char*);
is fixed.#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;
}
Upvotes: 0