473,548 Members | 2,683 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

remove spaces from a string and Complexity

I am writing a program in which I am removing all the spaces from the
string. I thought that I could do it two ways. One was parsing the
string character by character and copying onto another output string.
But this was trivial.
The other option is to use pointers and shift all the characters after
the space by one space to the left. I did this program using pointers
and then using array too and I get segmentation fault. What is going
wrong in here ?

#include<stdio. h>

int main(void)
{
char p[] = "please remove space from me";
int index = 0;

while(p[index] != '\0')
{
if (p[index] == ' '){
p[index] = p[index+1];
p[index+1] =' ';
}
index++;
}
puts(p);
return 0;
}

Feb 19 '07 #1
15 15600
On Feb 19, 5:08 pm, "DanielJohn son" <diffuse...@gma il.comwrote:
I am writing a program in which I am removing all the spaces from the
string. I thought that I could do it two ways. One was parsing the
string character by character and copying onto another output string.
But this was trivial.
The other option is to use pointers and shift all the characters after
the space by one space to the left. I did this program using pointers
and then using array too and I get segmentation fault. What is going
wrong in here ?

#include<stdio. h>

int main(void)
{
char p[] = "please remove space from me";
int index = 0;

while(p[index] != '\0')
{
if (p[index] == ' '){
p[index] = p[index+1];
p[index+1] =' ';
}
index++;
}
puts(p);
return 0;

}
I want to keep the complexity of the program to the minimum. I have
heard the STL provides list data structure which does it for you but I
was not sure what is the running time of list. So I thought of writing
my own.

How to reduce complexity of such algorithm when you have to manipulate
the same string and keep it to a constant time. Here in the above
program if it works correctly it will be 2*O(n). Any comments ?

Feb 19 '07 #2
DanielJohnson a écrit :
I am writing a program in which I am removing all the spaces from the
string. I thought that I could do it two ways. One was parsing the
string character by character and copying onto another output string.
But this was trivial.
The other option is to use pointers and shift all the characters after
the space by one space to the left. I did this program using pointers
and then using array too and I get segmentation fault. What is going
wrong in here ?

#include<stdio. h>

int main(void)
{
char p[] = "please remove space from me";
int index = 0;

while(p[index] != '\0')
{
if (p[index] == ' '){
p[index] = p[index+1];
p[index+1] =' ';
}
index++;
}
puts(p);
return 0;
}
If your string ends with a space, you will put a space in the
next character, erasing the zero that terminates the string...

Since the condition that you test for ending the iteration is

while(p[index] != '\0')

you will continue to read beyond the end of the string,
probably indefinitely... until a segmentation fault happens.

If you use two pointers, this can be done in a more simple way

void eraseAllBlanks( char *src)
{
char *dst = src;

while (*src != 0) {
if (*src != ' ') {
*dst++ = *src; // copy
}
src++;
}
*dst = 0;
}

If you want to use array notation:
void eraseAllBlanks( char *src)
{
int srcIndex=0;
int dstIndex=0;

while (src[srcIndex] != 0) {
if (src[srcIndex] != ' ') {
src[dstIndex++] = src[srcIndex]; // copy
}
srcIndex++;
}
src[dstIndex] = 0;
}
Feb 19 '07 #3
DanielJohnson said:
On Feb 19, 5:08 pm, "DanielJohn son" <diffuse...@gma il.comwrote:
>I am writing a program in which I am removing all the spaces from the
string. I thought that I could do it two ways. One was parsing the
string character by character and copying onto another output string.
But this was trivial.
The other option is to use pointers and shift all the characters
after the space by one space to the left. I did this program using
pointers and then using array too and I get segmentation fault. What
is going wrong in here ?

#include<stdio .h>

int main(void)
{
char p[] = "please remove space from me";
int index = 0;

while(p[index] != '\0')
{
if (p[index] == ' '){
p[index] = p[index+1];
p[index+1] =' ';
}
index++;
}
puts(p);
return 0;

}
Let's just look at " me", shall we? Or { ' ', 'm', 'e', '\0' } might be
clearer right now.

index = 0, p[index] = ' ', so we copy p[1] to p[0]:

{ 'm', 'm', 'e', '\0' }

p[index + 1] = ' ';

{ 'm', ' ', 'e', '\0' }

index++, so index is now 1.

p[index] = ' ', so we copy p[2] to p[1]:

{ 'm', 'e', 'e', '\0' }

p[index + 1] = ' ';

{ 'm', 'e', ' ', '\0' }

index++, so index is now 2.

p[index] = ' ', so we copy p[3] to p[2]:

{ 'm', 'e', '\0', '\0' }

p[index + 1] = ' ';

{ 'm', 'e', '\0', ' ' }

index++, so index is now 3, and p[index] = p[index + 1] constitutes an
illegal memory access. The problem is that you just assumed that the
while-control would protect you - but it didn't, because you moved the
terminator and the index past each other within the loop.

Even if that weren't a problem, I'm fairly sure the algorithm would
break with multiple spaces, although I haven't examined that too
closely.

What you want to do is fairly easy, actually, and - not surprisingly -
the answer is in K&R2, on page 47:

/* squeeze: delete all c from s */
void squeeze(char s[], int c)
{
int i, j;
for(i = j = 0; s[i] != '\0'; i++)
if(s[i] != c)
s[j++] = s[i];
s[j] = '\0';
}

Here's my own version:

void delchar(char *s, char c)
{
char *t = s;
for(;*s;(*s != c) ? *t++ = *s++ : *s++)
{
continue;
}
*t = '\0';
}
I want to keep the complexity of the program to the minimum.
You'll struggle to beat O(n), which is what I've shown you here.
I have
heard the STL provides list data structure which does it for you but
....but C doesn't have an STL. :-)
How to reduce complexity of such algorithm when you have to manipulate
the same string and keep it to a constant time. Here in the above
program if it works correctly it will be 2*O(n). Any comments ?
2 * O(n) is just O(n) - the trick is to find a computer that runs at
twice the speed. Constant factors can be ignored in O-notation.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Feb 19 '07 #4
On Feb 19, 5:30 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
DanielJohnson said:
On Feb 19, 5:08 pm, "DanielJohn son" <diffuse...@gma il.comwrote:
I am writing a program in which I am removing all the spaces from the
string. I thought that I could do it two ways. One was parsing the
string character by character and copying onto another output string.
But this was trivial.
The other option is to use pointers and shift all the characters
after the space by one space to the left. I did this program using
pointers and then using array too and I get segmentation fault. What
is going wrong in here ?
#include<stdio. h>
int main(void)
{
char p[] = "please remove space from me";
int index = 0;
while(p[index] != '\0')
{
if (p[index] == ' '){
p[index] = p[index+1];
p[index+1] =' ';
}
index++;
}
puts(p);
return 0;
}

Let's just look at " me", shall we? Or { ' ', 'm', 'e', '\0' } might be
clearer right now.

index = 0, p[index] = ' ', so we copy p[1] to p[0]:

{ 'm', 'm', 'e', '\0' }

p[index + 1] = ' ';

{ 'm', ' ', 'e', '\0' }

index++, so index is now 1.

p[index] = ' ', so we copy p[2] to p[1]:

{ 'm', 'e', 'e', '\0' }

p[index + 1] = ' ';

{ 'm', 'e', ' ', '\0' }

index++, so index is now 2.

p[index] = ' ', so we copy p[3] to p[2]:

{ 'm', 'e', '\0', '\0' }

p[index + 1] = ' ';

{ 'm', 'e', '\0', ' ' }

index++, so index is now 3, and p[index] = p[index + 1] constitutes an
illegal memory access. The problem is that you just assumed that the
while-control would protect you - but it didn't, because you moved the
terminator and the index past each other within the loop.

Even if that weren't a problem, I'm fairly sure the algorithm would
break with multiple spaces, although I haven't examined that too
closely.

What you want to do is fairly easy, actually, and - not surprisingly -
the answer is in K&R2, on page 47:

/* squeeze: delete all c from s */
void squeeze(char s[], int c)
{
int i, j;
for(i = j = 0; s[i] != '\0'; i++)
if(s[i] != c)
s[j++] = s[i];
s[j] = '\0';

}

Here's my own version:

void delchar(char *s, char c)
{
char *t = s;
for(;*s;(*s != c) ? *t++ = *s++ : *s++)
{
continue;
}
*t = '\0';

}
I want to keep the complexity of the program to the minimum.

You'll struggle to beat O(n), which is what I've shown you here.
I have
heard the STL provides list data structure which does it for you but

...but C doesn't have an STL. :-)
How to reduce complexity of such algorithm when you have to manipulate
the same string and keep it to a constant time. Here in the above
program if it works correctly it will be 2*O(n). Any comments ?

2 * O(n) is just O(n) - the trick is to find a computer that runs at
twice the speed. Constant factors can be ignored in O-notation.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.
I have a questions on the above solution. Since you assigned chat *t=s
and then go on using *t++ = *s++, does it seem intuitive . I mean t
and s both point to the same array and you go on copying until you
parse a space upon which you skip. I want to catch up with all the
pointer jargons as it interests me and I keep making mistakes. But I
guess thats the right way to learn.

Thank you again for your wonderfully elegant solutions.

Feb 19 '07 #5
DanielJohnson said:
On Feb 19, 5:30 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
<snip>
>Here's my own version:

void delchar(char *s, char c)
{
char *t = s;
for(;*s;(*s != c) ? *t++ = *s++ : *s++)
{
continue;
}
*t = '\0';

}

I have a questions on the above solution. Since you assigned chat *t=s
and then go on using *t++ = *s++, does it seem intuitive . I mean t
and s both point to the same array and you go on copying until you
parse a space upon which you skip.
t, the target, starts off at the same place as s, the source. Every time
s hits a space, no copying is done but s is bumped along, leaving t
trailing behind. Every time s hits a non-space, it is copied to
wherever t is pointing. Eventually, all the non-spaces have been
copied, and t is pointing just at the point where you want to nail the
terminator in place - so that's what happens after the loop.

I want to catch up with all the
pointer jargons as it interests me and I keep making mistakes. But I
guess thats the right way to learn.
If you can't make a mistake, you can't do anything.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Feb 19 '07 #6
Richard Heathfield wrote:
DanielJohnson said:
>On Feb 19, 5:08 pm, "DanielJohn son" <diffuse...@gma il.comwrote:
>>I am writing a program in which I am removing all the spaces from the
string. I thought that I could do it two ways. One was parsing the
string character by character and copying onto another output string.
But this was trivial.
The other option is to use pointers and shift all the characters
after the space by one space to the left. I did this program using
pointers and then using array too and I get segmentation fault. What
is going wrong in here ?
[snip op's code]
[snip Richard's explaination]
>
What you want to do is fairly easy, actually, and - not surprisingly -
the answer is in K&R2, on page 47:

/* squeeze: delete all c from s */
void squeeze(char s[], int c)
{
int i, j;
for(i = j = 0; s[i] != '\0'; i++)
if(s[i] != c)
s[j++] = s[i];
s[j] = '\0';
}

Here's my own version:

void delchar(char *s, char c)
{
char *t = s;
for(;*s;(*s != c) ? *t++ = *s++ : *s++)
{
continue;
}
*t = '\0';
}
I've seen functions written as above, however I'm still a little
confused about one point - C passes by value therefore with your above
function wouldn't the following behave incorrectly (incorrectly as in
not modify the contents referenced by the first parameter but instead
modify a copy of it):

int main(void)
{
char *p = NULL;

p = malloc(20);

strcpy(p, " me");

delchar(p, ' ');

return(0);
}

That being said, shouldn't the above function be written as such (i
added 'ptr' to make it a little easier to read, at least in my perspective):

void delchar(char **s, char c)
{
char *t = *s;
char *ptr = *s;
for(;*ptr;(*ptr != c) ? *t++ = *ptr++ : *ptr++)
{
continue;
}
*t = '\0';
}

[snip]

The above has confused me since day 1 of learning the language. I've
long since learned to accept that in order to modify the original
contents from another function a pointer to that data is needed.
Feb 19 '07 #7
Joe Estock said:
Richard Heathfield wrote:
>DanielJohnso n said:
>>On Feb 19, 5:08 pm, "DanielJohn son" <diffuse...@gma il.comwrote:
I am writing a program in which I am removing all the spaces from
the string. I thought that I could do it two ways. One was parsing
the string character by character and copying onto another output
string. But this was trivial.
The other option is to use pointers and shift all the characters
after the space by one space to the left. I did this program using
pointers and then using array too and I get segmentation fault.
What is going wrong in here ?

