• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Pawn] Skipping extra spaces
#1
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 strlen(text), spaces

while(--
!= -1)



? ?switch(
text[i]) 

? ?{ 

? ? ? ?case 
' ':

? ? ? ?{ 

? ? ? ? ? ?
spaces;

? ? ? ? ? ?if(
spaces 1)

? ? ? ? ? ?{ 

? ? ? ? ? ? ? ?
spaces--; ?

? ? ? ? ? ? ? ?
strdel(textii);

? ? ? ? ? ?} 

? ? ? ?} 

? ? ? ?default: 
spaces 0;

? ?} 

} ?

if(
text[i-1] == ' 'strdel(texti-1i);

if(
text[0] == ' 'strdel(text01); 

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[], 0)

{

? ?while((
strfind(string" ?"_i)) != -1strdel(stringii  1);

? ?if(
string[0] == ' 'strdel(string01);

? ?if(
string[strlen(string)-1] == ' 'strdel(stringstrlen(string)-1strlen(string));

? ?return 
string[strlen(string)];


[Image: aWbv5wm.gif]

  Reply
#2
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

  Reply
#3
PHP Code:
? ? ?new name[MAX_PLAYER_NAME  1];

? ? ?
GetPlayerName(playeridnameMAX_PLAYER_NAME);

? ? ?
name[strfind(name"_"true)] = " ";

? ? ?
SetPlayerName(playeridname); 



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(playeridnameMAX_PLAYER_NAME);



? ? if (
strfind(name"_"true) != -1) {

? ? ? ??
name[strfind(name"_"true)] = " ";

? ? ? ? 
SetPlayerName(playeridname);

? ? } 



Correct me if I'm wrong please. Sorry :)
  Reply
#4
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

  Reply
#5
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.

        
= -1,

        
// Write index.

        
= -1,

        
// Current character.

        
ch,

        
// Did we already see a space?

        
bool:space;

    do

    {

        if ((
ch string[]) != ' ')

        {

            
// Not a space, just copy it.

            
string[] = ch;

            
// Mark us as having NOT just seen a space.

            
space false;

        }

        else if (!
space)

        {

            
// First space.  Any more just ignore them.

            
string[] = 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.
  Reply
#6
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

  Reply
#7
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.
  Reply
#8
I think the strdel function does the same that you did.
3D modeler on Blender - OOP and functional programming programmer

  Reply
#9
(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.
  Reply
#10
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

  Reply
#11
(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 strlen(text); >= 0; --i)
{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?if(
text[i] == ' ')
?{
? ?if(
text[i-1] == ' ')
? ? ?
strdel(texti-1i);

? ?else if(
== 0)
? ? ?
strdel(text01);

? ?else if(
== strlen(text)-1)
? ? ?
strdel(textstrlen(text)-1strlen(text);
?}


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

PHP Code:
for(new strlen(text); >= 0; --i)
{
? ? if(
text[i] == ' ')
? ??{
? ? ? ? if(
text[i-1] == ' ')
? ? ?       
strdel(texti-1i);
? ? }
}
if(
text[0] ==?'?')
    
strdel(text01);
if(
text[strlen(text)-1] == ' ')
    
strdel(textstrlen(text)-1strlen(text)); 
[Image: aWbv5wm.gif]

  Reply
#12
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

  Reply
#13
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).
  Reply
#14
(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.

= -1,

// Write index.

= -1,

// Current character.

ch,

// Did we already see a space?

bool:space;

do

{

if ((
ch string[]) != ' ')

{

// Not a space, just copy it.

string[] = ch;

// Mark us as having NOT just seen a space.

space false;

}

else if (!
space)

{

// First space. ?Any more just ignore them.

string[] = 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]

  Reply
#15
I'll read the code of these functions next time xd
3D modeler on Blender - OOP and functional programming programmer

  Reply
#16
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"  "); 
  Reply
#17
Hi, so I wrote the working code.:
PHP Code:
RemoveDoubleSpace(string[])
{
    for(new 
iidstrlen(string); i)
    {
        
id strfind(string"  ");
        if(
id == -1) break;
        
strdel(stringidid);
    }

updated.
  Reply
#18
Oh, we're playing code golf now are we :)



PHP Code:
RemoveDoubleSpace(string[], 0)

{

    while ((
strfind(string"  "_i)) != -1)

        
strdel(stringii  1);


  Reply
#19
(2019-04-16, 03:08 PM)Y_Less Wrote: Oh, we're playing code golf now are we :)



PHP Code:
RemoveDoubleSpace(string[], 0)

{

while ((
strfind(string" ?"_i)) != -1)

strdel(stringii  1);





Your code looks better
  Reply
#20
(2019-04-16, 03:08 PM)Y_Less Wrote: Oh, we're playing code golf now are we :)



PHP Code:
RemoveDoubleSpace(string[], 0)

{

while ((
strfind(string" ?"_i)) != -1)

strdel(stringii  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.

= -1,

// Write index.

= -1,

// Current character.

ch,

// Did we already see a space?

bool:space;

do

{

if ((
ch string[]) != ' ')

{

// Not a space, just copy it.

string[] = ch;

// Mark us as having NOT just seen a space.

space false;

}

else if (!
space)

{

// First space. ?Any more just ignore them.

string[] = 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

  Reply
#21
You can also use Regular expressions
PHP Code:
#include<Pawn.Regex>//https://github.com/urShadow/Pawn.Regex
RemoveExtraSpace(str[]) {
    new 
Regex:Regex_New("\\s");
    
Regex_Replace(strr," "str);

The above one removes all extra white space like characters.If you just want space you can use
PHP Code:
new Regex:Regex_New(" "); 
then do the stripping for leading and trailing spaces
  Reply
#22
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.
  Reply
#23
(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
  Reply
#24
(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.
  Reply


Forum Jump: