Burgershot
  • Home
  • Members
  • Team
  • Help
  • Search
  • Register
  • Login
  • Home
  • Members
  • Help
  • Search
Burgershot SA-MP Pawn Scripting [Pawn] Skipping extra spaces

 
  • 0 Vote(s) - 0 Average
Pawn Skipping extra spaces
Mark2
Offline

Burgershot Member
Posts: 8
Threads: 3
Joined: Apr 2019
Reputation: 0
Location: Belarus (Russian lang.)
#1
2019-04-15, 11:40 AM (This post was last modified: 2019-04-16, 05:14 PM by Mark2.)
Hello! Not so long ago, I tried to write a script that would remove extra spaces in the players' sentences, so that's what I did:
PHP Code:
new i = strlen(text), spaces; 
while(--
i != -1)
{ 
   switch(text[i]) 
   { 
       case ' ':
       { 
           spaces++;
           if(spaces > 1)
           { 
               spaces--;  
               strdel
(text, i, i+1);
           } 
       } 
       default: spaces = 0;
   } 
} 
 
if(text[i-1] == ' ') strdel(text, i-1, i);
if(
text[0] == ' ') strdel(text, 0, 1); 
It is work, but i would like to know what can be optimized or improved.

Thanks, that's what i got:

PHP Code:
DeSpace(string[], i = 0)
{
   while((i = strfind(string, "  ", _, i)) != -1) strdel(string, i, i + 1);
   if(string[0] == ' ') strdel(string, 0, 1);
   if(string[strlen(string)-1] == ' ') strdel(string, strlen(string)-1, strlen(string));
   return string[strlen(string)];
} 
[Image: aWbv5wm.gif]
SimoSbara
Offline

Burgershot Member
Posts: 14
Threads: 0
Joined: Apr 2019
Reputation: 2
#2
2019-04-15, 09:01 PM (This post was last modified: 2019-04-15, 09:49 PM by SimoSbara.)
I optimized a bit this code:
Code:
for(new i = strlen(text); i >= 0; --i)
{
  if(text[i] == ' ')  
    if(text[i-1] == ' ' || i == 0)
            strdel(text, i-1, i);
}

The syntax is correct, I deleted the "spaces" variable because you could check the extra space by comparing the character before the text[i]. Let me know if it works the same.

EDIT: I also removed the switch case just to make the code cleaner.
EDIT 1: Optimized again a case scenario.

Final code:
Code:
for(new i = strlen(text); i >= 0; --i)
{
  if(text[i] == ' ')
  {
    if(text[i-1] == ' ')
      strdel(text, i-1, i);

    else if(i == 0)
      strdel(text, 0, 1);
  }
}
3D modeler on Blender - OOP and functional programming programmer
Bork
Offline

Burgershot Member
Posts: 31
Threads: 4
Joined: Apr 2019
Reputation: 4
#3
2019-04-15, 09:20 PM
PHP Code:
     new name[MAX_PLAYER_NAME + 1];
     GetPlayerName(playerid, name, MAX_PLAYER_NAME);
     name[strfind(name, "_", true)] = " ";
     SetPlayerName(playerid, name); 

I suppose this'll work. Only issue is that if a _ isn't found then it's gonna set a string in position -1 to nothing, which doesn't really exist. A more ideal solution would probably be...

PHP Code:
    new name[MAX_PLAYER_NAME + 1];
    GetPlayerName(playerid, name, MAX_PLAYER_NAME);

    if (strfind(name, "_", true) != -1) {
        name[strfind(name, "_", true)] = " ";
        SetPlayerName(playerid, name);
    } 

Correct me if I'm wrong please. Sorry :)
SimoSbara
Offline

Burgershot Member
Posts: 14
Threads: 0
Joined: Apr 2019
Reputation: 2
#4
2019-04-15, 09:23 PM (This post was last modified: 2019-04-15, 09:40 PM by SimoSbara.)
I think he meant to make an algorithm that removes extra spaces in sentences like: "This . . senteces has too . many spaces" --> "This senteces has too many spaces" (a period rappresent a space)
3D modeler on Blender - OOP and functional programming programmer
Y_Less
Offline

Administrator