[snip op's code]
[snip Richard's explaination]
>>
What you want to do is fairly easy, actually, and - not surprisingly
- the answer is in K&R2, on page 47:

/* squeeze: delete all c from s */
void squeeze(char s[], int c)
{
int i, j;
for(i = j = 0; s[i] != '\0'; i++)
if(s[i] != c)
s[j++] = s[i];
s[j] = '\0';
}

Here's my own version:

void delchar(char *s, char c)
{
char *t = s;
for(;*s;(*s != c) ? *t++ = *s++ : *s++)
{
continue;
}
*t = '\0';
}

I've seen functions written as above, however I'm still a little
confused about one point - C passes by value therefore with your above
function wouldn't the following behave incorrectly (incorrectly as in
not modify the contents referenced by the first parameter but instead
modify a copy of it):
int main(void)
{
char *p = NULL;

p = malloc(20);

strcpy(p, " me");

delchar(p, ' ');

return(0);
}
Well, if you add <stdlib.hand <string.hand a check for p != NULL,
it'll work fine. The *pointer* is passed by value, yes, but a copy of a
pointer is just as good for finding the object pointed to as the
original pointer. The purpose of delchar() is to modify the *string*,
not the pointer.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Feb 19 '07 #8
"DanielJohn son" <di********@gma il.comwrote in message
news:11******** ************@j2 7g2000cwj.googl egroups.com...
>I am writing a program in which I am removing all the spaces from the
string. I thought that I could do it two ways. One was parsing the
string character by character and copying onto another output string.
But this was trivial.
The other option is to use pointers and shift all the characters after
the space by one space to the left. I did this program using pointers
and then using array too and I get segmentation fault. What is going
wrong in here ?

#include<stdio. h>

int main(void)
{
char p[] = "please remove space from me";
int index = 0;

while(p[index] != '\0')
{
if (p[index] == ' '){
p[index] = p[index+1];
p[index+1] =' ';
}
index++;
}
puts(p);
return 0;
}

Your algorithm is flawed. Instead of shifting all of the characters to
the left, you only shift one and then insert a space. When you hit the
second space in the string you wind up with two consecutive spaces.
Also, things go haywire at the end of the string when the last space
marches off the end and the '\0' is not detected. Hence the seq fault.
Move the puts(p); inside the loop and see what happens at each pass.
Or try working it out the old-fashioned way with pencil and paper.

--
Tim Hagan
Feb 19 '07 #9
DanielJohnson wrote:
I am writing a program in which I am removing all the spaces from the
string. I thought that I could do it two ways. One was parsing the
string character by character and copying onto another output string.
But this was trivial.
The other option is to use pointers and shift all the characters after
the space by one space to the left. I did this program using pointers
and then using array too and I get segmentation fault. What is going
wrong in here ?

#include<stdio. h>

int main(void)
{
char p[] = "please remove space from me";
int index = 0;

while(p[index] != '\0')
{
if (p[index] == ' '){
p[index] = p[index+1];
p[index+1] =' ';
}
index++;
}
puts(p);
return 0;
}
I doubt it can work with only one index. Here's mine with pointers.

#include <stdio.h>

int main(void) {
char *d, *s;
char p[] = "please remove spaces from me";
d = s = p;
puts(p);
while (*s) {
while (*s == ' ') ++s;
*d++ = *s++;
}
*d = '\0';
puts(p);
return 0;
}

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Feb 22 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
89906
by: Thomas Mlynarczyk | last post by:
Which is the simplest way to remove all whitespace from a string? Is there a simpler method than a regex replace? Or how can I tell a regex pattern to ignore all whitespace in my subject string? There is a global modifier to ignore all spaces in the pattern, but I couldn't find one for ignoring spaces in the subject string. Do I really have...
1
4055
by: Danny | last post by:
Given this: "*" the pattern to remove the htnl code between brackets, how can I remove a series of spaces and just make one space. like here is a series of blank spaces thanks
2
2835
by: BobM | last post by:
I have two strings that I would like to compare. To guarantee the compare is not affected by trailing spaces, I would like to remove them. Will this do: MyTextBox.text.ToString().Trim()?
6
22861
by: Paul | last post by:
Hi just wondering if there is an easy way to remove spaces in a string, tried the trim method but think it is only for leading or trailing spaces. thanks -- Paul G Software engineer.
3
7842
by: Danny Yeadon | last post by:
Hi I need to remove unwanted characters from phone numbers from my phone bill to analyse the data. Some examples are 02 48222222 i need to remove the space +61266667656 i need to remove the + 0427 221 529 i need to remove both spaces 0419 637 344MNET i need to remove the spaces...
7
16453
by: Bosconian | last post by:
I know that str.replace(/^\s+|\s+$/g,''); will trim a string of space, but what about removing extra spaces from the middle? Where "hello world"
10
6752
by: pamelafluente | last post by:
Hi I have a sorted list with several thousands items. In my case, but this is not important, objects are stored only in Keys, Values are all Nothing. Several of the stored objects (might be a large number) have to be removed (say when ToBeRemoved = true). class SomeObj ToBeRemoved be a boolean field end class
34
4064
by: Registered User | last post by:
Hi experts, I'm trying to write a program that replaces two or more consecutive blanks in a string by a single blank. Here's what I did: #include <stdio.h> #include <string.h> #define MAX 80
8
2020
by: uzuria | last post by:
Hi there. I am doing a school project and need to be able to retrieve data from a file and display it in a selectable list box. I originally used a random access file, because I need to select particular fields from a record, but the data is not displaying correctly. Because you must give a field length for each string, my data is displaying...
0
7512
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7707
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7951
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7466
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7803
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5362
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
1
1926
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1051
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
751
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.