Posts: 323
Threads: 16
Joined: Feb 2019
Reputation: 90
#5
2019-04-15, 10:39 PM
Another way you can do this is to loop through once, and shift all letters backwards. Every time you see a space you increase this shift offset:

PHP Code:
DeSpace(string[])
{
    new
        
// Read index.
        
i = -1,
        
// Write index.
        
j = -1,
        
// Current character.
        
ch,
        
// Did we already see a space?
        
bool:space;
    do
    {
        if ((
ch = string[++i]) != ' ')
        {
            
// Not a space, just copy it.
            
string[++j] = ch;
            
// Mark us as having NOT just seen a space.
            
space = false;
        }
        else if (!
space)
        {
            
// First space.  Any more just ignore them.
            
string[++j] = ch;
            
// Mark us as having just seen a space.
            
space = true;
        }
    }
    while (
ch);
} 

Is this better? I don't know. It will depend on the length of the string and the number of double spaces.
SimoSbara
Offline

Burgershot Member
Posts: 14
Threads: 0
Joined: Apr 2019
Reputation: 2
#6
2019-04-15, 11:48 PM
So, your idea is to shift the sentece backwards and leaving the space on the "right"
3D modeler on Blender - OOP and functional programming programmer
Y_Less
Offline

Administrator

Posts: 323
Threads: 16
Joined: Feb 2019
Reputation: 90
#7
2019-04-16, 12:33 AM
Well shift the sentence backwards and just ignore the spaces. So they don't get shifted, and when encountered no shifting or destination incrementing happens. Thus the next character to be shifted goes where the space currently is.
SimoSbara
Offline

Burgershot Member
Posts: 14
Threads: 0
Joined: Apr 2019
Reputation: 2
#8
2019-04-16, 05:52 AM
I think the strdel function does the same that you did.
3D modeler on Blender - OOP and functional programming programmer
mr_sacrimoni
Offline

Burgershot Member
Posts: 16
Threads: 3
Joined: Apr 2019
Reputation: 1
#9
2019-04-16, 08:06 AM
(2019-04-16, 05:52 AM)SimoSbara Wrote: I think the strdel function does the same that you did.

I think strdel just copies the portions, depending on start and end arguments.
SimoSbara
Offline

Burgershot Member
Posts: 14
Threads: 0
Joined: Apr 2019
Reputation: 2
#10
2019-04-16, 08:51 AM
Anyways, I think the only problem with those algorithm is the space at the end of the sentence
3D modeler on Blender - OOP and functional programming programmer
Mark2
Offline

Burgershot Member
Posts: 8
Threads: 3
Joined: Apr 2019
Reputation: 0
Location: Belarus (Russian lang.)
#11
2019-04-16, 09:21 AM (This post was last modified: 2019-04-16, 10:06 AM by Mark2.)
(2019-04-15, 09:01 PM)SimoSbara Wrote: I optimized a bit this code:
Code:
for(new i = strlen(text); i >= 0; --i)
{
 if(text[i] == ' ')  
   if(text[i-1] == ' ' || i == 0)
           strdel(text, i-1, i);
}

The syntax is correct, I deleted the "spaces" variable because you could check the extra space by comparing the character before the text[i]. Let me know if it works the same.

EDIT: I also removed the switch case just to make the code cleaner.
EDIT 1: Optimized again a case scenario.

Final code:
Code:
for(new i = strlen(text); i >= 0; --i)
{
 if(text[i] == ' ')
 {
   if(text[i-1] == ' ')
     strdel(text, i-1, i);

   else if(i == 0)
     strdel(text, 0, 1);
 }
}

What about space at end of sentence?? You deleted at 0 pos and need to delete at strlen pos too

PHP Code:
for(new i = strlen(text); i >= 0; --i)
{
                                              
 if
(text[i] == ' ')
 {
   if(text[i-1] == ' ')
     strdel(text, i-1, i);

   else if(i == 0)
     strdel(text, 0, 1);

   else if(i == strlen(text)-1)
     strdel(text, strlen(text)-1, strlen(text);
 }
} 

I think that's will be faster(especially with long sentences):

PHP Code:
for(new i = strlen(text); i >= 0; --i)
{
    if(text[i] == ' ')
    {
        if(text[i-1] == ' ')
            strdel(text, i-1, i);
    }
}
if(
text[0] == ' ')
    
strdel(text, 0, 1);
if(
text[strlen(text)-1] == ' ')
    
strdel(text, strlen(text)-1, strlen(text)); 
[Image: aWbv5wm.gif]
SimoSbara
Offline

Burgershot Member
Posts: 14
Threads: 0
Joined: Apr 2019
Reputation: 2
#12
2019-04-16, 10:50 AM
About the end of the sentence is a little complex, but it is possibile. When I'll get back home, I'll write the condition for the spaces at the end of the sentence.
3D modeler on Blender - OOP and functional programming programmer
Y_Less
Offline

Administrator

Posts: 323
Threads: 16
Joined: Feb 2019
Reputation: 90
#13
2019-04-16, 11:21 AM
This is what I meant by it depending on how many spaces there are. My code always runs in O(n) - it doesn't matter how long the string is, nor how many duplicate spaces there are. "strdel" works by copying the rest of the string over the deleted part, which means it has to copy all the rest of the string every time there is a duplicated space. This makes its worst-case something like O(n^2).
Mark2
Offline

Burgershot Member
Posts: 8
Threads: 3
Joined: Apr 2019
Reputation: 0
Location: Belarus (Russian lang.)
#14
2019-04-16, 01:12 PM (This post was last modified: 2019-04-16, 01:16 PM by Mark2.)
(2019-04-15, 10:39 PM)Y_Less Wrote: Another way you can do this is to loop through once, and shift all letters backwards.  Every time you see a space you increase this shift offset:

PHP Code:
DeSpace(string[])
{
new
// Read index.
i = -1,
// Write index.
j = -1,
// Current character.
ch,
// Did we already see a space?
bool:space;
do
{
if ((
ch = string[++i]) != ' ')
{
// Not a space, just copy it.
string[++j] = ch;
// Mark us as having NOT just seen a space.
space = false;
}
else if (!
space)
{
// First space.  Any more just ignore them.
string[++j] = ch;
// Mark us as having just seen a space.
space = true;
}
}
while (
ch);
} 

Is this better?  I don't know.  It will depend on the length of the string and the number of double spaces.
(2019-04-16, 11:21 AM)Y_Less Wrote: This is what I meant by it depending on how many spaces there are.  My code always runs in O(n) - it doesn't matter how long the string is, nor how many duplicate spaces there are.  "strdel" works by copying the rest of the string over the deleted part, which means it has to copy all the rest of the string every time there is a duplicated space.  This makes its worst-case something like O(n^2).

hmm don't thought that strdel so working, in this case that's really nice, thanks!
[Image: aWbv5wm.gif]
SimoSbara
Offline

Burgershot Member
Posts: 14
Threads: 0
Joined: Apr 2019
Reputation: 2
#15
2019-04-16, 01:39 PM (This post was last modified: 2019-04-16, 01:39 PM by SimoSbara.)
I'll read the code of these functions next time xd
3D modeler on Blender - OOP and functional programming programmer
Y_Less
Offline

Administrator

Posts: 323
Threads: 16
Joined: Feb 2019
Reputation: 90
#16
2019-04-16, 02:03 PM
I just realised something else. All the code scans the text one character at a time. You could try using the `strfind` native to look for two spaces:

PHP Code:
strfind(string, "  "); 
WestCoast
Offline

Burgershot Member
Posts: 7
Threads: 0
Joined: Apr 2019
Reputation: 0
#17
2019-04-16, 03:01 PM (This post was last modified: 2019-04-16, 03:37 PM by WestCoast.)
Hi, so I wrote the working code.:
PHP Code:
RemoveDoubleSpace(string[])
{
    for(new 
i, id; i < strlen(string); i++)
    {
        
id = strfind(string, "  ");
        if(
id == -1) break;
        
strdel(string, id, id+1);
    }
} 
updated.
Y_Less
Offline

Administrator

Posts: 323
Threads: 16
Joined: Feb 2019
Reputation: 90
#18
2019-04-16, 03:08 PM
Oh, we're playing code golf now are we :)

PHP Code:
RemoveDoubleSpace(string[], i = 0)
{
    while ((
i = strfind(string, "  ", _, i)) != -1)
        
strdel(string, i, i + 1);
} 
WestCoast
Offline

Burgershot Member
Posts: 7
Threads: 0
Joined: Apr 2019
Reputation: 0
#19
2019-04-16, 03:45 PM
(2019-04-16, 03:08 PM)Y_Less Wrote: Oh, we're playing code golf now are we :)

PHP Code:
RemoveDoubleSpace(string[], i = 0)
{
while ((
i = strfind(string, "  ", _, i)) != -1)
strdel(string, i, i + 1);
} 

Your code looks better
SimoSbara
Offline

Burgershot Member
Posts: 14
Threads: 0
Joined: Apr 2019
Reputation: 2
#20
2019-04-16, 05:49 PM
(2019-04-16, 03:08 PM)Y_Less Wrote: Oh, we're playing code golf now are we :)

PHP Code:
RemoveDoubleSpace(string[], i = 0)
{
while ((
i = strfind(string, "  ", _, i)) != -1)
strdel(string, i, i + 1);
} 

(2019-04-15, 10:39 PM)Y_Less Wrote: Another way you can do this is to loop through once, and shift all letters backwards.  Every time you see a space you increase this shift offset:

PHP Code:
DeSpace(string[])
{
new
// Read index.
i = -1,
// Write index.
j = -1,
// Current character.
ch,
// Did we already see a space?
bool:space;
do
{
if ((
ch = string[++i]) != ' ')
{
// Not a space, just copy it.
string[++j] = ch;
// Mark us as having NOT just seen a space.
space = false;
}
else if (!
space)
{
// First space.  Any more just ignore them.
string[++j] = ch;
// Mark us as having just seen a space.
space = true;
}
}
while (
ch);
} 

Is this better?  I don't know.  It will depend on the length of the string and the number of double spaces.
 it should be the definitive, but there are other way to solve this problem
3D modeler on Blender - OOP and functional programming programmer
SyS
Offline

Burgershot Member
Posts: 37
Threads: 5
Joined: Apr 2019
Reputation: 4
#21
2019-04-17, 03:18 AM (This post was last modified: 2019-04-17, 03:21 AM by SyS.)
You can also use Regular expressions
PHP Code:
#include<Pawn.Regex>//https://github.com/urShadow/Pawn.Regex
RemoveExtraSpace(str[]) {
    new 
Regex:r = Regex_New("\\s+");
    
Regex_Replace(str, r," ", str);
} 
The above one removes all extra white space like characters.If you just want space you can use
PHP Code:
new Regex:r = Regex_New(" +"); 
then do the stripping for leading and trailing spaces
Y_Less
Offline

Administrator

Posts: 323
Threads: 16
Joined: Feb 2019
Reputation: 90
#22
2019-04-17, 02:22 PM (This post was last modified: 2019-04-17, 02:23 PM by Y_Less.)
I'd probably use

PHP Code:
"  *" 

or

PHP Code:
" {2,}" 

because

PHP Code:
" +" 

will match single spaces as well and replace those with another single space.
SyS
Offline

Burgershot Member
Posts: 37
Threads: 5
Joined: Apr 2019
Reputation: 4
#23
2019-04-17, 03:06 PM
(2019-04-17, 02:22 PM)Y_Less Wrote: I'd probably use

PHP Code:
"  *" 

or

PHP Code:
" {2,}" 

because

PHP Code:
" +" 

will match single spaces as well and replace those with another single space.

Ahh yes that's right
Y_Less
Offline

Administrator

Posts: 323
Threads: 16
Joined: Feb 2019
Reputation: 90
#24
2019-04-17, 03:29 PM
(2019-04-17, 03:06 PM)SyS Wrote:
(2019-04-17, 02:22 PM)Y_Less Wrote: I'd probably use

PHP Code:
"  *" 

or

PHP Code:
" {2,}" 

because

PHP Code:
" +" 

will match single spaces as well and replace those with another single space.

Ahh yes that's right

No it's not, I just realised this will also match single spaces:

PHP Code:
"  *" 

The second one is correct, but that should be:

PHP Code:
"  +" 

To match at least two.
« Next Oldest | Next Newest »



  • View a Printable Version
  • Subscribe to this thread
Forum Jump:

© Burgershot - Powered by our Community and MyBB Original Theme by Emerald

Linear Mode
Threaded Mode